diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index 96d7455c249..dac3ae97bb1 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -4,6 +4,12 @@ "pattern": "^https://github\\.com/open-telemetry/opentelemetry-specification/(issues|pull)" } ], + "replacementPatterns": [ + { + "pattern": "^/", + "replacement": "{{BASEURL}}/" + } + ], "retryOn429": true, "aliveStatusCodes": [ 200, diff --git a/CHANGELOG.md b/CHANGELOG.md index 14ae7e081b9..cffd1de1651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,36 +15,104 @@ release. ### Logs +### Resource + +### Semantic Conventions + +- Move X-Ray Env Variable propagation to span link instead of parent for AWS Lambda. + ([#3166](https://github.com/open-telemetry/opentelemetry-specification/pull/3166)) + +### Compatibility + +### OpenTelemetry Protocol + +### SDK Configuration + +### Telemetry Schemas + +### Common + +## v1.18.0 (2023-02-09) + +### Context + +- No changes. + +### Traces + +- Clarify guidance regarding excessive logging when attributes are dropped + or truncated. + ([#3151](https://github.com/open-telemetry/opentelemetry-specification/pull/3151)) + +### Metrics + +- No changes. + +### Logs + - Define BatchLogRecordProcessor default configuration values. ([#3002](https://github.com/open-telemetry/opentelemetry-specification/pull/3002)) +- Clarify guidance regarding excessive logging when attributes are dropped + or truncated. + ([#3151](https://github.com/open-telemetry/opentelemetry-specification/pull/3151)) ### Resource +- No changes. + ### Semantic Conventions +- Add Cloud Spanner and Microsoft SQL Server Compact to db.system semantic conventions + ([#3105](https://github.com/open-telemetry/opentelemetry-specification/pull/3105)). - Enable semantic convention tooling for metrics in spec ([#3119](https://github.com/open-telemetry/opentelemetry-specification/pull/3119)) - Rename google openshift platform attribute from `google_cloud_openshift` to `gcp_openshift` to match the existing `cloud.provider` prefix. - [#3095](https://github.com/open-telemetry/opentelemetry-specification/pull/3095) + ([#3095](https://github.com/open-telemetry/opentelemetry-specification/pull/3095)) +- Changes http server span names from `{http.route}` to `{http.method} {http.route}` + (when route is available), and from `HTTP {http.method}` to `{http.method}` (when + route is not available). + Changes http client span names from `HTTP {http.method}` to `{http.method}`. + ([#3165](https://github.com/open-telemetry/opentelemetry-specification/pull/3165)) +- Mark `http.server.duration` and `http.client.duration` metrics as required, and mark + all other HTTP metrics as optional. + [#3158](https://github.com/open-telemetry/opentelemetry-specification/pull/3158) +- Add `net.host.port` to `http.server.active_requests` metrics attributes. + [#3158](https://github.com/open-telemetry/opentelemetry-specification/pull/3158) +- `http.route` SHOULD contain the "application root" if there is one. + ([#3164](https://github.com/open-telemetry/opentelemetry-specification/pull/3164)) ### Compatibility +- Add condition with sum and count for Prometheus summaries + ([3059](https://github.com/open-telemetry/opentelemetry-specification/pull/3059)). +- Clarify prometheus unit conversions + ([#3066](https://github.com/open-telemetry/opentelemetry-specification/pull/3066)). +- Define conversion mapping from OTel Exponential Histograms to Prometheus Native + Histograms. + ([#3079](https://github.com/open-telemetry/opentelemetry-specification/pull/3079)) - Fix Prometheus histogram metric suffixes. Bucket series end in `_bucket` ([#3018](https://github.com/open-telemetry/opentelemetry-specification/pull/3018)). ### OpenTelemetry Protocol +- No changes. + ### SDK Configuration +- Add log-specific attribute limit configuration and clarify that general + attribute limit configuration also apply to log records + ([#2861](https://github.com/open-telemetry/opentelemetry-specification/pull/2861)). + ### Telemetry Schemas +- No changes. + ### Common -## v1.17.0 (2023-01-17) +- No changes. -- Add Cloud Spanner and Microsoft SQL Server Compact to db.system semantic conventions. - [#3105](https://github.com/open-telemetry/opentelemetry-specification/pull/3105) +## v1.17.0 (2023-01-17) ### Context @@ -119,8 +187,6 @@ release. - Add OpenCensus migration guide and add BinaryPropagation as an option to gRPC instrumentation for OpenCensus compatibility ([#3015](https://github.com/open-telemetry/opentelemetry-specification/pull/3015)). -- Add condition with sum and count for Prometheus summaries -([3059](https://github.com/open-telemetry/opentelemetry-specification/pull/3059)) ### OpenTelemetry Protocol @@ -215,9 +281,6 @@ release. - Specify handling of invalid numeric environment variables ([#2963](https://github.com/open-telemetry/opentelemetry-specification/pull/2963)) -- Add log-specific attribute limit configuration and clarify that general - attribute limit configuration also apply to log records. - ([#2861](https://github.com/open-telemetry/opentelemetry-specification/pull/2861)) ### Telemetry Schemas diff --git a/schemas/1.18.0 b/schemas/1.18.0 new file mode 100644 index 00000000000..400bd0969e0 --- /dev/null +++ b/schemas/1.18.0 @@ -0,0 +1,60 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.18.0 +versions: + 1.18.0: + 1.17.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/2957 + - rename_attributes: + attribute_map: + messaging.consumer_id: messaging.consumer.id + messaging.protocol: net.app.protocol.name + messaging.protocol_version: net.app.protocol.version + messaging.destination: messaging.destination.name + messaging.temp_destination: messaging.destination.temporary + messaging.destination_kind: messaging.destination.kind + messaging.message_id: messaging.message.id + messaging.conversation_id: messaging.message.conversation_id + messaging.message_payload_size_bytes: messaging.message.payload_size_bytes + messaging.message_payload_compressed_size_bytes: messaging.message.payload_compressed_size_bytes + messaging.rabbitmq.routing_key: messaging.rabbitmq.destination.routing_key + messaging.kafka.message_key: messaging.kafka.message.key + messaging.kafka.partition: messaging.kafka.destination.partition + messaging.kafka.tombstone: messaging.kafka.message.tombstone + messaging.rocketmq.message_type: messaging.rocketmq.message.type + messaging.rocketmq.message_tag: messaging.rocketmq.message.tag + messaging.rocketmq.message_keys: messaging.rocketmq.message.keys + messaging.kafka.consumer_group: messaging.kafka.consumer.group + 1.16.0: + 1.15.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/2743 + - rename_attributes: + attribute_map: + http.retry_count: http.resend_count + 1.14.0: + 1.13.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/2614 + - rename_attributes: + attribute_map: + net.peer.ip: net.sock.peer.addr + net.host.ip: net.sock.host.addr + 1.12.0: + 1.11.0: + 1.10.0: + 1.9.0: + 1.8.0: + spans: + changes: + - rename_attributes: + attribute_map: + db.cassandra.keyspace: db.name + db.hbase.namespace: db.name + 1.7.0: + 1.6.1: + 1.5.0: + 1.4.0: diff --git a/semantic_conventions/http-common.yaml b/semantic_conventions/http-common.yaml new file mode 100644 index 00000000000..8d1bf194494 --- /dev/null +++ b/semantic_conventions/http-common.yaml @@ -0,0 +1,120 @@ +groups: + - id: attributes.http.common + type: attribute_group + brief: "Describes HTTP attributes." + prefix: http + attributes: + - id: method + type: string + requirement_level: required + brief: 'HTTP request method.' + examples: ["GET", "POST", "HEAD"] + - id: status_code + type: int + requirement_level: + conditionally_required: If and only if one was received/sent. + brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' + examples: [200] + - id: flavor + type: + # Default value: `true`. If false, it helps the code gen tool to + # encode checks that only accept the listed values. + allow_custom_values: true + members: + - id: http_1_0 + value: '1.0' + brief: 'HTTP/1.0' + - id: http_1_1 + value: '1.1' + brief: 'HTTP/1.1' + - id: http_2_0 + value: '2.0' + brief: 'HTTP/2' + - id: http_3_0 + value: '3.0' + brief: 'HTTP/3' + - id: spdy + value: 'SPDY' + brief: 'SPDY protocol.' + - id: quic + value: 'QUIC' + brief: 'QUIC protocol.' + brief: 'Kind of HTTP protocol used.' + note: > + If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` + is `QUIC`, in which case `IP.UDP` is assumed. + + - id: attributes.http.client + prefix: http + type: attribute_group + brief: 'HTTP Client spans attributes' + attributes: + - ref: net.peer.name + requirement_level: required + brief: > + Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + note: | + Determined by using the first of the following that applies + + - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form + - Host identifier of the `Host` header + + SHOULD NOT be set if capturing it would require an extra DNS lookup. + - ref: net.peer.port + requirement_level: + conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). + brief: > + Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + note: > + When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `net.peer.name` MUST match + URI port identifier, otherwise it MUST match `Host` header port identifier. + + - id: attributes.http.server + prefix: http + type: attribute_group + brief: 'HTTP Server spans attributes' + attributes: + - id: scheme + type: string + brief: 'The URI scheme identifying the used protocol.' + requirement_level: required + examples: ["http", "https"] + - id: route + type: string + requirement_level: + conditionally_required: If and only if it's available + brief: > + The matched route (path template in the format used by the respective server framework). See note below + examples: ['/users/:userID?', '{controller}/{action}/{id?}'] + note: > + MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. + + SHOULD include the [application root](/specification/trace/semantic_conventions/http.md#http-server-definitions) if there is one. + - ref: net.host.name + requirement_level: required + brief: > + Name of the local HTTP server that received the request. + note: | + Determined by using the first of the following that applies + + - The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. + - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. + - Host identifier of the `Host` header + + SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + + - ref: net.host.port + requirement_level: + conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). + brief: > + Port of the local HTTP server that received the request. + note: | + Determined by using the first of the following that applies + + - Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. + - Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. + - Port identifier of the `Host` header diff --git a/semantic_conventions/logs/events.yaml b/semantic_conventions/logs/events.yaml index 7d7d80f88df..f3398c9ac12 100644 --- a/semantic_conventions/logs/events.yaml +++ b/semantic_conventions/logs/events.yaml @@ -1,6 +1,6 @@ groups: - id: event - type: span + type: attribute_group prefix: event brief: > This document defines attributes for Events represented using Log Records. diff --git a/semantic_conventions/logs/log-exception.yaml b/semantic_conventions/logs/log-exception.yaml index 94c52ba80cd..d0b251552aa 100644 --- a/semantic_conventions/logs/log-exception.yaml +++ b/semantic_conventions/logs/log-exception.yaml @@ -1,6 +1,6 @@ groups: - id: log-exception - type: span + type: attribute_group prefix: exception brief: > This document defines attributes for exceptions represented using Log diff --git a/semantic_conventions/metrics/http.yaml b/semantic_conventions/metrics/http.yaml new file mode 100644 index 00000000000..cb23f27e927 --- /dev/null +++ b/semantic_conventions/metrics/http.yaml @@ -0,0 +1,119 @@ +groups: + - id: metric.http.server.duration + type: metric + metric_name: http.server.duration + brief: "Measures the duration of inbound HTTP requests." + instrument: histogram + unit: "ms" + extends: attributes.http.server + attributes: + # todo (lmolkova) build tools don't populate grandparent attributes + - ref: http.method + - ref: http.status_code + - ref: http.flavor + + - id: metric.http.server.active_requests + type: metric + metric_name: http.server.active_requests + brief: "Measures the number of concurrent HTTP requests that are currently in-flight." + instrument: updowncounter + unit: "{requests}" + attributes: + - ref: http.method + - ref: http.status_code + - ref: http.scheme + - ref: net.host.name + requirement_level: required + brief: > + Name of the local HTTP server that received the request. + note: | + Determined by using the first of the following that applies + + - The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. + - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. + - Host identifier of the `Host` header + + SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + + - ref: net.host.port + requirement_level: + conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). + brief: > + Port of the local HTTP server that received the request. + note: | + Determined by using the first of the following that applies + + - Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. + - Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. + - Port identifier of the `Host` header + + - id: metric.http.server.request.size + type: metric + metric_name: http.server.request.size + brief: "Measures the size of HTTP request messages (compressed)." + instrument: histogram + unit: "By" + extends: attributes.http.server + # TODO (trask) below attributes are identical to above in metric.http.server.duration + attributes: + # todo (lmolkova) build tools don't populate grandparent attributes + - ref: http.method + - ref: http.status_code + - ref: http.flavor + + - id: metric.http.server.response.size + type: metric + metric_name: http.server.response.size + brief: "Measures the size of HTTP response messages (compressed)." + instrument: histogram + unit: "By" + extends: attributes.http.server + # TODO (trask) below attributes are identical to above in metric.http.server.duration + attributes: + - ref: http.method + - ref: http.status_code + - ref: http.flavor + + - id: metric.http.client.duration + type: metric + metric_name: http.client.duration + brief: "Measures the duration of outbound HTTP requests." + instrument: histogram + unit: "ms" + extends: attributes.http.client + attributes: + - ref: http.method + - ref: http.status_code + - ref: http.flavor + - ref: net.sock.peer.addr + + - id: metric.http.client.request.size + type: metric + metric_name: http.client.request.size + brief: "Measures the size of HTTP request messages (compressed)." + instrument: histogram + unit: "By" + extends: attributes.http.client + # TODO (trask) below attributes are identical to above in metric.http.client.duration + attributes: + - ref: http.method + - ref: http.status_code + - ref: http.flavor + - ref: net.sock.peer.addr + + - id: metric.http.client.response.size + type: metric + metric_name: http.client.response.size + brief: "Measures the size of HTTP response messages (compressed)." + instrument: histogram + unit: "By" + extends: attributes.http.client + # TODO (trask) below attributes are identical to above in metric.http.client.duration + attributes: + - ref: http.method + - ref: http.status_code + - ref: http.flavor + - ref: net.sock.peer.addr diff --git a/semantic_conventions/trace/faas.yaml b/semantic_conventions/trace/faas.yaml index fac000a7cef..ff4963b164d 100644 --- a/semantic_conventions/trace/faas.yaml +++ b/semantic_conventions/trace/faas.yaml @@ -95,7 +95,7 @@ groups: Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write. constraints: - - include: http.server + - include: trace.http.server - id: faas_span.pubsub type: span diff --git a/semantic_conventions/trace/general.yaml b/semantic_conventions/trace/general.yaml index 4491cc10290..54403442946 100644 --- a/semantic_conventions/trace/general.yaml +++ b/semantic_conventions/trace/general.yaml @@ -1,7 +1,7 @@ groups: - id: network prefix: net - type: span + type: attribute_group brief: > These attributes may be used for any network related operation. attributes: diff --git a/semantic_conventions/trace/http.yaml b/semantic_conventions/trace/http.yaml index d29672e4d3f..6b2eefbeacb 100644 --- a/semantic_conventions/trace/http.yaml +++ b/semantic_conventions/trace/http.yaml @@ -1,52 +1,13 @@ groups: - - id: http + - id: trace.http.common prefix: http - type: span + extends: attributes.http.common + type: attribute_group brief: 'This document defines semantic conventions for HTTP client and server Spans.' note: > These conventions can be used for http and https schemes and various HTTP versions like 1.1, 2 and SPDY. attributes: - - id: method - type: string - requirement_level: required - brief: 'HTTP request method.' - sampling_relevant: true - examples: ["GET", "POST", "HEAD"] - - id: status_code - type: int - requirement_level: - conditionally_required: If and only if one was received/sent. - brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' - examples: [200] - - id: flavor - type: - # Default value: `true`. If false, it helps the code gen tool to - # encode checks that only accept the listed values. - allow_custom_values: true - members: - - id: http_1_0 - value: '1.0' - brief: 'HTTP/1.0' - - id: http_1_1 - value: '1.1' - brief: 'HTTP/1.1' - - id: http_2_0 - value: '2.0' - brief: 'HTTP/2' - - id: http_3_0 - value: '3.0' - brief: 'HTTP/3' - - id: spdy - value: 'SPDY' - brief: 'SPDY protocol.' - - id: quic - value: 'QUIC' - brief: 'QUIC protocol.' - brief: 'Kind of HTTP protocol used.' - note: > - If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` - is `QUIC`, in which case `IP.UDP` is assumed. - id: user_agent type: string brief: 'Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.' @@ -65,18 +26,18 @@ groups: is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. examples: 3495 + - ref: http.method + sampling_relevant: true - ref: net.sock.peer.addr - ref: net.sock.peer.port - ref: net.sock.peer.name - ref: net.sock.family examples: ['inet', 'inet6'] - constraints: - - include: network - - id: http.client + - id: trace.http.client prefix: http type: span - extends: http + extends: attributes.http.client span_kind: client brief: 'Semantic Convention for HTTP Client' attributes: @@ -91,9 +52,20 @@ groups: In such case the attribute's value should be `https://www.example.com/`. sampling_relevant: true examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] + - id: resend_count + type: int + brief: > + The ordinal number of request resending attempt (for any reason, including redirects). + note: > + The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what + was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, + or any other). + requirement_level: + recommended: if and only if request was retried. + examples: 3 - ref: net.peer.name - requirement_level: required sampling_relevant: true + requirement_level: required brief: > Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. note: | @@ -113,46 +85,20 @@ groups: note: > When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `net.peer.name` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. - - id: resend_count - type: int - brief: > - The ordinal number of request resending attempt (for any reason, including redirects). - note: > - The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what - was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, - or any other). - requirement_level: - recommended: if and only if request was retried. - examples: 3 - - id: http.server + - id: trace.http.server prefix: http type: span - extends: http + extends: attributes.http.server span_kind: server brief: 'Semantic Convention for HTTP Server' attributes: - - id: scheme - type: string - brief: 'The URI scheme identifying the used protocol.' - requirement_level: required - sampling_relevant: true - examples: ["http", "https"] - id: target type: string brief: 'The full request target as passed in a HTTP request line or equivalent.' requirement_level: required sampling_relevant: true examples: ['/path/12314/?q=ddds'] - - id: route - type: string - requirement_level: - conditionally_required: If and only if it's available - brief: > - The matched route (path template in the format used by the respective server framework). See note below - examples: ['/users/:userID?', '{controller}/{action}/{id?}'] - note: > - 'http.route' MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. - id: client_ip type: string brief: > @@ -171,6 +117,8 @@ groups: one is at least somewhat confident that the address is not that of the closest proxy. examples: '83.164.160.102' + - ref: http.scheme + sampling_relevant: true - ref: net.host.name requirement_level: required sampling_relevant: true @@ -179,7 +127,7 @@ groups: note: | Determined by using the first of the following that applies - - The [primary server name](#http-server-definitions) of the matched virtual host. MUST only + - The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) if it's sent in absolute-form. @@ -196,11 +144,10 @@ groups: note: | Determined by using the first of the following that applies - - Port identifier of the [primary server host](#http-server-definitions) of the matched virtual host. + - Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. - Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) if it's sent in absolute-form. - Port identifier of the `Host` header - - ref: net.sock.host.addr requirement_level: optional - ref: net.sock.host.port diff --git a/semantic_conventions/trace/messaging.yaml b/semantic_conventions/trace/messaging.yaml index 83b049f4561..e89f6b6f944 100644 --- a/semantic_conventions/trace/messaging.yaml +++ b/semantic_conventions/trace/messaging.yaml @@ -1,8 +1,7 @@ groups: - id: messaging.message prefix: messaging - # todo (https://github.com/open-telemetry/build-tools/issues/123) - type: span + type: attribute_group brief: 'Semantic convention describing per-message attributes populated on messaging spans or links.' attributes: - ref: messaging.destination.name @@ -30,8 +29,7 @@ groups: - id: messaging.destination prefix: messaging.destination - # todo (https://github.com/open-telemetry/build-tools/issues/123) - type: span + type: attribute_group brief: 'Semantic convention for attributes that describe messaging destination on broker' attributes: - id: name @@ -71,8 +69,7 @@ groups: - id: messaging.source prefix: messaging.source - # todo (https://github.com/open-telemetry/build-tools/issues/123) - type: span + type: attribute_group brief: 'Semantic convention for attributes that describe messaging source on broker' attributes: - id: name @@ -270,7 +267,7 @@ groups: - id: messaging.rabbitmq prefix: messaging.rabbitmq - type: span + type: attribute_group extends: messaging brief: > Attributes for RabbitMQ @@ -285,7 +282,7 @@ groups: - id: messaging.kafka prefix: messaging.kafka - type: span + type: attribute_group extends: messaging brief: > Attributes for Apache Kafka @@ -334,7 +331,7 @@ groups: - id: messaging.rocketmq prefix: messaging.rocketmq - type: span + type: attribute_group extends: messaging brief: > Attributes for Apache RocketMQ diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index c3ff23a5570..a19b9b16e80 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -28,7 +28,7 @@ formats is required. Implementing more than one format is optional. | [Trace / Context interaction](specification/trace/api.md#context-interaction) | | | | | | | | | | | | | | Get active Span | | N/A | + | + | + | + | + | + | + | + | + | + | | Set active Span | | N/A | + | + | + | + | + | + | + | + | + | + | -| [Tracer](specification/trace/api.md#tracer-operations) | | | | | | | | | | | | | +| [Tracer](specification/trace/api.md#tracer-operations) | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | | Create a new Span | | + | + | + | + | + | + | + | + | + | + | + | | Documentation defines adding attributes at span creation as preferred | | | | | + | + | | + | | | + | | | Get active Span | | N/A | + | + | + | + | + | + | + | + | + | + | @@ -38,7 +38,7 @@ formats is required. Implementing more than one format is optional. | IsValid | | + | + | + | + | + | + | + | + | + | + | + | | IsRemote | | + | + | + | + | + | + | + | + | + | + | + | | Conforms to the W3C TraceContext spec | | + | + | + | + | + | + | + | + | + | + | + | -| [Span](specification/trace/api.md#span) | | | | | | | | | | | | | +| [Span](specification/trace/api.md#span) | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | | Create root span | | + | + | + | + | + | + | + | + | + | + | + | | Create with default parent (active span) | | N/A | + | + | + | + | + | + | + | + | + | + | | Create with parent from Context | | + | + | + | + | + | + | + | + | + | + | + | @@ -55,7 +55,7 @@ formats is required. Implementing more than one format is optional. | events collection size limit | | + | + | + | + | + | + | + | + | - | - | + | | attribute collection size limit | | + | + | + | + | + | + | + | + | - | - | + | | links collection size limit | | + | + | + | + | + | + | + | + | - | - | + | -| [Span attributes](specification/trace/api.md#set-attributes) | | | | | | | | | | | | | +| [Span attributes](specification/trace/api.md#set-attributes) | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | | SetAttribute | | + | + | + | + | + | + | + | + | + | + | + | | Set order preserved | X | + | - | + | + | + | + | + | + | + | + | + | | String type | | + | + | + | + | + | + | + | + | + | + | + | @@ -65,7 +65,7 @@ formats is required. Implementing more than one format is optional. | Array of primitives (homogeneous) | | + | + | + | + | + | + | + | + | + | + | + | | `null` values documented as invalid/undefined | | + | + | + | + | + | N/A | + | | + | | N/A | | Unicode support for keys and string values | | + | + | + | + | + | + | + | + | + | + | + | -| [Span linking](specification/trace/api.md#specifying-links) | | | | | | | | | | | | | +| [Span linking](specification/trace/api.md#specifying-links) | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | | Links can be recorded on span creation | | + | + | | + | + | + | + | + | + | + | | | Links order is preserved | | + | + | | + | + | + | + | + | + | + | | | [Span events](specification/trace/api.md#add-events) | | | | | | | | | | | | | @@ -75,9 +75,10 @@ formats is required. Implementing more than one format is optional. | [Span exceptions](specification/trace/api.md#record-exception) | | | | | | | | | | | | | | RecordException | | - | + | + | + | + | + | + | + | - | + | - | | RecordException with extra parameters | | - | + | + | + | + | + | + | + | - | + | - | -| [Sampling](specification/trace/sdk.md#sampling) | | | | | | | | | | | | | +| [Sampling](specification/trace/sdk.md#sampling) | Optional | Go | Java | JS | Python | Ruby | Erlang | PHP | Rust | C++ | .NET | Swift | | Allow samplers to modify tracestate | | + | + | | + | + | + | + | + | + | - | + | | ShouldSample gets full parent Context | | + | + | + | + | + | + | + | + | + | - | + | +| Sampler: JaegerRemoteSampler | | + | + | | | | | | + | | | | | [New Span ID created also for non-recording Spans](specification/trace/sdk.md#sdk-span-creation) | | + | + | | + | + | + | + | + | + | - | + | | [IdGenerators](specification/trace/sdk.md#id-generators) | | + | + | | + | + | + | + | + | + | | + | | [SpanLimits](specification/trace/sdk.md#span-limits) | X | + | + | | + | + | + | + | | - | | + | diff --git a/specification/compatibility/prometheus_and_openmetrics.md b/specification/compatibility/prometheus_and_openmetrics.md index 5314b1bb2f5..6db6993b0f8 100644 --- a/specification/compatibility/prometheus_and_openmetrics.md +++ b/specification/compatibility/prometheus_and_openmetrics.md @@ -27,8 +27,8 @@ * [Gauges](#gauges-1) * [Sums](#sums) * [Histograms](#histograms-1) + * [Exponential Histograms](#exponential-histograms) * [Summaries](#summaries-1) - * [Dropped Data Points](#dropped-data-points) * [Metric Attributes](#metric-attributes) * [Exemplars](#exemplars-1) * [Resource Attributes](#resource-attributes-1) @@ -293,6 +293,41 @@ An [OpenTelemetry Histogram](../metrics/data-model.md#histogram) with a cumulati OpenTelemetry Histograms with Delta aggregation temporality SHOULD be aggregated into a Cumulative aggregation temporality and follow the logic above, or MUST be dropped. +### Exponential Histograms + +An [OpenTelemetry Exponential Histogram](../metrics/data-model.md#exponentialhistogram) with +a cumulative aggregation temporality MUST be converted to a Prometheus Native +Histogram as follows: + +- `Scale` is converted to the Native Histogram `Schema`. Currently, + [valid values](https://github.com/prometheus/prometheus/commit/d9d51c565c622cdc7d626d3e7569652bc28abe15#diff-bdaf80ebc5fa26365f45db53435b960ce623ea6f86747fb8870ad1abc355f64fR76-R83) + for `schema` are -4 <= n <= 8. + If `Scale` is > 8 then Exponential Histogram data points SHOULD be downscaled + to a scale accepted by Prometheus (in range [-4,8]). Any data point unable to + be rescaled to an acceptable range MUST be dropped. +- `Count` is converted to Native Histogram `Count` if the `NoRecordedValue` + flag is set to `false`, otherwise, Native Histogram `Count` is set to the + Stale NaN value. +- `Sum` is converted to the Native Histogram `Sum` if `Sum` is set and the + `NoRecordedValue` flag is set to `false`, otherwise, Native Histogram `Sum` is + set to the Stale NaN value. +- `TimeUnixNano` is converted to the Native Histogram `Timestamp` after + converting nanoseconds to milliseconds. +- `ZeroCount` is converted directly to the Native Histogram `ZeroCount`. +- `ZeroThreshold`, if set, is converted to the Native Histogram `ZeroThreshold`. + Otherwise, it is set to the default value `1e-128`. +- The dense bucket layout represented by `Positive` bucket counts and `Offset` is + converted to the Native Histogram sparse layout represented by `PositiveSpans` + and `PositiveDeltas`. The same holds for the `Negative` bucket counts + and `Offset`. Note that Prometheus Native Histograms buckets are indexed by + upper boundary while Exponential Histograms are indexed by lower boundary, the + result being that the Offset fields are different-by-one. +- `Min` and `Max` are not used. +- `StartTimeUnixNano` is not used. + +[OpenTelemetry Exponential Histogram](../metrics/data-model.md#exponentialhistogram) +metrics with the delta aggregation temporality are dropped. + ### Summaries An [OpenTelemetry Summary](../metrics/data-model.md#summary-legacy) MUST be converted to a Prometheus metric family with the following metrics: @@ -310,12 +345,6 @@ An [OpenTelemetry Summary](../metrics/data-model.md#summary-legacy) MUST be conv each point is the computed value of the quantile point. - Summaries with `StartTimeUnixNano` set should export the `{name}_created` metric as well. -### Dropped Data Points - -The following OTLP data points MUST be dropped: - -* [ExponentialHistogram](../metrics/data-model.md#exponentialhistogram) - ### Metric Attributes OpenTelemetry Metric Attributes MUST be converted to diff --git a/specification/logs/data-model.md b/specification/logs/data-model.md index 8d7221b094a..58faec0e78c 100644 --- a/specification/logs/data-model.md +++ b/specification/logs/data-model.md @@ -549,7 +549,7 @@ Can include data that describes particular occurrence of the event. Can be meta-information, e.g. quality of timestamp value. SDID origin.swVersion map to Resource["service.version"] -SDID origin.ip map to attribute[net.host.ip"] +SDID origin.ip map to attribute["net.sock.host.addr"] Rest of SDIDs -> Attributes["syslog.*"] @@ -846,19 +846,19 @@ When mapping from the unified model to HEC, we apply this additional mapping: %a string - Client IP - Attributes["net.peer.ip"] + Client address + Attributes["net.sock.peer.addr"] %A string - Server IP - Attributes["net.host.ip"] + Server address + Attributes["net.sock.host.addr"] %h string - Remote hostname. + Client hostname. Attributes["net.peer.name"] @@ -918,7 +918,7 @@ When mapping from the unified model to HEC, we apply this additional mapping: sourceIPAddress string The IP address that the request was made from. - Resource["net.peer.ip"] or Resource["net.host.ip"]? TBD + Attributes["net.sock.peer.addr"] or Attributes["net.sock.host.addr"] errorCode @@ -1036,7 +1036,7 @@ All other fields | | source.ip, client.ip string The IP address that the request was made from. - Attributes["net.peer.ip"] or Attributes["net.host.ip"] + Attributes["net.sock.peer.addr"] or Attributes["net.sock.host.addr"] cloud.account.id diff --git a/specification/logs/sdk.md b/specification/logs/sdk.md index 77853fcfe56..425c4121efd 100644 --- a/specification/logs/sdk.md +++ b/specification/logs/sdk.md @@ -153,8 +153,8 @@ public interface LogRecordLimits { There SHOULD be a message printed in the SDK's log to indicate to the user that an attribute was discarded due to such a limit. -To prevent excessive logging, the message should not be printed once per -`LogRecord` or per discarded attribute. +To prevent excessive logging, the message MUST be printed at most once per +`LogRecord` (i.e., not per discarded attribute). ## LogRecordProcessor diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 663e4d46a17..5bac1968ec0 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -19,9 +19,7 @@ linkTitle: API * [Meter operations](#meter-operations) - [Instrument](#instrument) * [General characteristics](#general-characteristics) - + [Instrument type conflict detection](#instrument-type-conflict-detection) - + [Instrument namespace](#instrument-namespace) - + [Instrument naming rule](#instrument-naming-rule) + + [Instrument name syntax](#instrument-name-syntax) + [Instrument unit](#instrument-unit) + [Instrument description](#instrument-description) + [Synchronous and Asynchronous instruments](#synchronous-and-asynchronous-instruments) @@ -115,30 +113,16 @@ The `MeterProvider` MUST provide the following functions: This API MUST accept the following parameters: -* `name`: This name SHOULD uniquely identify the [instrumentation +* `name`: This name uniquely identifies the [instrumentation scope](../glossary.md#instrumentation-scope), such as the [instrumentation library](../glossary.md#instrumentation-library) (e.g. `io.opentelemetry.contrib.mongodb`), package, module or class name. If an application or library has built-in OpenTelemetry instrumentation, both [Instrumented library](../glossary.md#instrumented-library) and [Instrumentation - library](../glossary.md#instrumentation-library) may refer to the same + library](../glossary.md#instrumentation-library) can refer to the same library. In that scenario, the `name` denotes a module name or component name - within that library or application. In case an invalid name (null or empty - string) is specified, a working Meter implementation MUST be returned as a - fallback rather than returning null or throwing an exception, its `name` - property SHOULD keep the original invalid value, and a message reporting that - the specified value is invalid SHOULD be logged. A library, implementing the - OpenTelemetry API *may* also ignore this name and return a default instance - for all calls, if it does not support "named" functionality (e.g. an - implementation which is not even observability-related). A MeterProvider could - also return a no-op Meter here if application owners configure the SDK to - suppress telemetry produced by this library. - - The `name` needs to be provided by a user. If possible, the API SHOULD be - structured so a user is obligated to provide this parameter. If it is not - possible to structurally enforce this obligation, the API MUST be documented - in a way to communicate to users that this parameter is needed. + within that library or application. * `version`: Specifies the version of the instrumentation scope if the scope has a version (e.g. a library version). Example value: `1.0.0`. @@ -168,23 +152,6 @@ The term *identical* applied to Meters describes instances where all identifying fields are equal. The term *distinct* applied to Meters describes instances where at least one identifying field has a different value. -Implementations MUST NOT require users to repeatedly obtain a `Meter` with -the same identity to pick up configuration changes. This can be -achieved either by allowing to work with an outdated configuration or by -ensuring that new configuration applies also to previously returned `Meter`s. - -Note: This could, for example, be implemented by storing any mutable -configuration in the `MeterProvider` and having `Meter` implementation objects -have a reference to the `MeterProvider` from which they were obtained. If -configuration must be stored per-meter (such as disabling a certain meter), the -meter could, for example, do a look-up with its identity in a map -in the `MeterProvider`, or the `MeterProvider` could maintain a registry of all -returned `Meter`s and actively update their configuration if it changes. - -The effect of associating a Schema URL with a `Meter` MUST be that the telemetry -emitted using the `Meter` will be associated with the Schema URL, provided that -the emitted data format is capable of representing such association. - ## Meter The meter is responsible for creating [Instruments](#instrument). @@ -224,42 +191,10 @@ floating point numbers SHOULD be considered as identifying. ### General characteristics -#### Instrument type conflict detection - -When more than one Instrument of the same `name` is created for -identical Meters, denoted *duplicate instrument registration*, the -implementation MUST create a valid Instrument in every case. Here, -"valid" means an instrument that is functional and can be expected to -export data, despite potentially creating a [semantic error in the -data -model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations). +#### Instrument name syntax -It is unspecified whether or under which conditions the same or -different Instrument instance will be returned as a result of -duplicate instrument registration. The term *identical* applied to -Instruments describes instances where all identifying fields are -equal. The term *distinct* applied to Instruments describes instances -where at least one field value is different. - -When more than one distinct Instrument is registered with the same -`name` for identical Meters, the implementation SHOULD emit a warning -to the user informing them of duplicate registration conflict(s). -The warning helps to avoid the semantic error state described in the -[OpenTelemetry Metrics data -model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations) -when more than one `Metric` is written for a given instrument `name` -and Meter identity by the same MeterProvider. - -#### Instrument namespace - -Distinct Meters MUST be treated as separate namespaces for the -purposes of detecting [duplicate instrument registration -conflicts](#instrument-type-conflict-detection). - -#### Instrument naming rule - -Instrument names MUST conform to the following syntax (described using the -[Augmented Backus-Naur Form](https://tools.ietf.org/html/rfc5234)): +The instrument name syntax is defined below using the [Augmented Backus-Naur +Form](https://tools.ietf.org/html/rfc5234): ```abnf instrument-name = ALPHA 0*62 ("_" / "." / "-" / ALPHA / DIGIT) @@ -277,12 +212,9 @@ DIGIT = %x30-39 ; 0-9 #### Instrument unit -The `unit` is an optional string provided by the author of the Instrument. It -SHOULD be treated as an opaque string from the API and SDK (e.g. the SDK is not -expected to validate the unit of measurement, or perform the unit conversion). +The `unit` is an optional string provided by the author of the Instrument. The +API SHOULD treat it as an opaque string. -* If the `unit` is not provided or the `unit` is null, the API and SDK MUST make - sure that the behavior is the same as an empty `unit` string. * It MUST be case-sensitive (e.g. `kb` and `kB` are different units), ASCII string. * It can have a maximum length of 63 characters. The number 63 is chosen to @@ -293,11 +225,8 @@ expected to validate the unit of measurement, or perform the unit conversion). #### Instrument description The `description` is an optional free-form text provided by the author of the -instrument. It MUST be treated as an opaque string from the API and SDK. +instrument. The API MUST treat it as an opaque string. -* If the `description` is not provided or the `description` is null, the API and - SDK MUST make sure that the behavior is the same as an empty `description` - string. * It MUST support [BMP (Unicode Plane 0)](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), which is basically only the first three bytes of UTF-8 (or `utf8mb3`). @@ -340,11 +269,10 @@ The API to construct synchronous instruments MUST accept the following parameter possible to structurally enforce this obligation, the API MUST be documented in a way to communicate to users that this parameter is needed. - The `name` needs to follow the [instrument naming - rule](#instrument-naming-rule). The API SHOULD be documented in a way to - communicate to users that this parameter needs to conform to the linked - syntax. The API SHOULD NOT validate the `name`, that is left to - implementations of the API. + The API SHOULD be documented in a way to communicate to users that the `name` + parameter needs to conform to the [instrument name + syntax](#instrument-name-syntax). The API SHOULD NOT validate the `name`; + that is left to implementations of the API. * A `unit` of measure. Users can provide a `unit`, but it is up to their discretion. Therefore, this @@ -383,11 +311,10 @@ The API to construct asynchronous instruments MUST accept the following paramete possible to structurally enforce this obligation, the API MUST be documented in a way to communicate to users that this parameter is needed. - The `name` needs to follow the [instrument naming - rule](#instrument-naming-rule). The API SHOULD be documented in a way to - communicate to users that this parameter needs to conform to the linked - syntax. The API SHOULD NOT validate the `name`, that is left to - implementations of the API. + The API SHOULD be documented in a way to communicate to users that the `name` + parameter needs to conform to the [instrument name + syntax](#instrument-name-syntax). The API SHOULD NOT validate the `name`, + that is left to implementations of the API. * A `unit` of measure. Users can provide a `unit`, but it is up to their discretion. Therefore, this diff --git a/specification/metrics/noop.md b/specification/metrics/noop.md new file mode 100644 index 00000000000..94e72b70325 --- /dev/null +++ b/specification/metrics/noop.md @@ -0,0 +1,289 @@ + + +# Metrics No-Op API Implementation + +**Status**: [Experimental](../document-status.md) + +
+ Table of Contents + + + +- [MeterProvider](#meterprovider) + * [Meter Creation](#meter-creation) +- [Meter](#meter) + * [Counter Creation](#counter-creation) + * [UpDownCounter Creation](#updowncounter-creation) + * [Histogram Creation](#histogram-creation) + * [Asynchronous Counter Creation](#asynchronous-counter-creation) + * [Asynchronous UpDownCounter Creation](#asynchronous-updowncounter-creation) + * [Asynchronous Gauge Creation](#asynchronous-gauge-creation) +- [Instruments](#instruments) + * [Counter](#counter) + + [Counter Add](#counter-add) + * [UpDownCounter](#updowncounter) + + [UpDownCounter Add](#updowncounter-add) + * [Histogram](#histogram) + + [Histogram Record](#histogram-record) + * [Asynchronous Counter](#asynchronous-counter) + * [Asynchronous Counter Observations](#asynchronous-counter-observations) + * [Asynchronous UpDownCounter](#asynchronous-updowncounter) + * [Asynchronous UpDownCounter Observations](#asynchronous-updowncounter-observations) + * [Asynchronous Gauge](#asynchronous-gauge) + * [Asynchronous Gauge Observations](#asynchronous-gauge-observations) + + + +
+ +Users of OpenTelemetry need a way to disable the API from actually +performing any operations. The No-Op OpenTelemetry API implementation +(henceforth referred to as the No-Op) provides users with this +functionally. It implements the OpenTelemetry API so that no telemetry +is produced and computation resources are minimized. + +All language implementations of OpenTelemetry MUST provide a No-Op. + +## MeterProvider + +The No-Op MUST allow the creation of multiple MeterProviders. + +The MeterProviders created by the No-Op needs to hold as small a memory +footprint as possible. Therefore, all MeterProviders created MUST NOT +hold configuration or operational state. + +Since all MeterProviders hold the same empty state, a No-Op MAY +provide the same MeterProvider instances to all creation requests. + +The No-Op is used by OpenTelemetry users to disable OpenTelemetry +computation overhead and eliminate OpenTelemetry related output. For +this reason, the MeterProvider MUST NOT return a non-empty error or log +any message for any operations it performs. + +All operations a MeterProvider provides MUST be safe to be run +concurrently. + +### Meter Creation + +[New Meter instances are always created with a +MeterProvider](./api.md#meterprovider). Therefore, MeterProviders MUST +allow for the creation of Meters. All Meters created MUST be an instance of the +[No-Op Meter](#meter). + +Since all Meters will hold the same empty state, a MeterProvider MAY +return the same Meter instances to all creation requests. + +[The API specifies multiple parameters](./api.md#meterprovider) that +need to be accepted by the creation operation. The MeterProvider MUST +accept these parameters. However, the MeterProvider MUST NOT validate +any argument it receives. + +## Meter + +A Meter is always created by a MeterProvider. The No-Op MUST NOT provide +a way for a user to create a Meter other than by a No-Op MeterProvider. + +The Meters created by the No-Op need to hold as small a memory +footprint as possible. Therefore, all Meters created MUST NOT hold +configuration or operational state. + +The Meter MUST NOT return a non-empty error or log any message for any +operations it performs. + +All operations a Meter provides MUST be safe to be run concurrently. + +### Counter Creation + +The No-Op Meter MUST allow for the creation of a [Counter +instrument](#counter). + +Since all Counters hold the same empty state, a Meter MAY return the +same Counter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### UpDownCounter Creation + +The No-Op Meter MUST allow for the creation of a [UpDownCounter +instrument](#updowncounter). + +Since all UpDownCounters hold the same empty state, a Meter MAY return +the same UpDownCounter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### Histogram Creation + +The No-Op Meter MUST allow for the creation of a [Histogram +instrument](#histogram). + +Since all Histograms hold the same empty state, a Meter MAY return the +same Histogram instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### Asynchronous Counter Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous Counter +instrument](#asynchronous-counter). + +Since all Asynchronous Counters hold the same empty state, a Meter MAY +return the same Asynchronous Counter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +### Asynchronous UpDownCounter Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous +UpDownCounter instrument](#asynchronous-updowncounter). + +Since all Asynchronous UpDownCounters hold the same empty state, a Meter +MAY return the same Asynchronous UpDownCounter instance to all creation +requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +### Asynchronous Gauge Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous Gauge +instrument](#asynchronous-gauge). + +Since all Asynchronous Gauges hold the same empty state, a Meter MAY +return the same Asynchronous UpDownCounter instance to all creation +requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +## Instruments + +Instruments are used to make measurements and report telemetry for a +system. However, the No-Op is used to disable this production of +telemetry. Because of this, all instruments the No-Op provides MUST NOT +hold any configuration or operational state including the aggregation of +telemetry. + +### Counter + +Counters are always created by a Meter, the No-Op MUST NOT provide a way +for a user to create a Counter other than by a No-Op Meter. + +Counters MUST NOT return a non-empty error or log any message for any +operations they perform. + +All operations a Counter provides MUST be safe to be run concurrently. + +#### Counter Add + +The No-Op Counter MUST provide the user an interface to Add that +implements the [API](./api.md#add). It MUST NOT validate or retain any +state about the arguments it receives. + +### UpDownCounter + +UpDownCounters are always created by a Meter, the No-Op MUST NOT provide +a way for a user to create a UpDownCounter other than by a No-Op Meter. + +UpDownCounters MUST NOT return a non-empty error or log any message for +any operations they perform. + +All operations an UpDownCounter provides MUST be safe to be run +concurrently. + +#### UpDownCounter Add + +The No-Op UpDownCounter MUST provide the user an interface to Add that +implements the [API](./api.md#add-1). It MUST NOT validate or retain any +state about the arguments it receives. + +### Histogram + +Histograms are always created by a Meter, the No-Op MUST NOT provide a +way for a user to create a Histogram other than by a No-Op Meter. + +Histograms MUST NOT return a non-empty error or log any message for any +operations they perform. + +All operations a Histogram provides MUST be safe to be run concurrently. + +#### Histogram Record + +The No-Op Histogram MUST provide the user an interface to Record that +implements the [API](./api.md#record). It MUST NOT validate or retain +any state about the arguments it receives. + +### Asynchronous Counter + +Asynchronous Counters are always created by a Meter, the No-Op MUST NOT +provide a way for a user to create a Asynchronous Counter other than by +a No-Op Meter. + +Asynchronous Counters MUST NOT return a non-empty error or log any +message for any operations they perform. + +All operations an Asynchronous Counter provides MUST be safe to be run +concurrently. + +### Asynchronous Counter Observations + +The No-Op Asynchronous Counter MUST NOT validate or retain any state +about observations made for the instrument. + +### Asynchronous UpDownCounter + +Asynchronous UpDownCounters are always created by a Meter, the No-Op +MUST NOT provide a way for a user to create a Asynchronous UpDownCounter +other than by a No-Op Meter. + +Asynchronous UpDownCounters MUST NOT return a non-empty error or log any +message for any operations they perform. + +All operations an Asynchronous UpDownCounter provides MUST be safe to be +run concurrently. + +### Asynchronous UpDownCounter Observations + +The No-Op Asynchronous UpDownCounter MUST NOT validate or retain any +state about observations made for the instrument. + +### Asynchronous Gauge + +Asynchronous Gauges are always created by a Meter, the No-Op MUST NOT +provide a way for a user to create a Asynchronous Gauge other than by a +No-Op Meter. + +Asynchronous Gauges MUST NOT return a non-empty error or log any message +for any operations they perform. + +All operations an Asynchronous Gauge provides MUST be safe to be run +concurrently. + +### Asynchronous Gauge Observations + +The No-Op Asynchronous Gauge MUST NOT validate or retain any state about +observations made for the instrument. diff --git a/specification/metrics/sdk.md b/specification/metrics/sdk.md index f9e358e1542..092c17e1969 100644 --- a/specification/metrics/sdk.md +++ b/specification/metrics/sdk.md @@ -30,7 +30,11 @@ linkTitle: SDK * [Use the maximum scale for single measurements](#use-the-maximum-scale-for-single-measurements) * [Maintain the ideal scale](#maintain-the-ideal-scale) * [Observations inside asynchronous callbacks](#observations-inside-asynchronous-callbacks) - * [Resolving duplicate instrument registration conflicts](#resolving-duplicate-instrument-registration-conflicts) +- [Meter](#meter) + * [Duplicate instrument registration](#duplicate-instrument-registration) + * [Instrument name](#instrument-name) + * [Instrument unit](#instrument-unit) + * [Instrument description](#instrument-description) - [Attribute limits](#attribute-limits) - [Exemplar](#exemplar) * [ExemplarFilter](#exemplarfilter) @@ -65,6 +69,13 @@ linkTitle: SDK +Users of OpenTelemetry need a way for instrumentation interactions with the +OpenTelemetry API to actually produce telemetry. The OpenTelemetry SDK +(henceforth referred to as the SDK) is an implementation of the OpenTelemetry +API that provides users with this functionally. + +All language implementations of OpenTelemetry MUST provide an SDK. + ## MeterProvider **Status**: [Stable](../document-status.md) @@ -88,6 +99,15 @@ the `MeterProvider` MUST be used to create an [`InstrumentationScope`](../glossary.md#instrumentation-scope) instance which is stored on the created `Meter`. +In the case where an invalid `name` (null or empty string) is specified, a +working Meter MUST be returned as a fallback rather than returning null or +throwing an exception, its `name` SHOULD keep the original invalid value, and a +message reporting that the specified value is invalid SHOULD be logged. + +When a Schema URL is passed as an argument when creating a `Meter` the emitted +telemetry for that `Meter` MUST be associated with the Schema URL, provided +that the emitted data format is capable of representing such association. + Configuration (i.e., [MetricExporters](#metricexporter), [MetricReaders](#metricreader) and [Views](#view)) MUST be managed solely by the `MeterProvider` and the SDK MUST provide a way to configure all options that are @@ -560,33 +580,67 @@ execution. The implementation MUST complete the execution of all callbacks for a given instrument before starting a subsequent round of collection. -### Resolving duplicate instrument registration conflicts +## Meter + +Distinct meters MUST be treated as separate namespaces for the purposes of detecting +[duplicate instrument registrations](#duplicate-instrument-registration). + +### Duplicate instrument registration + +When more than one Instrument of the same `name` is created for identical +Meters, denoted _duplicate instrument registration_, the Meter MUST create a +valid Instrument in every case. Here, "valid" means an instrument that is +functional and can be expected to export data, despite potentially creating a +[semantic error in the data +model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations). -As [stated in the API -specification](api.md#instrument-type-conflict-detection), -implementations are REQUIRED to create valid instruments in case of -duplicate instrument registration, and the [data model includes -RECOMMENDATIONS on how to treat the consequent duplicate -conflicting](data-model.md#opentelemetry-protocol-data-model-producer-recommendations) -`Metric` definitions. +It is unspecified whether or under which conditions the same or +different Instrument instance will be returned as a result of +duplicate instrument registration. The term _identical_ applied to +Instruments describes instances where all [identifying +fields](./api.md#instrument) are equal. The term _distinct_ applied +to Instruments describes instances where at least one field value is +different. -The implementation MUST aggregate data from identical Instruments -together in its export pipeline. +Based on [the recommendations from the data +model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations), +the SDK MUST aggregate data from identical Instruments together in its export +pipeline. -The implementation SHOULD assist the user in managing conflicts by -reporting each duplicate-conflicting instrument registration that was -not corrected by a View as follows. When a potential conflict arises -between two non-identical `Metric` instances having the same `name`: +When a duplicate instrument registration occurs, and it is not corrected with a +View, a warning SHOULD be emitted. The emitted warning SHOULD include +information for the user on how to resolve the conflict, if possible. 1. If the potential conflict involves multiple `description` properties, setting the `description` through a configured View SHOULD avoid the warning. 2. If the potential conflict involves instruments that can be distinguished by a supported View selector (e.g., instrument type) - a View recipe SHOULD be printed advising the user how to avoid the - warning by renaming one of the conflicting instruments. -3. Otherwise (e.g., use of multiple units), the implementation SHOULD - pass through the data by reporting both `Metric` objects. + a renaming View recipe SHOULD be included in the warning. +3. Otherwise (e.g., use of multiple units), the SDK SHOULD pass through the + data by reporting both `Metric` objects and emit a generic warning + describing the duplicate instrument registration. + +### Instrument name + +When a Meter creates an instrument, it SHOULD validate the instrument name +conforms to the [instrument name syntax](./api.md#instrument-name-syntax) + +If the instrument name does not conform to this syntax, the Meter SHOULD emit +an error notifying the user about the invalid name. It is left unspecified if a +valid instrument is also returned. + +### Instrument unit + +When a Meter creates an instrument, it SHOULD NOT validate the instrument unit. +If a unit is not provided or the unit is null, the Meter MUST treat it the same +as an empty unit string. + +### Instrument description + +When a Meter creates an instrument, it SHOULD NOT validate the instrument +description. If a description is not provided or the description is null, the +Meter MUST treat it the same as an empty description string. ## Attribute limits diff --git a/specification/metrics/semantic_conventions/http-metrics.md b/specification/metrics/semantic_conventions/http-metrics.md index 3a4244f80cd..be603a309fb 100644 --- a/specification/metrics/semantic_conventions/http-metrics.md +++ b/specification/metrics/semantic_conventions/http-metrics.md @@ -12,61 +12,354 @@ operations. By adding HTTP attributes to metric events it allows for finely tune **Disclaimer:** These are initial HTTP metric instruments and attributes but more may be added in the future. -## Metric Instruments +## HTTP Server -The following metric instruments MUST be used to describe HTTP operations. They MUST be of the specified -type and units. +### Metric: `http.server.duration` -### HTTP Server +This metric is required. -Below is a table of HTTP server metric instruments. + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.server.duration` | Histogram | `ms` | Measures the duration of inbound HTTP requests. | + -| Name | Instrument Type ([*](README.md#instrument-types)) | Unit | Unit ([UCUM](README.md#instrument-units)) | Description | -|-------------------------------|---------------------------------------------------|--------------|-------------------------------------------|------------------------------------------------------------------------------| -| `http.server.duration` | Histogram | milliseconds | `ms` | measures the duration inbound HTTP requests | -| `http.server.request.size` | Histogram | bytes | `By` | measures the size of HTTP request messages (compressed) | -| `http.server.response.size` | Histogram | bytes | `By` | measures the size of HTTP response messages (compressed) | -| `http.server.active_requests` | UpDownCounter | requests | `{requests}` | measures the number of concurrent HTTP requests that are currently in-flight | + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | +| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| `http.flavor` | string | Kind of HTTP protocol used. [2] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.host.name`](../../trace/semantic_conventions/span-general.md) | string | Name of the local HTTP server that received the request. [3] | `localhost` | Required | +| [`net.host.port`](../../trace/semantic_conventions/span-general.md) | int | Port of the local HTTP server that received the request. [4] | `8080` | Conditionally Required: [5] | -### HTTP Client +**[1]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/specification/trace/semantic_conventions/http.md#http-server-definitions) if there is one. -Below is a table of HTTP client metric instruments. +**[2]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. -| Name | Instrument Type ([*](README.md#instrument-types)) | Unit | Unit ([UCUM](README.md#instrument-units)) | Description | -|-----------------------------|---------------------------------------------------|--------------|-------------------------------------------|----------------------------------------------------------| -| `http.client.duration` | Histogram | milliseconds | `ms` | measures the duration outbound HTTP requests | -| `http.client.request.size` | Histogram | bytes | `By` | measures the size of HTTP request messages (compressed) | -| `http.client.response.size` | Histogram | bytes | `By` | measures the size of HTTP response messages (compressed) | +**[3]:** Determined by using the first of the following that applies -## Attributes +- The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Host identifier of the `Host` header -Below is a table of the attributes that SHOULD be included on `duration` and `size` metric events -and whether they should be on server, client, or both types of HTTP metric events: +SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -| Name | Type | Requirement Level | Notes and examples | -|----------------------|---------------------|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| -| `http.method` | `client` & `server` | Required | The HTTP request method. E.g. `"GET"` | -| `http.scheme` | `server` | Required | The URI scheme identifying the used protocol in lowercase: `"http"` or `"https"` | -| `http.route` | `server` | Conditionally Required: If and only if it's available | The matched route (path template in the format used by the respective server framework). See note below [1]. E.g. `"/path/{id}/?q={}"`. | -| `http.status_code` | `client` & `server` | Conditionally Required: if and only if one was received/sent. | [HTTP response status code][]. E.g. `200` (int) | -| `http.flavor` | `client` & `server` | Recommended | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. | -| `net.peer.name` | `client` | Required | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | -| `net.peer.port` | `client` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | -| `net.sock.peer.addr` | `client` | Recommended | See [general network connection attributes](../../trace/semantic_conventions/span-general.md#general-network-connection-attributes) | -| `net.host.name` | `server` | Required | Host of the local HTTP server that received the request. | -| `net.host.port` | `server` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port of the local HTTP server that received the request. | +**[4]:** Determined by using the first of the following that applies -**[1]:** 'http.route' MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +- Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. +- Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Port identifier of the `Host` header -The following attributes SHOULD be included in the `http.server.active_requests` observation: +**[5]:** If not default (`80` for `http` scheme, `443` for `https`). -| Name | Requirement Level | Notes and examples | -|--------------------|-------------------|----------------------------------------------------------------------------------| -| `http.method` | Required | The HTTP request method. E.g. `"GET"` | -| `http.scheme` | Required | The URI scheme identifying the used protocol in lowercase: `"http"` or `"https"` | -| `http.flavor` | Recommended | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"` | -| `net.host.name` | Required | Host component of the ["origin"](https://www.rfc-editor.org/rfc/rfc9110.html#section-3.6) server HTTP request is sent to. | +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. -[HTTP host header]: https://www.rfc-editor.org/rfc/rfc9110.html#name-host-and-authority -[HTTP response status code]: https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes -[HTTP reason phrase]: https://www.rfc-editor.org/rfc/rfc9110.html#section-15.1 +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + + +### Metric: `http.server.active_requests` + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.server.active_requests` | UpDownCounter | `{requests}` | Measures the number of concurrent HTTP requests that are currently in-flight. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.host.name`](../../trace/semantic_conventions/span-general.md) | string | Name of the local HTTP server that received the request. [1] | `localhost` | Required | +| [`net.host.port`](../../trace/semantic_conventions/span-general.md) | int | Port of the local HTTP server that received the request. [2] | `8080` | Conditionally Required: [3] | + +**[1]:** Determined by using the first of the following that applies + +- The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Host identifier of the `Host` header + +SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + +**[2]:** Determined by using the first of the following that applies + +- Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. +- Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Port identifier of the `Host` header + +**[3]:** If not default (`80` for `http` scheme, `443` for `https`). + + +### Metric: `http.server.request.size` + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.server.request.size` | Histogram | `By` | Measures the size of HTTP request messages (compressed). | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | +| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| `http.flavor` | string | Kind of HTTP protocol used. [2] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.host.name`](../../trace/semantic_conventions/span-general.md) | string | Name of the local HTTP server that received the request. [3] | `localhost` | Required | +| [`net.host.port`](../../trace/semantic_conventions/span-general.md) | int | Port of the local HTTP server that received the request. [4] | `8080` | Conditionally Required: [5] | + +**[1]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/specification/trace/semantic_conventions/http.md#http-server-definitions) if there is one. + +**[2]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +**[3]:** Determined by using the first of the following that applies + +- The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Host identifier of the `Host` header + +SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + +**[4]:** Determined by using the first of the following that applies + +- Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. +- Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Port identifier of the `Host` header + +**[5]:** If not default (`80` for `http` scheme, `443` for `https`). + +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + + +### Metric: `http.server.response.size` + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.server.response.size` | Histogram | `By` | Measures the size of HTTP response messages (compressed). | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | +| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| `http.flavor` | string | Kind of HTTP protocol used. [2] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.host.name`](../../trace/semantic_conventions/span-general.md) | string | Name of the local HTTP server that received the request. [3] | `localhost` | Required | +| [`net.host.port`](../../trace/semantic_conventions/span-general.md) | int | Port of the local HTTP server that received the request. [4] | `8080` | Conditionally Required: [5] | + +**[1]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/specification/trace/semantic_conventions/http.md#http-server-definitions) if there is one. + +**[2]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +**[3]:** Determined by using the first of the following that applies + +- The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only + include host identifier. +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Host identifier of the `Host` header + +SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + +**[4]:** Determined by using the first of the following that applies + +- Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. +- Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form. +- Port identifier of the `Host` header + +**[5]:** If not default (`80` for `http` scheme, `443` for `https`). + +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + + +## HTTP Client + +### Metric: `http.client.duration` + +This metric is required. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.duration` | Histogram | `ms` | Measures the duration of outbound HTTP requests. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.flavor` | string | Kind of HTTP protocol used. [1] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.peer.name`](../../trace/semantic_conventions/span-general.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `example.com` | Required | +| [`net.peer.port`](../../trace/semantic_conventions/span-general.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `80`; `8080`; `443` | Conditionally Required: [4] | +| [`net.sock.peer.addr`](../../trace/semantic_conventions/span-general.md) | string | Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). | `127.0.0.1`; `/tmp/mysql.sock` | Recommended | + +**[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +**[2]:** Determined by using the first of the following that applies + +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form +- Host identifier of the `Host` header + +SHOULD NOT be set if capturing it would require an extra DNS lookup. + +**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `net.peer.name` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. + +**[4]:** If not default (`80` for `http` scheme, `443` for `https`). + +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + + +### Metric: `http.client.request.size` + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.request.size` | Histogram | `By` | Measures the size of HTTP request messages (compressed). | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.flavor` | string | Kind of HTTP protocol used. [1] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.peer.name`](../../trace/semantic_conventions/span-general.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `example.com` | Required | +| [`net.peer.port`](../../trace/semantic_conventions/span-general.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `80`; `8080`; `443` | Conditionally Required: [4] | +| [`net.sock.peer.addr`](../../trace/semantic_conventions/span-general.md) | string | Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). | `127.0.0.1`; `/tmp/mysql.sock` | Recommended | + +**[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +**[2]:** Determined by using the first of the following that applies + +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form +- Host identifier of the `Host` header + +SHOULD NOT be set if capturing it would require an extra DNS lookup. + +**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `net.peer.name` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. + +**[4]:** If not default (`80` for `http` scheme, `443` for `https`). + +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + + +### Metric: `http.client.response.size` + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.response.size` | Histogram | `By` | Measures the size of HTTP response messages (compressed). | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.flavor` | string | Kind of HTTP protocol used. [1] | `1.0` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | +| `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`net.peer.name`](../../trace/semantic_conventions/span-general.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `example.com` | Required | +| [`net.peer.port`](../../trace/semantic_conventions/span-general.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `80`; `8080`; `443` | Conditionally Required: [4] | +| [`net.sock.peer.addr`](../../trace/semantic_conventions/span-general.md) | string | Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). | `127.0.0.1`; `/tmp/mysql.sock` | Recommended | + +**[1]:** If `net.transport` is not specified, it can be assumed to be `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. + +**[2]:** Determined by using the first of the following that applies + +- Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form +- Host identifier of the `Host` header + +SHOULD NOT be set if capturing it would require an extra DNS lookup. + +**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `net.peer.name` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. + +**[4]:** If not default (`80` for `http` scheme, `443` for `https`). + +`http.flavor` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `1.0` | HTTP/1.0 | +| `1.1` | HTTP/1.1 | +| `2.0` | HTTP/2 | +| `3.0` | HTTP/3 | +| `SPDY` | SPDY protocol. | +| `QUIC` | QUIC protocol. | + diff --git a/specification/protocol/file-exporter.md b/specification/protocol/file-exporter.md index b300090d71b..6342967b0e0 100644 --- a/specification/protocol/file-exporter.md +++ b/specification/protocol/file-exporter.md @@ -53,26 +53,26 @@ Files must contain exactly one type of data: traces, metrics, or logs. This is an example showing traces: ```json lines -{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibrarySpans":[{"instrumentationLibrary":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000123","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000123","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":"2"}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":4},{"traceId":"","spanId":"","droppedAttributesCount":1}],"droppedLinksCount":3,"status":{}}]}]}]} -{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibrarySpans":[{"instrumentationLibrary":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000424","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000424","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":"2"}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000000343","endTimeUnixNano":"1581452773000001089","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":3},{"traceId":"","spanId":"","droppedAttributesCount":4}],"droppedLinksCount":2,"status":{}}]}]}]} -{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibrarySpans":[{"instrumentationLibrary":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000826","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000826","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":"2"}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000200521","endTimeUnixNano":"1581452773000004789","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":5},{"traceId":"","spanId":"","droppedAttributesCount":2}],"droppedLinksCount":3,"status":{}}]}]}]} -{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibrarySpans":[{"instrumentationLibrary":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000010925","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000010925","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":"2"}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000011821","endTimeUnixNano":"1581452772000012924","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":2},{"traceId":"","spanId":"","droppedAttributesCount":2}],"droppedLinksCount":5,"status":{}}]}]}]} +{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeSpans":[{"scope":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000123","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000123","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":2}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":4},{"traceId":"","spanId":"","droppedAttributesCount":1}],"droppedLinksCount":3,"status":{}}]}]}]} +{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeSpans":[{"scope":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000424","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000424","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":2}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000000343","endTimeUnixNano":"1581452773000001089","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":3},{"traceId":"","spanId":"","droppedAttributesCount":4}],"droppedLinksCount":2,"status":{}}]}]}]} +{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeSpans":[{"scope":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000000826","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000000826","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":2}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000200521","endTimeUnixNano":"1581452773000004789","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":5},{"traceId":"","spanId":"","droppedAttributesCount":2}],"droppedLinksCount":3,"status":{}}]}]}]} +{"resourceSpans":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeSpans":[{"scope":{},"spans":[{"traceId":"","spanId":"","parentSpanId":"","name":"operationA","startTimeUnixNano":"1581452772000000321","endTimeUnixNano":"1581452773000000789","droppedAttributesCount":1,"events":[{"timeUnixNano":"1581452773000010925","name":"event-with-attr","attributes":[{"key":"span-event-attr","value":{"stringValue":"span-event-attr-val"}}],"droppedAttributesCount":2},{"timeUnixNano":"1581452773000010925","name":"event","droppedAttributesCount":2}],"droppedEventsCount":1,"status":{"message":"status-cancelled","code":2}},{"traceId":"","spanId":"","parentSpanId":"","name":"operationB","startTimeUnixNano":"1581452772000011821","endTimeUnixNano":"1581452772000012924","links":[{"traceId":"","spanId":"","attributes":[{"key":"span-link-attr","value":{"stringValue":"span-link-attr-val"}}],"droppedAttributesCount":2},{"traceId":"","spanId":"","droppedAttributesCount":2}],"droppedLinksCount":5,"status":{}}]}]}]} ``` This is an example showing metrics: ```json lines -{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryMetrics":[{"instrumentationLibrary":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000000789","timeUnixNano":"1581452773000000789","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}}]}]}]} -{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryMetrics":[{"instrumentationLibrary":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"120"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}}]}]}]} -{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryMetrics":[{"instrumentationLibrary":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"121"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}}]}]}]} -{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryMetrics":[{"instrumentationLibrary":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000007891","timeUnixNano":"1581452773000007891","asInt":"125"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000007891","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000007891","timeUnixNano":"1581452773000007891","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000007891","asInt":"456"}],"aggregationTemporality":"2","isMonotonic":true}}]}]}]} +{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeMetrics":[{"scope":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000000789","timeUnixNano":"1581452773000000789","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}}]}]}]} +{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeMetrics":[{"scope":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"120"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000001459","timeUnixNano":"1581452773000001459","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}}]}]}]} +{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeMetrics":[{"scope":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"121"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000002346","timeUnixNano":"1581452773000002346","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000000789","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}}]}]}]} +{"resourceMetrics":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeMetrics":[{"scope":{},"metrics":[{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000007891","timeUnixNano":"1581452773000007891","asInt":"125"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000007891","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}},{"name":"counter-int","unit":"1","sum":{"dataPoints":[{"attributes":[{"key":"label-1","value":{"stringValue":"label-value-1"}}],"startTimeUnixNano":"1581452773000007891","timeUnixNano":"1581452773000007891","asInt":"123"},{"attributes":[{"key":"label-2","value":{"stringValue":"label-value-2"}}],"startTimeUnixNano":"1581452772000000321","timeUnixNano":"1581452773000007891","asInt":"456"}],"aggregationTemporality":2,"isMonotonic":true}}]}]}]} ``` This is an example showing logs: ```json lines -{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryLogs":[{"instrumentationLibrary":{},"logs":[{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} -{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryLogs":[{"instrumentationLibrary":{},"logs":[{"timeUnixNano":"1581452773000001233","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} -{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryLogs":[{"instrumentationLibrary":{},"logs":[{"timeUnixNano":"1581452773000005443","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} -{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"instrumentationLibraryLogs":[{"instrumentationLibrary":{},"logs":[{"timeUnixNano":"1581452773000009875","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} +{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeLogs":[{"scope":{},"logRecords":[{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} +{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeLogs":[{"scope":{},"logRecords":[{"timeUnixNano":"1581452773000001233","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} +{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeLogs":[{"scope":{},"logRecords":[{"timeUnixNano":"1581452773000005443","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} +{"resourceLogs":[{"resource":{"attributes":[{"key":"resource-attr","value":{"stringValue":"resource-attr-val-1"}}]},"scopeLogs":[{"scope":{},"logRecords":[{"timeUnixNano":"1581452773000009875","severityNumber":9,"severityText":"Info","name":"logA","body":{"stringValue":"This is a log message"},"attributes":[{"key":"app","value":{"stringValue":"server"}},{"key":"instance_num","value":{"intValue":"1"}}],"droppedAttributesCount":1,"traceId":"08040201000000000000000000000000","spanId":"0102040800000000"},{"timeUnixNano":"1581452773000000789","severityNumber":9,"severityText":"Info","name":"logB","body":{"stringValue":"something happened"},"attributes":[{"key":"customer","value":{"stringValue":"acme"}},{"key":"env","value":{"stringValue":"dev"}}],"droppedAttributesCount":1,"traceId":"","spanId":""}]}]}]} ``` diff --git a/specification/protocol/otlp.md b/specification/protocol/otlp.md index 4d222c4c16b..5eb25f9f8c2 100644 --- a/specification/protocol/otlp.md +++ b/specification/protocol/otlp.md @@ -395,7 +395,7 @@ response headers when sending binary Protobuf encoded payload. #### JSON Protobuf Encoding -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md) JSON Protobuf encoded payloads use proto3 standard defined [JSON Mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) diff --git a/specification/trace/sdk.md b/specification/trace/sdk.md index 458491015bc..2e5b0dd46dc 100644 --- a/specification/trace/sdk.md +++ b/specification/trace/sdk.md @@ -361,18 +361,22 @@ Optional parameters: #### JaegerRemoteSampler -[Jaeger remote sampler](https://www.jaegertracing.io/docs/1.29/sampling/#collector-sampling-configuration) allows remotely controlling the sampling configuration for the SDKs. The sampling is typically configured at the collector and the SDKs actively poll for changes. The sampler uses `TraceIdRatioBased` or rate-limited sampler under the hood. These samplers can be configured per whole service (a.k.a default), or per span name in a given service (a.k.a per operation). +[Jaeger remote sampler][jaeger-remote-sampling] allows remotely controlling the sampling configuration for the SDKs. The sampling configuration is periodically loaded from the backend (see [Remote Sampling API][jaeger-remote-sampling-api]), where it can be managed by operators via configuration files or even automatically calculated (see [Adaptive Sampling][jaeger-adaptive-sampling]). The sampling configuration retrieved by the remote sampler can instruct it to use either a single sampling method for the whole service (e.g., `TraceIdRatioBased`), or different methods for different endpoints (span names), for example, sample `/product` endpoint at 10%, `/admin` endpoint at 100%, and never sample `/metrics` endpoint. The full Protobuf definition can be found at [jaegertracing/jaeger-idl/api_v2/sampling.proto](https://github.com/jaegertracing/jaeger-idl/blob/main/proto/api_v2/sampling.proto). ##### Configuration -Following configuration properties should be available when creating the sampler: +The following configuration properties should be available when creating the sampler: -* endpoint - collector address with running service with sampling manager +* endpoint - address of a service that implements the [Remote Sampling API][jaeger-remote-sampling-api], such as Jaeger Collector or OpenTelemetry Collector. * polling interval - polling interval for getting configuration from remote * initial sampler - initial sampler that is used before the first configuration is fetched +[jaeger-remote-sampling]: https://www.jaegertracing.io/docs/1.41/sampling/#remote-sampling +[jaeger-remote-sampling-api]: https://www.jaegertracing.io/docs/1.41/apis/#remote-sampling-configuration-stable +[jaeger-adaptive-sampling]: https://www.jaegertracing.io/docs/1.41/sampling/#adaptive-sampling + ## Span Limits Span attributes MUST adhere to the [common rules of attribute limits](../common/README.md#attribute-limits). @@ -412,9 +416,10 @@ public final class SpanLimits { * `AttributePerEventCountLimit` (Default=128) - Maximum allowed attribute per span event count; * `AttributePerLinkCountLimit` (Default=128) - Maximum allowed attribute per span link count; -There SHOULD be a log emitted to indicate to the user that an attribute, event, -or link was discarded due to such a limit. To prevent excessive logging, the log -should not be emitted once per span, or per discarded attribute, event, or links. +There SHOULD be a message printed in the SDK's log to indicate to the user +that an attribute was discarded due to such a limit. +To prevent excessive logging, the message MUST be printed at most once per +span (i.e., not per discarded attribute, event, or link). ## Id Generators diff --git a/specification/trace/sdk_exporters/zipkin.md b/specification/trace/sdk_exporters/zipkin.md index b398c1efa31..f88688732fb 100644 --- a/specification/trace/sdk_exporters/zipkin.md +++ b/specification/trace/sdk_exporters/zipkin.md @@ -95,16 +95,16 @@ always available. The following table lists the possible attributes for |---|---|---| |1|peer.service|[OpenTelemetry adopted attribute for remote service.](../semantic_conventions/span-general.md#general-remote-service-attributes)| |2|net.peer.name|[OpenTelemetry adopted attribute for remote hostname, or similar.](../semantic_conventions/span-general.md#general-network-connection-attributes)| -|3|net.peer.ip & net.peer.port|[OpenTelemetry adopted attribute for remote address of the peer.](../semantic_conventions/span-general.md#general-network-connection-attributes)| -|4|peer.hostname|Remote hostname defined in OpenTracing specification.| -|5|peer.address|Remote address defined in OpenTracing specification.| -|6|http.host|Commonly used HTTP host header attribute for Http Spans.| +|3|net.sock.peer.name|[OpenTelemetry adopted attribute for remote socket hostname of the peer.](../semantic_conventions/span-general.md#general-network-connection-attributes)| +|4|net.sock.peer.addr & net.sock.peer.port|[OpenTelemetry adopted attribute for remote socket address of the peer.](../semantic_conventions/span-general.md#general-network-connection-attributes)| +|5|peer.hostname|Remote hostname defined in OpenTracing specification.| +|6|peer.address|Remote address defined in OpenTracing specification.| |7|db.name|Commonly used database name attribute for DB Spans.| * Ranking should control the selection order. For example, `net.peer.name` (Rank - 2) should be selected before `http.host` (Rank 6). -* `net.peer.ip` can be used by itself as `remoteEndpoint` but should be combined - with `net.peer.port` if it is also present. + 2) should be selected before `peer.address` (Rank 6). +* `net.sock.peer.name` and `net.sock.peer.addr` can be used by themselves as `remoteEndpoint` but should be combined + with `net.sock.peer.port` if it is also present. #### Zipkin -> OTLP diff --git a/specification/trace/semantic_conventions/http.md b/specification/trace/semantic_conventions/http.md index eaa2e5ec40f..8bfc9bbfb1d 100644 --- a/specification/trace/semantic_conventions/http.md +++ b/specification/trace/semantic_conventions/http.md @@ -30,16 +30,14 @@ and various HTTP versions like 1.1, 2 and SPDY. ## Name HTTP spans MUST follow the overall [guidelines for span names](../api.md#span). -Many REST APIs encode parameters into URI path, e.g. `/api/users/123` where `123` -is a user id, which creates high cardinality value space not suitable for span -names. In case of HTTP servers, these endpoints are often mapped by the server -frameworks to more concise *HTTP routes*, e.g. `/api/users/{user_id}`, which are -recommended as the low cardinality span names. However, the same approach usually -does not work for HTTP client spans, especially when instrumentation is provided -by a lower-level middleware that is not aware of the specifics of how the URIs -are formed. Therefore, HTTP client spans SHOULD be using conservative, low -cardinality names formed from the available parameters of an HTTP request, -such as `"HTTP {METHOD_NAME}"`. Instrumentation MUST NOT default to using URI +HTTP server span names SHOULD be `{http.method} {http.route}` if there is a +(low-cardinality) `http.route` available. +HTTP server span names SHOULD be `{http.method}` if there is no (low-cardinality) +`http.route` available. +HTTP client spans have no `http.route` attribute since client-side instrumentation +is not generally aware of the "route", and therefore HTTP client spans SHOULD use +`{http.method}`. +Instrumentation MUST NOT default to using URI path as span name, but MAY provide hooks to allow custom logic to override the default span name. @@ -64,15 +62,15 @@ The common attributes listed in this section apply to both HTTP clients and serv the specific attributes listed in the [HTTP client](#http-client) and [HTTP server](#http-server) sections below. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | | `http.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | `http.flavor` | string | Kind of HTTP protocol used. [1] | `1.0` | Recommended | | `http.user_agent` | string | Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended | | `http.request_content_length` | int | The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. | `3495` | Recommended | | `http.response_content_length` | int | The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. | `3495` | Recommended | +| `http.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Required | | [`net.sock.family`](span-general.md) | string | Protocol [address family](https://man7.org/linux/man-pages/man7/address_families.7.html) which is used for communication. | `inet`; `inet6` | Conditionally Required: [2] | | [`net.sock.peer.addr`](span-general.md) | string | Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, [etc](https://man7.org/linux/man-pages/man7/address_families.7.html). | `127.0.0.1`; `/tmp/mysql.sock` | Recommended | | [`net.sock.peer.name`](span-general.md) | string | Remote socket peer name. | `proxy.example.com` | Recommended: [3] | @@ -100,6 +98,14 @@ Following attributes MUST be provided **at span creation time** (when provided a | `3.0` | HTTP/3 | | `SPDY` | SPDY protocol. | | `QUIC` | QUIC protocol. | + +`net.sock.family` has the following list of well-known values. If one of them applies, then the respective value MUST be used, otherwise a custom value MAY be used. + +| Value | Description | +|---|---| +| `inet` | IPv4 address | +| `inet6` | IPv6 address | +| `unix` | Unix domain socket path | It is recommended to also use the general [socket-level attributes][] - `net.sock.peer.addr` when available, `net.sock.peer.name` and `net.sock.peer.port` when don't match `net.peer.name` and `net.peer.port` (if [intermediary](https://www.rfc-editor.org/rfc/rfc9110.html#section-3.7) is detected). @@ -130,7 +136,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. If set, `http.url` must be the originally requested URL, before any HTTP-redirects that may happen when executing the request. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `http.url` | 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` | Required | @@ -202,8 +208,8 @@ Within a single virtual host, some servers support the concepts of an **HTTP app in a deployment of a Python application to Apache, the application would be the [PEP 3333][] conformant callable that is configured using the [`WSGIScriptAlias` directive][modwsgisetup] of `mod_wsgi`). -An application can be "mounted" under some **application root** -(also know as *[context root][]* *[context prefix][]*, or *[document base][]*) +An application can be "mounted" under an **application root** +(also known as a *[context root][]*, *[context prefix][]*, or *[document base][]*) which is a fixed path prefix of the URL that determines to which application a request is routed (e.g., the server could be configured to route all requests that go to an URL path starting with `/webshop/` at a particular virtual host @@ -232,23 +238,23 @@ This span type represents an inbound HTTP request. For an HTTP server span, `SpanKind` MUST be `Server`. Given an inbound request for a route (e.g. `"/users/:userID?"`) the `name` attribute of the span SHOULD be set to this route. -If the route does not include the application root, it SHOULD be prepended to the span name. If the route cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | -| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds` | Required | | `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| `http.target` | string | The full request target as passed in a HTTP request line or equivalent. | `/path/12314/?q=ddds` | Required | | `http.client_ip` | string | The IP address of the original client behind all proxies, if known (e.g. from [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)). [2] | `83.164.160.102` | Recommended | +| `http.scheme` | string | The URI scheme identifying the used protocol. | `http`; `https` | Required | | [`net.host.name`](span-general.md) | string | Name of the local HTTP server that received the request. [3] | `localhost` | Required | | [`net.host.port`](span-general.md) | int | Port of the local HTTP server that received the request. [4] | `8080` | Conditionally Required: [5] | | [`net.sock.host.addr`](span-general.md) | string | Local socket address. Useful in case of a multi-IP host. | `192.168.0.1` | Optional | | [`net.sock.host.port`](span-general.md) | int | Local socket port number. | `35555` | Recommended: [6] | -**[1]:** 'http.route' MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +**[1]:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/specification/trace/semantic_conventions/http.md#http-server-definitions) if there is one. **[2]:** This is not necessarily the same as `net.sock.peer.addr`, which would identify the network-level peer, which may be a proxy. @@ -264,7 +270,7 @@ the closest proxy. **[3]:** Determined by using the first of the following that applies -- The [primary server name](#http-server-definitions) of the matched virtual host. MUST only +- The [primary server name](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) if it's sent in absolute-form. @@ -274,7 +280,7 @@ SHOULD NOT be set if only IP address is available and capturing name would requi **[4]:** Determined by using the first of the following that applies -- Port identifier of the [primary server host](#http-server-definitions) of the matched virtual host. +- Port identifier of the [primary server host](/specification/trace/semantic_conventions/http.md#http-server-definitions) of the matched virtual host. - Port identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) if it's sent in absolute-form. - Port identifier of the `Host` header @@ -285,8 +291,8 @@ SHOULD NOT be set if only IP address is available and capturing name would requi Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: -* `http.scheme` * `http.target` +* `http.scheme` * [`net.host.name`](span-general.md) * [`net.host.port`](span-general.md) @@ -301,7 +307,7 @@ Note that in some cases host and port identifiers in the `Host` header might be As an example, if a browser request for `https://example.com:8080/webshop/articles/4?s=1` is invoked from a host with IP 192.0.2.4, we may have the following Span on the client side: -Span name: `HTTP GET` +Span name: `GET` | Attribute name | Value | | :------------------- | :-------------------------------------------------------| @@ -315,7 +321,7 @@ Span name: `HTTP GET` The corresponding server Span may look like this: -Span name: `/webshop/articles/:article_id`. +Span name: `GET /webshop/articles/:article_id`. | Attribute name | Value | | :------------------- | :---------------------------------------------- | diff --git a/specification/trace/semantic_conventions/instrumentation/aws-lambda.md b/specification/trace/semantic_conventions/instrumentation/aws-lambda.md index ac2726cfebe..cad57ad0eca 100644 --- a/specification/trace/semantic_conventions/instrumentation/aws-lambda.md +++ b/specification/trace/semantic_conventions/instrumentation/aws-lambda.md @@ -14,7 +14,7 @@ use cases. - [All triggers](#all-triggers) - * [Determining the parent of a span](#determining-the-parent-of-a-span) + * [AWS X-Ray Environment Span Link](#aws-x-ray-environment-span-link) - [API Gateway](#api-gateway) - [SQS](#sqs) * [SQS Event](#sqs-event) @@ -61,22 +61,19 @@ and the [cloud resource conventions][cloud]. The following AWS Lambda-specific a [faasres]: ../../../resource/semantic_conventions/faas.md (FaaS resource conventions) [cloud]: ../../../resource/semantic_conventions/cloud.md (Cloud resource conventions) -### Determining the parent of a span +### AWS X-Ray Environment Span Link -The parent of the span MUST be determined by considering both the environment and any headers or attributes -available from the event. - -If the `_X_AMZN_TRACE_ID` environment variable is set, instrumentations SHOULD first try to parse an +If the `_X_AMZN_TRACE_ID` environment variable is set, instrumentation SHOULD try to parse an OpenTelemetry `Context` out of it using the [AWS X-Ray Propagator](../../../context/api-propagators.md). If the -resulting `Context` is [valid](../../api.md#isvalid) and sampled, then this `Context` is the parent of the -function span. We check if it is valid because sometimes the `_X_AMZN_TRACE_ID` environment variable contains -an incomplete trace context which indicates X-Ray isn’t enabled. The environment variable will be set and the +resulting `Context` is [valid](../../api.md#isvalid) then a [Span Link][] SHOULD be added to the new Span's +[start options](../../api.md#specifying-links) with an associated attribute of `source=x-ray-env` to +indicate the source of the linked span. +Instrumentation MUST check if the context is valid before using it because the `_X_AMZN_TRACE_ID` environment variable can +contain an incomplete trace context which indicates X-Ray isn’t enabled. The environment variable will be set and the `Context` will be valid and sampled only if AWS X-Ray has been enabled for the Lambda function. A user can -disable AWS X-Ray for the function if X-Ray propagation is not desired. +disable AWS X-Ray for the function if the X-Ray Span Link is not desired. -Otherwise, when X-Ray propagation fails, the user's configured propagators SHOULD be applied to the HTTP -headers of the request to extract a `Context`. For example, API Gateway proxy requests can be configured to -send HTTP headers to a Lambda function using [a body mapping template](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-override-request-response-parameters.html). +[Span Link]: https://opentelemetry.io/docs/concepts/signals/traces/#span-links ## API Gateway