-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pdata] Add a documentation with naming conventions
Co-authored-by: Pablo Baeyens <pbaeyens31+github@gmail.com>
- Loading branch information
Showing
1 changed file
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
# Pipeline data (pdata) | ||
|
||
Pipeline data (pdata) implements data structures that represent telemetry data in-memory. All data received | ||
is converted into this format, travels through the pipeline in this format, and is converted from this format by | ||
exporters when sending. | ||
|
||
Current implementation primarily uses OTLP protobuf structs as the underlying data structures for many of the | ||
declared structs. We keep a pointer to OTLP protobuf in the "orig" member field. This allows efficient translation | ||
to/from OTLP wire protocol. The underlying data structure is kept private so that we are free to make changes to it | ||
in the future. | ||
|
||
API provided by pdata ensures that no underlying data can be used in more than one place. Each pdata instance cannot | ||
contain a reference to an object that is already used somewhere else. | ||
|
||
## API naming convention | ||
|
||
### Protobuf message representation in pdata | ||
|
||
Packages of pdata are not following names of the protobuf packages. pdata has a package per telemetry type starting | ||
with `p`, e.g. `ptace`, and `pcommon` package with API for other protobuf definitions from `common` and `resource` | ||
protobuf packages. | ||
|
||
Pipeline data structs SHOULD be based on the names of the underlying OTLP protobuf messages. Data types for | ||
protobuf messages defined as part of another message SHOULD include the owner's name as a prefix. Exceptions to these | ||
rules are possible, but not encouraged. Another name can be chosen for brevity or if the struct provides a completely | ||
different interface to manipulate the underlying data. The following exceptions are currently accepted: | ||
|
||
- `plog.Logs` based on `LogsData` protobuf message. | ||
- `pmetric.Metrics` based on `MetricsData` protobuf message. | ||
- `ptrace.Traces` based on `TracesData` protobuf message. | ||
- `pcommon.Slice` based on `ArrayValue` protobuf message. | ||
- `pcommon.Map` based on `KeyValueList` protobuf message. | ||
- `pcommon.Value` based on `AnyValue` protobuf message. | ||
|
||
Each pdata struct MUST have an initialization function starting with `New` prefix. Usage of zero-initialized is | ||
prohibited and can cause a panic. Each pdata struct MUST provide the following methods: | ||
|
||
- `MoveTo(<type>)`: moves all the data from one struct instance to another. Destination instance is overridden, the | ||
source instance is re-initialized as a new empty instance. | ||
- `CopyTo(<type>)`: copies all the data from one struct instance to another. Destination instance is overridden, the | ||
source instance is not modified. | ||
|
||
### Protobuf fields representation in pdata | ||
|
||
### Singular fields | ||
|
||
Each pdata struct based on a protobuf message SHOULD have getter methods for every protobuf field called the same as | ||
the protobuf field but in CamelCase. Exceptions to this rule are allowed if exposing a field is not desirable in pdata. | ||
pdata can also provide a different interface to manipulate fields without exposing them explicitly as it's done in | ||
`pcommon.Map`. If protobuf field is of scalar or enum type, the corresponding pdata struct MUST provide a setter | ||
method with `Set` prefix. | ||
|
||
Some fields of scalar type in protobuf message MAY be represented by another pdata type providing an additional | ||
interface, for example `pcommon.Timestamp`. | ||
|
||
### Optional fields | ||
|
||
Each optional field in protobuf message exposed in pdata MUST have an additional method with `Has` prefix to | ||
determine if the field is set. | ||
|
||
### OneOf fields | ||
|
||
A pdata struct representing a protobuf message with a oneof field MUST provide getter and setter methods for each | ||
option of the oneof field. If a oneof field option is another protobuf message, setter name MUST include `Empty` | ||
word, such setter MUST set the oneof field to an empty initialized struct and return it. The following conditions | ||
define if name the oneof field has to be included in the setter and getter methods names: | ||
|
||
1. If a oneof field represents the whole protobuf message, name of the oneof field itself MAY be omitted in setter | ||
and getter methods. For example: | ||
|
||
```go | ||
func (ms Metric) Sum() Sum | ||
func (ms Metric) SetEmptySum() Sum | ||
``` | ||
|
||
2. If a oneof field is relevant only to a particular field of the message, the pdata getter and setter methods MUST | ||
include name of the oneof field along with name of the option. For example: | ||
|
||
```go | ||
func (ms NumberDataPoint) IntValue() int64 | ||
func (ms NumberDataPoint) SetIntValue(v int64) | ||
``` | ||
|
||
Additionally, the pdata struct MUST provide a type getter for every exposed oneof protobuf field. Name of the getter | ||
MUST be `Type` for oneof fields representing the whole protobuf message (1), or `<oneof field>Type` for oneof fields | ||
relevant only to a particular field. The function MUST return an `int32` enum type called `<struct name>Type` for (1) | ||
and `<struct name><oneof field>Type` for (2). For example: | ||
|
||
- `func (ms Metric) Type() MetricType` (1) | ||
- `func (ms NumberDataPoint) ValueType() NumberDataPointValueType` (2) | ||
|
||
The enum constants MUST be called the same as the type with a suffix named after the oneof option, e.g.: | ||
|
||
- `MetricTypeSum` (1) | ||
- `NumberDataPointValueTypeString` (2) | ||
|
||
An unset oneof protobuf value MUST be represented by a pdata constant with `Empty` suffix, e.g.: | ||
|
||
- `MetricTypeEmpty` (1) | ||
- `NumberDataPointValueTypeEmpty` (2) | ||
|
||
The pdata enum type SHOULD have `String()` method returning a string value of the corresponding oneof field option. | ||
|
||
### Repeated fields | ||
|
||
Repeated protobuf fields MUST be represented as another pdata struct with `Slice` suffix unless the slice message is | ||
represented in pdata through a modified interface, e.g. `pdata.Map`. Each slice MUST have the following methods: | ||
|
||
- `Len()`: returns length of the slice. | ||
- `At(int) <element type>`: returns an element from the slice by its index, can cause "index out of range" panic. | ||
- `CopyTo(<slice type>)`: copies the slice to another slice of the same type overriding the destination. | ||
- `EnsureCapacity(int)`: ensures that the slice have at least the requested capacity. | ||
- `AppendEmpty() <element type>`: adds another slice element with an empty initialized value and returns it. | ||
- `Sort(func(a, b <element type>) bool) <slice type>`: sorts the slice using the function and returns itself. | ||
|
||
### Repeated scalar fields | ||
|
||
Repeated scalar protobuf fields MUST be represented as another pdata type wrapping native go slices. Name of the | ||
type MUST include name of the primitive data type ending with `Slice`, e.g. `UInt64Slice`. Each pdata type MUST have | ||
the following methods: | ||
|
||
- `AsRaw() []<primitive type>`: returns copy of the underlying go slice. | ||
- `FromRaw(val []<primitive type>)`: copies a go slice into the pdata wrapper instance. | ||
- `Len()`: returns length of the slice. | ||
- `At(int) <primitive type>`: returns an element from the slice by its index, can cause "index out of range" panic. | ||
- `EnsureCapacity(int)`: ensures that the slice have at least the requested capacity. | ||
- `AppendEmpty() <primitive type>`: adds another slice element with a zero value. | ||
- `CopyTo(<slice type>)`: copies the slice to another slice of the same type overriding the destination. | ||
- `MoveTo(<slice type>)`: move the slice to another slice of the same type. The destination is overridden, the | ||
source is set to an empty slice. | ||
|
||
### Enum fields | ||
|
||
Each protobuf enum field exposed in pdata MUST have a type declared with underlying `int64` type. Name of the type MUST | ||
follow the same rules as for struct type names representing protobuf messages: | ||
|
||
- If a protobuf enum is defined on the package level, pdata type SHOULD have the same name. | ||
- If a protobuf enum is defined as part of another message, pdata type SHOULD include the protobuf message name as a | ||
prefix. | ||
|
||
Constants defined for the pdata int64 type MUST have the same names and numeric values defined in protobuf. Names | ||
of the constants must be translated from ALL_CAPS_SNAKE_CASE to CamelCase. | ||
|
||
The pdata enum type SHOULD have `String()` method returning a string value for each constant. | ||
|
||
Example of a protobuf enum definition in pdata: | ||
|
||
```golang | ||
type AggregationTemporality int32 | ||
const ( | ||
AggregationTemporalityUnspecified = AggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_UNSPECIFIED) | ||
AggregationTemporalityDelta = AggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_DELTA) | ||
AggregationTemporalityCumulative = AggregationTemporality(otlpmetrics.AggregationTemporality_AGGREGATION_TEMPORALITY_CUMULATIVE) | ||
) | ||
``` | ||
|
||
### Flags | ||
|
||
Flags fields are typically defined in protobuf as `uint32` fields representing 32 distinct boolean flags. The | ||
exposed protobuf flags fields MUST be defined as new types with `uint32` underlying type and called according to | ||
the same rules as struct names representing protobuf messages and other enum types. Each pdata flags type MUST have | ||
an empty variable of the fields type with `Default` prefix. Each flag MUST have a getter method returning a | ||
particular flag and a setter method with `With` prefix returning a new instance of the pdata flags type. Any instance | ||
of the pdata type is immutable since it's just a wrapper over `uint32`. | ||
|
||
The following pdata type is used for log record flags field: | ||
|
||
```golang | ||
type LogRecordFlags uint32 | ||
var DefaultLogRecordFlags = LogRecordFlags(0) | ||
func (ms LogRecordFlags) IsSampled() bool | ||
func (ms LogRecordFlags) WithIsSampled(b bool) LogRecordFlags | ||
``` | ||
|
||
### Examples | ||
|
||
The following protobuf message: | ||
|
||
```protobuf | ||
message NumberDataPoint { | ||
reserved 1; | ||
repeated opentelemetry.proto.common.v1.KeyValue attributes = 7; | ||
fixed64 start_time_unix_nano = 2; | ||
fixed64 time_unix_nano = 3; | ||
oneof value { | ||
double as_double = 4; | ||
sfixed64 as_int = 6; | ||
} | ||
repeated Exemplar exemplars = 5; | ||
uint32 flags = 8; | ||
} | ||
``` | ||
|
||
is represented by the following pdata API | ||
|
||
```go | ||
type NumberDataPoint | ||
func NewNumberDataPoint() NumberDataPoint | ||
func (ms NumberDataPoint) MoveTo(dest NumberDataPoint) | ||
func (ms NumberDataPoint) CopyTo(dest NumberDataPoint) | ||
func (ms NumberDataPoint) Attributes() pcommon.Map | ||
func (ms NumberDataPoint) StartTimestamp() pcommon.Timestamp | ||
func (ms NumberDataPoint) SetStartTimestamp(v pcommon.Timestamp) | ||
func (ms NumberDataPoint) Timestamp() pcommon.Timestamp | ||
func (ms NumberDataPoint) SetTimestamp(v pcommon.Timestamp) | ||
func (ms NumberDataPoint) ValueType() NumberDataPointValueType | ||
func (ms NumberDataPoint) DoubleValue() float64 | ||
func (ms NumberDataPoint) SetDoubleValue(v float64) | ||
func (ms NumberDataPoint) IntValue() int64 | ||
func (ms NumberDataPoint) SetIntValue(v int64) | ||
func (ms NumberDataPoint) Exemplars() ExemplarSlice | ||
func (ms NumberDataPoint) Flags() DataPointFlags | ||
func (ms NumberDataPoint) SetFlags(v DataPointFlags) | ||
``` |