The protocol buffers required for protobuf ingestion are not yet available in the public repository. To retrieve them, see Protocol Buffers below.
bytes value), and the server creates channels based on the message structure.
How channels are generated from protobuf fields
Given the following protobuf message:Vehicle.velocityVehicle.direction[0]Vehicle.direction[1](one channel per array index)Vehicle.vehicle_stateVehicle.propulsion.fuel_levelVehicle.batteries[cpu].voltage(one channel per map key)Vehicle.batteries[cpu].tempVehicle.batteries[propulsion].voltageVehicle.batteries[propulsion].temp
Schema registration
ProtobufDescriptorService
UseProtobufDescriptorService.AddProtobufDescriptor to register a protobuf schema before ingesting messages.
Registration process
- Registration is performed by message type and
namespace. Thenamespacefield enables schema separation between environments. For example, a developer can iterate on protobuf definitions in a separate namespace without affecting live telemetry. - The request takes a
file_descriptor_setfield generated by compiling the protobuf withprotoc:
ProtobufDescriptors with the same message type and namespace stores a new version of the descriptor. When a message is ingested, all stored descriptor sets for that message type and namespace are used to generate channel values. The unique set of channels generated is then ingested.
Backward compatibility
New protobuf descriptors must be backward compatible with existing descriptors that share the same message_type_full_name and namespace. A descriptor is not backward compatible when a field name changes (for example, velocity with field number 1 is renamed to speed).
When a new descriptor is not backward compatible, you will receive an error such as:
CheckProtobufDescriptorCompatibility to check compatibility before registering.
Deletion
DeleteProtobufDescriptors removes all descriptors for a given message type and namespace. This is useful for:
- Cleaning up test protobuf messages that are no longer in use.
- Simplifying ingestion when a new version of the descriptor is fully backward compatible.
Data ingestion
Once the schema is registered, send serialized messages usingIngestService.IngestArbitraryProtobufDataStream.
Sift protobuf options
To create more descriptive channels, add custom options fromchannel_parsing_options.proto to your protobuf definitions.
| Option | Description |
|---|---|
| Units and Description | Add units and descriptions to primitive fields. |
| Bytes Decoding | Interpret a bytes-typed field as another type, such as UTF-8. Enum: BYTES_DECODING_TYPE_UNSPECIFIED, BYTES_DECODING_TYPE_UTF8. |
| Tags | Add context from field values to channel names. Useful when a field path needs additional context to be unique. |
| Map Key Display Overrides | Replace the display value of a map key. Useful when keys are not human-readable or have transient values. |
| Array Index Overrides | Replace or remove array index display values in channel names. |
Tagging example
A tag source identifies a field whose value becomes a tag on related channels.TestProto.nameTestProto.primary_child.child_nameTestProto.primary_child.map_int_to_message[1].sub_child_nameTestProto.primary_child.map_int_to_message[1].idTestProto.array_of_children[0].child_nameTestProto.array_of_children[0].map_int_to_message[1].sub_child_nameTestProto.array_of_children[0].map_int_to_message[1].idTestProto.type_id
TestProto(type_id:3).nameTestProto(type_id:3).primary_child(kid_name:childname).child_nameTestProto(type_id:3).primary_child(kid_name:childname).map_int_to_message[1].sub_child_name(id:35)TestProto(type_id:3).primary_child(kid_name:childname).map_int_to_message[1].idTestProto(type_id:3).array_of_children[0].child_nameTestProto(type_id:3).array_of_children[0].map_int_to_message[1].sub_child_name(id:35)TestProto(type_id:3).array_of_children[0].map_int_to_message[1].idTestProto(type_id:3).type_id
field_name(field_1:value_1)(field_2:value_2).
Map key and array index override example
0 is the only map key):
TestProto.nameTestProto.map_key_test[0].new_keyTestProto.map_key_test[0].some_valueTestProto.map_key_removal_test[0]TestProto.map_key_enum_test[0]TestProto.array_index_override_test[0].new_indexTestProto.array_index_override_test[0].other_valueTestProto.array_index_override_remove_index[0]TestProto.array_index_enum_test[0]
new_key value is my-new-key and new_index value is my-new-index):
TestProto.nameTestProto.map_key_test[my-new-key].new_keyTestProto.map_key_test[my-new-key].some_valueTestProto.map_key_removal_testTestProto.map_key_enum_test[NONE]TestProto.array_index_override_test[my-new-index].new_indexTestProto.array_index_override_test[my-new-index].other_valueTestProto.array_index_override_remove_indexTestProto.array_index_enum_test[NONE]
Protocol buffers
| Component | Description | API reference | Source |
|---|---|---|---|
ProtobufDescriptorService | Registers the protobuf schema. | protobuf_descriptors | GitHub |
IngestService | Streams serialized protobuf messages. | ingest#ingestservice | GitHub |
| Channel Parsing | Converts protobuf field paths to channels. | channel_parsing_options | GitHub |