Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Azure SDK semantic conventions #2233

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ release.
([#2191](https://github.com/open-telemetry/opentelemetry-specification/pull/2191))
- Add `device.manufacturer` to describe mobile device manufacturers.
([2100](https://github.com/open-telemetry/opentelemetry-specification/pull/2100))
- Add Azure SDK trace semantic conventions
([#2233](https://github.com/open-telemetry/opentelemetry-specification/pull/2233))

### Compatibility

Expand Down
117 changes: 117 additions & 0 deletions semantic_conventions/trace/instrumentation/azure-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Version: 0.0.0
# Status: Experimental
Comment on lines +1 to +2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those metadata fields used by internal tooling or intended to be used by the MD and code generator in https://github.com/open-telemetry/build-tools?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are only intended for MD generator at this point, they might also be used by Java code generator in the future. The main intent is formal documentation though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make sense to agree on the format and content first and have that specified in the syntax.md for the tool (but it looks good to me in general).

# This document describes Azure SDK trace semantic conventions. For more details refer to https://azure.github.io/azure.sdk/distributed_tracing_conventions.html

groups:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these define an id but no prefix. I assume you'd want to set prefix to match your ids.

Copy link
Contributor Author

@lmolkova lmolkova Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not aware of any requirement for id and prefix to match. Did I miss something?
AFAIK id is only relevant for tooling, while prefix is attribute prefix.
I don't see anything here and if I check existing specs, some of them have different prefix and id. Moreover, with things like HTTP, we don't add any new prefixes to attributes.

Copy link
Member

@arminru arminru Jan 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct. Currently you have request_id and service_request_id as standalone top-level attributes though. I assume those should be put under an azure prefix / namespace (e.g. azure.sdk.http.request_id), or is this intentional?

# common
- id: azure
brief: 'Describes Azure spans.'
prefix: az
attributes:
- id: namespace
required: always
type: string
sampling_relevant: true
brief: '[Namespace](https://docs.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) of Azure service that the request is made against.'
examples: ['Microsoft.Storage', 'Microsoft.KeyVault', 'Microsoft.ServiceBus']

# public API
- id: azure.sdk.api
span_kind: internal
extends: azure
brief: 'Describes Azure SDK API calls that wrap an Azure service call(s).'

# http
- id: azure.sdk.http
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirming if you meant to remove .sdk in all the cases too, assuming a possibility of filling in on the server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this specific section describes the client side of things (e.g. populates http.url), if we add server, I assume it would go under azure.<server>.http, so I kept sdk intentionally. Do you see any problem with this?

I assume if we add common attributes between server and client and declare them in azure.http this would still be a backward-compatible change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For HTTP, we chose the same names for client and server, since the overlapping attributes (like http.url) do have the same meaning. We use the span kind to distinguish.

extends: azure
span_kind: client
brief: 'Describes HTTP client spans created per HTTP request.'
note: >
Follows [OpenTelemetry HTTP conventions v1.8.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/trace/semantic_conventions/http.md)
but omits optional attributes, providing only `http.url` to describe destination. It adds request-id attributes supported by Azure services.
attributes:
- id: request_id
type: string
required: always
brief: 'Value of the "x-ms-client-request-id" header (or other "*-request-id" header, depending on the service) sent by the client.'
examples: ['eb178587-c05a-418c-a695-ae9466c5303c']
- id: service_request_id
type: string
required: always
brief: 'Value of the "x-ms-request-id" header (or other "*-request-id" header, depending on the service) sent by the server in response.'
examples: ['3f828ae5-ecb9-40ab-88d9-db0420af30c6']
- ref: http.method
required: always
sampling_relevant: true
- ref: http.url
required: always
sampling_relevant: true
- ref: http.status_code
required: always
- ref: http.user_agent
required: always
sampling_relevant: true
brief: 'Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) or X-MS-UserAgent header sent by the client.'

# messaging
- id: azure.sdk.messaging
brief: 'Describes Azure messaging SDKs spans.'
extends: azure
note: Implements OpenTracing MessageBus conventions https://opentracing.io/specification/conventions/
attributes:
- id: message_bus.destination
type: string
required: always
brief: 'Name of the messaging entity within namespace: e.g EventHubs name, ServiceBus queue or topic name.'
examples: ['myqueue', 'myhub']
- id: peer.address
type: string
brief: 'Fully qualified messaging service name.'
required: always
examples: ['myEventHubNamespace.servicebus.windows.net']
Comment on lines +67 to +71
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about referencing net.peer.name from the general conventions here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once we'll switch to net.peer.name I'll use it and add a reference. But this is instrumentation exists for years and it can't be changed overnight.

Copy link
Member

@arminru arminru Jan 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah so that's not a new suggestion that just borrows from OpenTracing semconvs but it's documenting an existing instrumentation that's already in use?

- id: azure.sdk.messaging.producer
span_kind: producer
extends: azure.sdk.messaging
brief: 'Describes producer span created per message.'

- id: azure.sdk.messaging.send
span_kind: client
extends: azure.sdk.messaging
brief: 'Describes send (transport call) span.'
note: 'Contains links to all messages contexts being sent.'

- id: azure.sdk.messaging.process
span_kind: consumer
extends: azure.sdk.messaging
brief: 'Describes consumption span.'
note: >
Contains links to all messages contexts being consumed. Each link has `enqueued_time` (with `long` type)
attribute with unix epoch time with milliseconds precision representing when message was enqueued.

# CosmosDB
- id: azure.sdk.cosmos
span_kind: client
brief: 'Describes Azure CosmosDB spans.'
note: >
Events with additional debug info are added for long running or failed operations.
Implements https://github.com/open-telemetry/opentelemetry-specification/blob/v0.5.0/specification/trace/semantic_conventions/database.md
extends: azure
attributes:
- id: db.url
type: string
required: always
brief: 'Cosmos DB URI'
examples: ['https://my-cosmos.documents.azure.com:443/']
- ref: db.statement
required: always
examples: ['createContainerIfNotExists.myContainer']
- id: db.instance
type: string
required: always
brief: 'Database name'
examples: ['mydb']
- id: db.type
type: string
required: always
brief: 'Database type'
examples: ['Cosmos']
1 change: 1 addition & 0 deletions specification/trace/semantic_conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The following library-specific semantic conventions are defined:

* [AWS Lambda](instrumentation/aws-lambda.md): For AWS Lambda spans.
* [AWS SDK](instrumentation/aws-sdk.md): For AWS SDK spans.
* [Azure SDK](instrumentation/azure-sdk.md): For Azure SDK spans.

Apart from semantic conventions for traces and [metrics](../../metrics/semantic_conventions/README.md),
OpenTelemetry also defines the concept of overarching [Resources](../../resource/sdk.md) with their own
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Semantic conventions for Azure SDK
lmolkova marked this conversation as resolved.
Show resolved Hide resolved

**Status**: [Experimental](../../../document-status.md)

This document describes tracing semantic conventions adopted by Azure SDK. Instrumentations live in Azure SDK repos and are shipped along with Azure SDK artifacts. Instrumentations cover all modern (track 2) Azure client libraries.
lmolkova marked this conversation as resolved.
Show resolved Hide resolved

- [Java](https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/core/azure-core-tracing-opentelemetry)
- [JavaScript](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-tracing)
- [Python](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core-tracing-opentelemetry)
- [.NET](https://github.com/Azure/azure-sdk-for-net/blob/5ce907df6490e68c2e632d97048a6b6ee95c01f0/sdk/core/Azure.Core/samples/Diagnostics.md#activitysource-support)

Azure SDK produces spans for public API calls and nested HTTP client spans. Non-HTTP transport-level calls (AMQP, CosmosDB TCP-based protocol) are not traced.

## Versioning

Azure SDK semantic conventions pin specific versions of OpenTelemetry semantic conventions (where applicable) and are not updated regularly to the latest OpenTelemetry semantic conventions version. However OpenTelemetry-compatible changes should be expected.

Azure SDK plans to fully adopt OpenTelemetry semantic conventions once they reach `Stable` status.

## Common Attributes

All Azure SDKs spans have `az.namespace` attribute to uniquely identify *Azure SDK* request is made *from*, usually the value matches the destination Azure service, but in some cases client library can support multiple services.

<!-- semconv azure -->
| Attribute | Type | Description | Examples | Required |
|---|---|---|---|---|
| `az.namespace` | string | [Namespace](https://docs.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) of Azure service that the request is made against. | `Microsoft.Storage`; `Microsoft.KeyVault`; `Microsoft.ServiceBus` | Yes |

Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions:

* `az.namespace`
<!-- endsemconv -->

## Public API calls

Azure SDKs create a span for public API call (that involves communication with Azure services).

- Spans representing public APIs have names following `client.method` pattern, which is language-specific.
- For HTTP-based SDKs, public API spans have `INTERNAL` kind.

[Messaging](#messaging-sdks) and [CosmosDb](#cosmosdb) sections below describe non-HTTP semantics.

## HTTP Client

Azure SDK implements a valid subset of [OpenTelemetry HTTP conventions v1.8.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/trace/semantic_conventions/http.md) and create a span per HTTP call (attempt).

<!-- semconv azure.sdk.http -->
| Attribute | Type | Description | Examples | Required |
|---|---|---|---|---|
| `request_id` | string | Value of the "x-ms-client-request-id" header (or other "*-request-id" header, depending on the service) sent by the client. | `eb178587-c05a-418c-a695-ae9466c5303c` | Yes |
| `service_request_id` | string | Value of the "x-ms-request-id" header (or other "*-request-id" header, depending on the service) sent by the server in response. | `3f828ae5-ecb9-40ab-88d9-db0420af30c6` | Yes |
| [`http.method`](../http.md) | string | HTTP request method. | `GET`; `POST`; `HEAD` | Yes |
| [`http.status_code`](../http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Yes |
| [`http.url`](../http.md) | string | Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | Yes |
| [`http.user_agent`](../http.md) | string | Value of the [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) or X-MS-UserAgent header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Yes |

**[1]:** `http.url` MUST NOT contain credentials passed via URL in form of `https://username:[email protected]/`. In such case the attribute's value should be `https://www.example.com/`.

Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions:

* [`http.method`](../http.md)
* [`http.url`](../http.md)
* [`http.user_agent`](../http.md)
<!-- endsemconv -->

Instrumentation supports [W3C Trace context](https://w3c.github.io/trace-context/) propagation and Azure legacy correlation protocols. Propagator configuration is not supported.

## Messaging SDKs

Messaging span semantics apply to Azure Event Hubs and Service Bus SDKs.

Attribute names predate OpenTelemetry and originate from [OpenTracing semantic conventions](https://opentracing.io/specification/conventions/)

Messaging SDKs produce three kinds of spans:

- `PRODUCER` - describes message creation and associates unique context with the message to trace them when they are sent in batches.
- Producer spans name follows `<client>.message` pattern (e.g. `EventHubs.message`)

- `CLIENT` - describes message (or batch) publishing.
- It has links pointing to each message being sent.
- Links don't have attributes.
- Send spans name follows `<client>.send` pattern (e.g. `EventHubs.send`)

- `CONSUMER` - describes message (or batch) processing.
- It is created when user leverages handler APIs that wrap message or batch processing.
- Processing span has links to each message being processed (when context is present).
- Each link has `enqueued_time` attribute with `long` value with unix epoch time (with milliseconds precision) representing when message was enqueued on the broker.

### Messaging attributes

<!-- semconv azure.sdk.messaging -->
| Attribute | Type | Description | Examples | Required |
|---|---|---|---|---|
| `message_bus.destination` | string | Name of the messaging entity within namespace: e.g EventHubs name, ServiceBus queue or topic name. | `myqueue`; `myhub` | Yes |
| `peer.address` | string | Fully qualified messaging service name. | `myEventHubNamespace.servicebus.windows.net` | Yes |
<!-- endsemconv -->

## CosmosDB

CosmosDB SDK in [Direct mode](https://docs.microsoft.com/azure/cosmos-db/sql/sql-sdk-connection-modes#available-connectivity-modes) uses TCP-based protocol and traces public API calls only.
CosmosDB semantic conventions are pinned to OpenTelemetry [Semantic Conventions v0.5.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v0.5.0/specification/trace/semantic_conventions/database.md) version.

Spans have `CLIENT` kind and the name matches `db.statement` value. When CosmosDB detects an error or long operation (with configurable threshold), it adds a span event with extended `CosmosDiagnostics` information.

### CosmosDB attributes

<!-- semconv azure.sdk.cosmos -->
| Attribute | Type | Description | Examples | Required |
|---|---|---|---|---|
| `db.url` | string | Cosmos DB URI | `https://my-cosmos.documents.azure.com:443/` | Yes |
| `db.instance` | string | Database name | `mydb` | Yes |
| `db.type` | string | Database type | `Cosmos` | Yes |
| [`db.statement`](../database.md) | string | The database statement being executed. [1] | `createContainerIfNotExists.myContainer` | Yes |

**[1]:** The value may be sanitized to exclude sensitive information.
<!-- endsemconv -->