semantic-conventions/semantic-conventions.md

108 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Semantic Conventions
This document defines reserved attributes that can be used to add operation and
protocol specific information.
In OpenTelemetry spans can be created freely and its up to the implementor to
annotate them with attributes specific to the represented operation. Spans
represent specific operations in and between systems. Some of these operations
represent calls that use well-known protocols like HTTP or database calls.
Depending on the protocol and the type of operation, additional information
is needed to represent and analyze a span correctly in monitoring systems. It is
also important to unify how this attribution is made in different languages.
This way, the operator will not need to learn specifics of a language and
telemetry collected from multi-language micro-service can still be easily
correlated and cross-analyzed.
## Databases client calls
For database client call the `SpanKind` MUST be `Client`.
Span `name` should be set to low cardinality value representing the statement
executed on the database. It may be stored procedure name (without argument), sql
statement without variable arguments, etc. When it's impossible to get any
meaningful representation of the span `name`, it can be populated using the same
value as `db.instance`.
Note, Redis, Cassandra, HBase and other storage systems may reuse the same
attribute names.
| Attribute name | Notes and examples | Required? |
| :------------- | :----------------------------------------------------------- | --------- |
| `component` | Database driver name or database name (when known) `JDBI`, `jdbc`, `odbc`, `postgreSQL`. | Yes |
| `db.type` | Database type. For any SQL database, `"sql"`. For others, the lower-case database category, e.g. `"cassandra"`, `"hbase"`, or `"redis"`. | Yes |
| `db.instance` | Database instance name. E.g., In java, if the jdbc.url=`"jdbc:mysql://db.example.com:3306/customers"`, the instance name is `"customers"`. | Yes |
| `db.statement` | A database statement for the given database type. Note, that the value may be sanitized to exclude sensitive information. E.g., for `db.type="sql"`, `"SELECT * FROM wuser_table"`; for `db.type="redis"`, `"SET mykey 'WuValue'"`. | Yes |
| `db.user` | Username for accessing database. E.g., `"readonly_user"` or `"reporting_user"` | No |
For database client calls, peer information can be populated and interpreted as
follows:
| Attribute name | Notes and examples | Required |
| :-------------- | :----------------------------------------------------------- | -------- |
| `peer.address` | JDBC substring like `"mysql://db.example.com:3306"` | Yes |
| `peer.hostname` | Remote hostname. `db.example.com` | Yes |
| `peer.ipv4` | Remote IPv4 address as a `.`-separated tuple. E.g., `"127.0.0.1"` | No |
| `peer.ipv6` | Remote IPv6 address as a string of colon-separated 4-char hex tuples. E.g., `"2001:0db8:85a3:0000:0000:8a2e:0370:7334"` | No |
| `peer.port` | Remote port. E.g., `80` (integer) | No |
| `peer.service` | Remote service name. Can be database friendly name or `db.instance` | No |
## gRPC
Implementations MUST create a span, when the gRPC call starts, one for
client-side and one for server-side. Outgoing requests should be a span `kind`
of `CLIENT` and incoming requests should be a span `kind` of `SERVER`.
Span `name` MUST be full gRPC method name formatted as:
```
$package.$service/$method
```
Examples of span name: `grpc.test.EchoService/Echo`.
### Attributes
| Attribute name | Notes and examples | Required? |
| -------------- | ------------------------------------------------------------ | --------- |
| `component` | Declares that this is a grpc component. Value MUST be `grpc` | Yes |
`peer.*` attributes MUST define service name as `peer.service`, host as
`peer.hostname` and port as `peer.port`.
### Status
Implementations MUST set status which MUST be the same as the gRPC client/server
status. The mapping between gRPC canonical codes and OpenTelemetry status codes
is 1:1 as OpenTelemetry canonical codes is just a snapshot of grpc codes which
can be found [here](https://github.com/grpc/grpc-go/blob/master/codes/codes.go).
### Events
In the lifetime of a gRPC stream, an event for each message sent/received on
client and server spans SHOULD be created with the following attributes:
```
-> [time],
"name" = "message",
"message.type" = "SENT",
"message.id" = id
"message.compressed_size" = <compressed size in bytes>,
"message.uncompressed_size" = <uncompressed size in bytes>
```
```
-> [time],
"name" = "message",
"message.type" = "RECEIVED",
"message.id" = id
"message.compressed_size" = <compressed size in bytes>,
"message.uncompressed_size" = <uncompressed size in bytes>
```
The `message.id` MUST be calculated as two different counters starting from `1`
one for sent messages and one for received message. This way we guarantee that
the values will be consistent between different implementations. In case of
unary calls only one sent and one received message will be recorded for both
client and server spans.