From fbf46a1302e08ce9afc5175f51443af0ab850031 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 25 Jul 2023 13:47:37 +0200 Subject: [PATCH 001/482] Change company affiliation for Johannes (#207) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d568e1955d..28ddc8967e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/ope - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian - [Joao Grassi](https://github.com/joaopgrassi), Dynatrace -- [Johannes Tax](https://github.com/pyohannes), Microsoft +- [Johannes Tax](https://github.com/pyohannes), Grafana Labs - [Liudmila Molkova](https://github.com/lmolkova), Microsoft - [Sean Marciniak](https://github.com/MovieStoreGuy), Atlassian - [Ted Young](https://github.com/tedsuo), Lightstep From a5509c690ada39e35df18e1c2b85a355970bb15b Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 25 Jul 2023 11:00:55 -0700 Subject: [PATCH 002/482] `.count` metric naming convention only applies to UpDownCounters (#107) --- CHANGELOG.md | 3 +++ docs/general/metrics.md | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 800a0d08a3..e60ef60c1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ release. - Fix the unit of metric.process.runtime.jvm.system.cpu.load_1m to be {run_queue_item} ([#95](https://github.com/open-telemetry/semantic-conventions/pull/95)) +- Update `.count` metric naming convention so that it only applies to UpDownCounters, + and add that `.total` should not be used by either Counters or UpDownCounters + ([#107](https://github.com/open-telemetry/opentelemetry-specification/pull/107)) ## v1.21.0 (2023-07-13) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index f4b03f34f6..3ba128a273 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -12,8 +12,10 @@ aliases: [docs/specs/semconv/general/metrics-general] - [General Guidelines](#general-guidelines) * [Name Reuse Prohibition](#name-reuse-prohibition) * [Units](#units) - * [Pluralization](#pluralization) - + [Use `count` Instead of Pluralization](#use-count-instead-of-pluralization) + * [Naming rules for Counters and UpDownCounters](#naming-rules-for-counters-and-updowncounters) + + [Pluralization](#pluralization) + + [Use `count` Instead of Pluralization for UpDownCounters](#use-count-instead-of-pluralization-for-updowncounters) + + [Do not use `total`](#do-not-use-total) - [General Metric Semantic Conventions](#general-metric-semantic-conventions) * [Instrument Naming](#instrument-naming) * [Instrument Units](#instrument-units) @@ -99,7 +101,9 @@ When building components that interoperate between OpenTelemetry and a system using the OpenMetrics exposition format, use the [OpenMetrics Guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/compatibility/prometheus_and_openmetrics.md). -### Pluralization +### Naming rules for Counters and UpDownCounters + +#### Pluralization Metric names SHOULD NOT be pluralized, unless the value being recorded represents discrete instances of a @@ -114,7 +118,7 @@ should not be pluralized, even if many data points are recorded. * `system.paging.faults`, `system.disk.operations`, and `system.network.packets` should be pluralized, even if only a single data point is recorded. -#### Use `count` Instead of Pluralization +#### Use `count` Instead of Pluralization for UpDownCounters If the value being recorded represents the count of concepts signified by the namespace then the metric should be named `count` (within its namespace). @@ -125,6 +129,14 @@ to the processes then to represent the count of the processes we can have a metr `system.processes.count`. The suffix `count` here indicates that it is the count of `system.processes`. +#### Do not use `total` + +UpDownCounters SHOULD NOT use `_total` because then they will look like +monotonic sums. + +Counters SHOULD NOT append `_total` either because then their meaning will +be confusing in delta backends. + ## General Metric Semantic Conventions **Status**: [Mixed][DocumentStatus] From 73408c933e56671422fcf362759ff8993dda912d Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 27 Jul 2023 09:21:07 -0400 Subject: [PATCH 003/482] [editorial][CI] Ensure markdownlint has proper exit status (#210) Co-authored-by: Josh Suereth --- gulpfile.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index a42fd496e5..b01927ecc0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,8 +4,8 @@ const markdownlint = require("markdownlint"); const yaml = require("js-yaml"); const fs = require("fs"); -let fileCount = 0, - issueCount = 0; +let numFilesProcessed = 0, + numFilesWithIssues = 0; function markdownLintFile(file, encoding, callback) { const config = yaml.load(fs.readFileSync("./.markdownlint.yaml", "utf8")); @@ -33,9 +33,11 @@ function markdownLintFile(file, encoding, callback) { .join("\n"); if (resultString) { console.log(resultString); - issueCount++; + numFilesWithIssues++; + // Don't report an error yet so that other files can be checked: + // callback(new Error('...')); } - fileCount++; + numFilesProcessed++; callback(null, file); }); } @@ -47,11 +49,13 @@ function lintMarkdown() { .src(markdownFiles) .pipe(through2.obj(markdownLintFile)) .on("end", () => { - console.log( - `Processed ${fileCount} file${ - fileCount == 1 ? "" : "s" - }, ${issueCount} had issues.`, - ); + const fileOrFiles = "file" + (numFilesProcessed == 1 ? "" : "s"); + const msg = `Processed ${numFilesProcessed} ${fileOrFiles}, ${numFilesWithIssues} had issues.`; + if (numFilesWithIssues > 0) { + throw new Error(msg); + } else { + console.log(msg); + } }); } From 2ded691f9d35ac142aa2c6da01fc0f5884398365 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 28 Jul 2023 08:26:16 -0400 Subject: [PATCH 004/482] Update contributing documentation for restructuring of repository (#216) Co-authored-by: Johannes Tax Co-authored-by: Armin Ruech --- CONTRIBUTING.md | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc249e0823..5721670ffa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,10 +11,51 @@ requirements and recommendations. Before you can contribute, you will need to sign the [Contributor License Agreement](https://identity.linuxfoundation.org/projects/cncf). -## TODO +## How to Contribute + +When contributing to semantic conventions, it's important to understand a few +key, but non-obvious, aspects: + +- All attributes, metrics, etc. are formally defined in YAML files under + the `model/` directory. +- All descriptions, normative language are defined in the `docs/` + directory. + - We provide tooling to generate Markdown documentation from the formal + YAML definitons. See [Yaml to Markdown](#yaml-to-markdown). + - We use Hugo to render [semantic conventions on our website](https://opentelemetry.io/docs/specs/semconv/). + You will see ` +``` + +When creating new pages, you should provide the `linkTitle` attribute. This is used +to generate the navigation bar on the website, and will be listed relative to the +"parent" document. + +## Automation + +Semantic Conventions provides a set of automated tools for general development. ### Consistency Checks From 23b0d5eaeabab4232375ab7b91c9f27bcc00a145 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 28 Jul 2023 09:29:09 -0400 Subject: [PATCH 005/482] Re-enable the schema check to look at the website. (#217) --- internal/tools/schema_check.sh | 58 +++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index 50c8d5e724..d6f0efa4fc 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -11,19 +11,37 @@ BUILD_TOOL_SCHEMAS_VERSION=0.18.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") -root_dir=$PWD -schemas_dir=$root_dir/schemas - -# Find all version sections in CHANGELOG that start with a number in 1..9 range. -grep -o -e '## v[1-9].*\s' $root_dir/CHANGELOG.md | grep -o '[1-9].*' | while read ver; do - if [[ " ${skip_versions[*]} " == *" $ver "* ]]; then - # Skip this version, it does not need a schema file. - continue +# Verifies remote avilability of a schema file. +# +# If the schema file is available for download, THEN we make sure it is exactly +# what is in the repository. If the file is not available for download, +# we pass this check. This is to allow releases to be checked in, where +# a new version is specified but hasn't propagated to the website yet. +# +# Args: +# 1 - version number +verify_remote_availability() { + local ver="$1" + echo -n "Ensure published schema file https://opentelemetry.io/schemas/$ver matches local copy... " + if curl --fail --no-progress-meter https://opentelemetry.io/schemas/$ver > verify$ver 2>/dev/null; then + diff verify$ver $file && echo "OK, matches" \ + || (echo "Incorrect!" && exit 3) + else + echo "Not found" fi + rm verify$ver +} +# Verifies remote avilability of a schema file in the current repository. +# +# Args: +# 1 - version number +verify_local_availability() { + local ver="$1" + file="$schemas_dir/$ver" echo -n "Ensure schema file $file exists... " - + # Check that the schema for the version exists. if [ -f "$file" ]; then echo "OK, exists." @@ -31,16 +49,20 @@ grep -o -e '## v[1-9].*\s' $root_dir/CHANGELOG.md | grep -o '[1-9].*' | while re echo "FAILED: $file does not exist. The schema file must exist because the version is declared in CHANGELOG.md." exit 3 fi +} + +root_dir=$PWD +schemas_dir=$root_dir/schemas + +# Find all version sections in CHANGELOG that start with a number in 1..9 range. +grep -o -e '## v[1-9].*\s' $root_dir/CHANGELOG.md | grep -o '[1-9].*' | while read ver; do + if [[ " ${skip_versions[*]} " == *" $ver "* ]]; then + # Skip this version, it does not need a schema file. + continue + fi - # Schema file will no be served directly from this repository when linked - # into opentelemetry.io. We disable this for now and need to move the check - # into the website. - # curl --no-progress-meter https://opentelemetry.io/schemas/$ver > verify$ver - # - # diff verify$ver $file && echo "Published schema at https://opentelemetry.io/schemas/$ver is correct" \ - # || (echo "Published schema at https://opentelemetry.io/schemas/$ver is incorrect!" && exit 3) - # - # rm verify$ver + verify_local_availability "$ver" + verify_remote_availability "$ver" done # Now check the content of all schema files in the ../shemas directory. From b01788635499b306b969de4c6dde4a992c850663 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 1 Aug 2023 04:29:43 -0700 Subject: [PATCH 006/482] Add Alexander Wert as an Approver (#220) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 28ddc8967e..73e784ec82 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/open-telemetry/teams/specs-semconv-approvers)): +- [Alexander Wert](https://github.com/AlexanderWert), Elastic - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian - [Joao Grassi](https://github.com/joaopgrassi), Dynatrace @@ -29,8 +30,8 @@ _Find more about the approver role in [community repository](https://github.com/ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs/open-telemetry/teams/specs-semconv-maintainers)): -- [Josh Suereth](https://github.com/jsuereth) - [Armin Ruech](https://github.com/arminru) +- [Josh Suereth](https://github.com/jsuereth) - [Reiley Yang](https://github.com/reyang) _Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)._ From 6c82745744046a1b657f586e8ac2fe22d9ce1609 Mon Sep 17 00:00:00 2001 From: Armin Ruech Date: Tue, 1 Aug 2023 14:08:29 +0200 Subject: [PATCH 007/482] Bump semantic conventions tooling to v0.20.0 (#225) Co-authored-by: Josh Suereth --- .vscode/settings.json | 2 +- Makefile | 2 +- internal/tools/schema_check.sh | 2 +- model/README.md | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c216d9b9ef..89d895f2f4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "MD040": false, }, "yaml.schemas": { - "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.17.0/semantic-conventions/semconv.schema.json": [ + "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.20.0/semantic-conventions/semconv.schema.json": [ "semantic_conventions/**/*.yaml" ] }, diff --git a/Makefile b/Makefile index 4d04b73d8f..0a7bed5ae5 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! -SEMCONVGEN_VERSION=0.19.0 +SEMCONVGEN_VERSION=0.20.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index d6f0efa4fc..179ca4087b 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -6,7 +6,7 @@ set -e -BUILD_TOOL_SCHEMAS_VERSION=0.18.0 +BUILD_TOOL_SCHEMAS_VERSION=0.20.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") diff --git a/model/README.md b/model/README.md index a6c52ba625..b8afe3e506 100644 --- a/model/README.md +++ b/model/README.md @@ -14,12 +14,12 @@ Semantic conventions for the spec MUST adhere to the [attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-requirement-level.md), and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md) conventions. -Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.18.0/semantic-conventions/syntax.md) +Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. A schema file for VS code is configured in the `/.vscode/settings.json` of this repository, enabling auto-completion and additional checks. Refer to -[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.18.0/semantic-conventions/README.md) for what extension you need. +[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions/README.md) for what extension you need. ## Generating markdown @@ -30,7 +30,7 @@ formatted Markdown tables for all semantic conventions in the specification. Run make table-generation ``` -For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.18.0/semantic-conventions) +For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions) in the OpenTelemetry build tools repository. Using this build tool, it is also possible to generate code for use in OpenTelemetry language projects. From f4ed03e456411a7355042527f232ab94c950d861 Mon Sep 17 00:00:00 2001 From: Ben B Date: Tue, 1 Aug 2023 17:46:45 +0200 Subject: [PATCH 008/482] Add system.cpu.physical.count and system.cpu.logical.count metrics (#99) Co-authored-by: Pablo Baeyens Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Co-authored-by: Dmitrii Anoshin Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 ++ docs/system/system-metrics.md | 14 ++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e60ef60c1d..7ec2227460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,8 @@ Note: This is the first release of Semantic Conventions separate from the Specif ([#133](https://github.com/open-telemetry/semantic-conventions/pull/133)) - Add markdown file for url semantic conventions ([#174](https://github.com/open-telemetry/semantic-conventions/pull/174)) +- Add `system.cpu.physical.count` and `system.cpu.logical.count` metrics. + ([#99](https://github.com/open-telemetry/opentelemetry-specification/pull/99)) ## v1.20.0 (2023-04-07) diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 3882a55788..2f71ef86af 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -33,12 +33,14 @@ instruments not explicitly defined in the specification. **Description:** System level processor metrics. -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key(s) | Attribute Values | -| ---------------------- | -------------------------------------------------------------------------------------------------------- | ----- | ------------------------------------------------- | ---------- | ---------------- | ----------------------------------- | -| system.cpu.time | | s | Counter | Double | state | idle, user, system, interrupt, etc. | -| | | | | | cpu | CPU number [0..n-1] | -| system.cpu.utilization | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of CPUs | 1 | Gauge | Double | state | idle, user, system, interrupt, etc. | -| | | | | | cpu | CPU number (0..n) | +| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key(s) | Attribute Values | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----- | ------------------------------------------------- | ---------- | ---------------- | ----------------------------------- | +| system.cpu.time | Seconds each logical CPU spent on each mode | s | Counter | Double | state | idle, user, system, interrupt, etc. | +| | | | | | cpu | Logical CPU number [0..n-1] | +| system.cpu.utilization | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs | 1 | Gauge | Double | state | idle, user, system, interrupt, etc. | +| | | | | | cpu | Logical CPU number (0..n) | +| system.cpu.physical.count | Reports the number of actual physical processor cores on the hardware | {cpu} | UpDownCounter | Int64 | | | +| system.cpu.logical.count | Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking | {cpu} | UpDownCounter | Int64 | | | ### `system.memory.` - Memory metrics From ea17e33a0d1b047693217eeed3571296416e7824 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 1 Aug 2023 09:20:58 -0700 Subject: [PATCH 009/482] Add PR template (#223) --- .github/PULL_REQUEST_TEMPLATE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..40f8193207 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +Fixes # + +## Changes + +Please provide a brief description of the changes here. + +Note: if the PR is touching an area that is not listed in the [existing areas](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md), or the area does not have sufficient [domain experts coverage](https://github.com/open-telemetry/semantic-conventions/blob/main/.github/CODEOWNERS), the PR might be tagged as [experts needed](https://github.com/open-telemetry/semantic-conventions/labels/experts%20needed) and move slowly until experts are identified. + +## Merge requirement checklist + +* [ ] [CONTRIBUTING.md](https://github.com/open-telemetry/semantic-conventions/blob/main/CONTRIBUTING.md) guidelines followed. +* [ ] [CHANGELOG.md](https://github.com/open-telemetry/semantic-conventions/blob/main/CHANGELOG.md) updated for non-trivial changes. +* [ ] [schema-next.yaml](https://github.com/open-telemetry/semantic-conventions/blob/main/schema-next.yaml) updated with changes to existing conventions. From 6deba959d037ecbc5c557577e32fee9ad691aad0 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Tue, 1 Aug 2023 22:30:10 +0200 Subject: [PATCH 010/482] Generate database metrics semconv from YAML (#90) --- docs/database/database-metrics.md | 191 +++++++++++++++++++++++----- model/metrics/database-metrics.yaml | 107 ++++++++++++++++ 2 files changed, 265 insertions(+), 33 deletions(-) create mode 100644 model/metrics/database-metrics.yaml diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 7a24a76e98..047ec6651d 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -8,56 +8,181 @@ linkTitle: Metrics The conventions described in this section are specific to SQL and NoSQL clients. -**Disclaimer:** These are initial database client metric instruments and attributes but more may be added in the future. +**Disclaimer:** These are initial database client metric instruments +and attributes but more may be added in the future. -- [Metric Instruments](#metric-instruments) - * [Connection pools](#connection-pools) +- [Connection pools](#connection-pools) + * [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) + * [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) + * [Metric: `db.client.connections.idle.min`](#metric-dbclientconnectionsidlemin) + * [Metric: `db.client.connections.max`](#metric-dbclientconnectionsmax) + * [Metric: `db.client.connections.pending_requests`](#metric-dbclientconnectionspending_requests) + * [Metric: `db.client.connections.timeouts`](#metric-dbclientconnectionstimeouts) + * [Metric: `db.client.connections.create_time`](#metric-dbclientconnectionscreate_time) + * [Metric: `db.client.connections.wait_time`](#metric-dbclientconnectionswait_time) + * [Metric: `db.client.connections.use_time`](#metric-dbclientconnectionsuse_time) -## Metric Instruments +## Connection pools -The following metric instruments MUST be used to describe database client operations. They MUST be of the specified type -and units. +The following metric instruments describe database client connection pool operations. -### Connection pools +### Metric: `db.client.connections.usage` -Below is a table of database client connection pool metric instruments that MUST be used by connection pool -instrumentations: +This metric is [required][MetricRequired]. -| Name | Instrument | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | -|-------------------------------|----------------------------|-------------|-------------------------------------------|-------------------------------------------------------------------------------------------| -| `db.client.connections.usage` | UpDownCounter | connections | `{connection}` | The number of connections that are currently in state described by the `state` attribute. | + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.usage` | UpDownCounter | `{connection}` | The number of connections that are currently in state described by the `state` attribute | + -All `db.client.connections.usage` measurements MUST include the following attribute: + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `state` | string | The state of a connection in the pool | `idle` | Required | -| Name | Type | Description | Examples | Requirement Level | -|---------|--------|------------------------------------------------------------------------------|----------|-------------------| -| `state` | string | The state of a connection in the pool. Valid values include: `idle`, `used`. | `idle` | Required | +`state` MUST be one of the following: -Instrumentation libraries for database client connection pools that collect data for the following data MUST use the -following metric instruments. Otherwise, if the instrumentation library does not collect this data, these instruments -MUST NOT be used. +| Value | Description | +|---|---| +| `idle` | idle | +| `used` | used | + +### Metric: `db.client.connections.idle.max` -| Name | Instrument ([*](/docs/general/metrics.md#instrument-types)) | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | -|------------------------------------------|----------------------------------------------|--------------|-------------------------------------------|---------------------------------------------------------------------------------------------------| -| `db.client.connections.idle.max` | UpDownCounter | connections | `{connection}` | The maximum number of idle open connections allowed. | -| `db.client.connections.idle.min` | UpDownCounter | connections | `{connection}` | The minimum number of idle open connections allowed. | -| `db.client.connections.max` | UpDownCounter | connections | `{connection}` | The maximum number of open connections allowed. | -| `db.client.connections.pending_requests` | UpDownCounter | requests | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool. | -| `db.client.connections.timeouts` | Counter | timeouts | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool. | -| `db.client.connections.create_time` | Histogram | milliseconds | `ms` | The time it took to create a new connection. | -| `db.client.connections.wait_time` | Histogram | milliseconds | `ms` | The time it took to obtain an open connection from the pool. | -| `db.client.connections.use_time` | Histogram | milliseconds | `ms` | The time between borrowing a connection and returning it to the pool. | +This metric is [recommended][MetricRecommended]. -Below is a table of the attributes that MUST be included on all connection pool measurements: + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed | + -| Name | Type | Description | Examples | Requirement Level | -|-------------|--------|------------------------------------------------------------------------------|----------------|-------------------| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used. | `myDataSource` | Required | + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.idle.min` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.max` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.pending_requests` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.pending_requests` | UpDownCounter | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.timeouts` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.timeouts` | Counter | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.create_time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.create_time` | Histogram | `ms` | The time it took to create a new connection | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.wait_time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.wait_time` | Histogram | `ms` | The time it took to obtain an open connection from the pool | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + + +### Metric: `db.client.connections.use_time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `db.client.connections.use_time` | Histogram | `ms` | The time between borrowing a connection and returning it to the pool | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#required +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml new file mode 100644 index 0000000000..fdb6a0ce2a --- /dev/null +++ b/model/metrics/database-metrics.yaml @@ -0,0 +1,107 @@ +groups: + - id: attributes.db + type: attribute_group + brief: Describes Database attributes + attributes: + - id: state + type: + allow_custom_values: false + members: + - id: idle + value: 'idle' + - id: used + value: 'used' + requirement_level: required + brief: "The state of a connection in the pool" + examples: ["idle"] + - id: pool.name + type: string + requirement_level: required + brief: > + The name of the connection pool; unique within the instrumented application. + In case the connection pool implementation does not provide a name, + then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) + should be used + examples: ["myDataSource"] + + - id: metric.db.client.connections.usage + type: metric + metric_name: db.client.connections.usage + brief: "The number of connections that are currently in state described by the `state` attribute" + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: state + - ref: pool.name + + - id: metric.db.client.connections.idle.max + type: metric + metric_name: db.client.connections.idle.max + brief: "The maximum number of idle open connections allowed" + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.idle.min + type: metric + metric_name: db.client.connections.idle.min + brief: "The minimum number of idle open connections allowed" + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.max + type: metric + metric_name: db.client.connections.max + brief: "The maximum number of open connections allowed" + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.pending_requests + type: metric + metric_name: db.client.connections.pending_requests + brief: "The number of pending requests for an open connection, cumulative for the entire pool" + instrument: updowncounter + unit: "{request}" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.timeouts + type: metric + metric_name: db.client.connections.timeouts + brief: "The number of connection timeouts that have occurred trying to obtain a connection from the pool" + instrument: counter + unit: "{timeout}" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.create_time + type: metric + metric_name: db.client.connections.create_time + brief: "The time it took to create a new connection" + instrument: histogram + unit: "ms" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.wait_time + type: metric + metric_name: db.client.connections.wait_time + brief: "The time it took to obtain an open connection from the pool" + instrument: histogram + unit: "ms" + attributes: + - ref: pool.name + + - id: metric.db.client.connections.use_time + type: metric + metric_name: db.client.connections.use_time + brief: "The time between borrowing a connection and returning it to the pool" + instrument: histogram + unit: "ms" + attributes: + - ref: pool.name From b89a0337674d8a68002c2bba30ddddf52a9c1c6f Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Wed, 2 Aug 2023 19:22:58 +0200 Subject: [PATCH 011/482] Generate RPC metrics from YAML (#93) --- docs/rpc/rpc-metrics.md | 137 ++++++++++++++++++++++++++++----- model/metrics/rpc-metrics.yaml | 115 +++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 18 deletions(-) create mode 100644 model/metrics/rpc-metrics.yaml diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index aaa3647ad3..98d444be96 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -18,7 +18,17 @@ metrics can be filtered for finer grain analysis. - [Metric instruments](#metric-instruments) * [RPC Server](#rpc-server) + + [Metric: `rpc.server.duration`](#metric-rpcserverduration) + + [Metric: `rpc.server.request.size`](#metric-rpcserverrequestsize) + + [Metric: `rpc.server.response.size`](#metric-rpcserverresponsesize) + + [Metric: `rpc.server.requests_per_rpc`](#metric-rpcserverrequests_per_rpc) + + [Metric: `rpc.server.responses_per_rpc`](#metric-rpcserverresponses_per_rpc) * [RPC Client](#rpc-client) + + [Metric: `rpc.client.duration`](#metric-rpcclientduration) + + [Metric: `rpc.client.request.size`](#metric-rpcclientrequestsize) + + [Metric: `rpc.client.response.size`](#metric-rpcclientresponsesize) + + [Metric: `rpc.client.requests_per_rpc`](#metric-rpcclientrequests_per_rpc) + + [Metric: `rpc.client.responses_per_rpc`](#metric-rpcclientresponses_per_rpc) - [Attributes](#attributes) * [Service name](#service-name) - [Semantic Conventions for specific RPC technologies](#semantic-conventions-for-specific-rpc-technologies) @@ -59,28 +69,118 @@ MUST be of the specified type and units. ### RPC Server -Below is a table of RPC server metric instruments. +Below is a list of RPC server metric instruments. -| Name | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | Status | Streaming | -|------|------------|------|-------------------------------------------|-------------|--------|-----------| -| `rpc.server.duration` | Histogram | milliseconds | `ms` | measures duration of inbound RPC | Recommended | N/A. While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. | -| `rpc.server.request.size` | Histogram | Bytes | `By` | measures size of RPC request messages (uncompressed) | Optional | Recorded per message in a streaming batch | -| `rpc.server.response.size` | Histogram | Bytes | `By` | measures size of RPC response messages (uncompressed) | Optional | Recorded per response in a streaming batch | -| `rpc.server.requests_per_rpc` | Histogram | count | `{count}` | measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs | Optional | Required | -| `rpc.server.responses_per_rpc` | Histogram | count | `{count}` | measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs | Optional | Required | +#### Metric: `rpc.server.duration` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.server.duration` | Histogram | `ms` | Measures the duration of inbound RPC. **Streaming**: N/A. [1] | + +**[1]:** While streaming RPCs may record this metric as start-of-batch +to end-of-batch, it's hard to interpret in practice. + + +#### Metric: `rpc.server.request.size` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.server.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). **Streaming**: Recorded per message in a streaming batch | + + +#### Metric: `rpc.server.response.size` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.server.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). **Streaming**: Recorded per response in a streaming batch | + + +#### Metric: `rpc.server.requests_per_rpc` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.server.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | + + +#### Metric: `rpc.server.responses_per_rpc` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.server.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | + ### RPC Client -Below is a table of RPC client metric instruments. These apply to traditional -RPC usage, not streaming RPCs. +Below is a list of RPC client metric instruments. +These apply to traditional RPC usage, not streaming RPCs. -| Name | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | Status | Streaming | -|------|------------|------|-------------------------------------------|-------------|--------|-----------| -| `rpc.client.duration` | Histogram | milliseconds | `ms` | measures duration of outbound RPC | Recommended | N/A. While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. | -| `rpc.client.request.size` | Histogram | Bytes | `By` | measures size of RPC request messages (uncompressed) | Optional | Recorded per message in a streaming batch | -| `rpc.client.response.size` | Histogram | Bytes | `By` | measures size of RPC response messages (uncompressed) | Optional | Recorded per message in a streaming batch | -| `rpc.client.requests_per_rpc` | Histogram | count | `{count}` | measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs | Optional | Required | -| `rpc.client.responses_per_rpc` | Histogram | count | `{count}` | measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs | Optional | Required | +#### Metric: `rpc.client.duration` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.client.duration` | Histogram | `ms` | Measures the duration of outbound RPC **Streaming**: N/A. [1] | + +**[1]:** While streaming RPCs may record this metric as start-of-batch +to end-of-batch, it's hard to interpret in practice. + + +#### Metric: `rpc.client.request.size` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.client.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). **Streaming**: Recorded per message in a streaming batch | + + +#### Metric: `rpc.client.response.size` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.client.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). **Streaming**: Recorded per response in a streaming batch | + + +#### Metric: `rpc.client.requests_per_rpc` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.client.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | + + +#### Metric: `rpc.client.responses_per_rpc` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `rpc.client.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | + ## Attributes @@ -146,4 +246,5 @@ More specific Semantic Conventions are defined for the following RPC technologie * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/model/metrics/rpc-metrics.yaml b/model/metrics/rpc-metrics.yaml new file mode 100644 index 0000000000..38755d4bf2 --- /dev/null +++ b/model/metrics/rpc-metrics.yaml @@ -0,0 +1,115 @@ +groups: + # TODO: Should we list the attributes on each metric + # OR leave a single table like it is today? Since all attributes are applied + # to all metrics, the repetition of them bloats the page + - id: attributes.metrics.rpc + type: attribute_group + brief: "Describes RPC metric attributes." + attributes: + - ref: rpc.system + - ref: rpc.service + - ref: rpc.method + - ref: network.transport + - ref: network.type + - ref: server.address + - ref: server.port + - ref: server.socket.address + - ref: server.socket.port + + # RPC Server metrics + - id: metric.rpc.server.duration + type: metric + metric_name: rpc.server.duration + brief: > + Measures the duration of inbound RPC. + **Streaming**: N/A. + instrument: histogram + unit: "ms" + note: | + While streaming RPCs may record this metric as start-of-batch + to end-of-batch, it's hard to interpret in practice. + + - id: metric.rpc.server.request.size + type: metric + metric_name: rpc.server.request.size + brief: > + Measures the size of RPC request messages (uncompressed). + **Streaming**: Recorded per message in a streaming batch + instrument: histogram + unit: "By" + + - id: metric.rpc.server.response.size + type: metric + metric_name: rpc.server.response.size + brief: > + Measures the size of RPC response messages (uncompressed). + **Streaming**: Recorded per response in a streaming batch + instrument: histogram + unit: "By" + + - id: metric.rpc.server.requests_per_rpc + type: metric + metric_name: rpc.server.requests_per_rpc + brief: > + Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. + **Streaming**: This metric is required for server and client streaming RPCs + instrument: histogram + unit: "{count}" + + - id: metric.rpc.server.responses_per_rpc + type: metric + metric_name: rpc.server.responses_per_rpc + brief: > + Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. + **Streaming**: This metric is required for server and client streaming RPCs + instrument: histogram + unit: "{count}" + + # RPC Client metrics + - id: metric.rpc.client.duration + type: metric + metric_name: rpc.client.duration + brief: > + Measures the duration of outbound RPC + **Streaming**: N/A. + instrument: histogram + unit: "ms" + note: | + While streaming RPCs may record this metric as start-of-batch + to end-of-batch, it's hard to interpret in practice. + + - id: metric.rpc.client.request.size + type: metric + metric_name: rpc.client.request.size + brief: > + Measures the size of RPC request messages (uncompressed). + **Streaming**: Recorded per message in a streaming batch + instrument: histogram + unit: "By" + + - id: metric.rpc.client.response.size + type: metric + metric_name: rpc.client.response.size + brief: > + Measures the size of RPC response messages (uncompressed). + **Streaming**: Recorded per response in a streaming batch + instrument: histogram + unit: "By" + + - id: metric.rpc.client.requests_per_rpc + type: metric + metric_name: rpc.client.requests_per_rpc + brief: > + Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. + **Streaming**: This metric is required for server and client streaming RPCs + instrument: histogram + unit: "{count}" + + - id: metric.rpc.client.responses_per_rpc + type: metric + metric_name: rpc.client.responses_per_rpc + brief: > + Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. + **Streaming**: This metric is required for server and client streaming RPCs + instrument: histogram + unit: "{count}" From fa2d7f993fcc1b7bdc29f9ea453c806a9863e260 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 3 Aug 2023 10:26:43 -0700 Subject: [PATCH 012/482] Rename `http.*.duration` to `http.*.request.duration` (#224) --- CHANGELOG.md | 5 ++++- docs/general/metrics.md | 2 +- docs/http/http-metrics.md | 20 ++++++++++---------- model/metrics/http.yaml | 8 ++++---- schema-next.yaml | 6 ++++++ 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ec2227460..9b633c9659 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,10 @@ release. ([#95](https://github.com/open-telemetry/semantic-conventions/pull/95)) - Update `.count` metric naming convention so that it only applies to UpDownCounters, and add that `.total` should not be used by either Counters or UpDownCounters - ([#107](https://github.com/open-telemetry/opentelemetry-specification/pull/107)) + ([#107](https://github.com/open-telemetry/semantic-conventions/pull/107)) +- BREAKING: Rename `http.client.duration` and `http.server.duration` metrics to + `http.client.request.duration` and `http.server.request.duration` respectively. + ([#224](https://github.com/open-telemetry/semantic-conventions/pull/224)) ## v1.21.0 (2023-07-13) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 3ba128a273..938a5e73e1 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -113,7 +113,7 @@ question is a non-unit (like `{fault}` or `{operation}`). Examples: -* `system.filesystem.utilization`, `http.server.duration`, and `system.cpu.time` +* `system.filesystem.utilization`, `http.server.request.duration`, and `system.cpu.time` should not be pluralized, even if many data points are recorded. * `system.paging.faults`, `system.disk.operations`, and `system.network.packets` should be pluralized, even if only a single data point is recorded. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 502d9e0a14..fe9c4da823 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -15,12 +15,12 @@ operations. By adding HTTP attributes to metric events it allows for finely tune - [HTTP Server](#http-server) - * [Metric: `http.server.duration`](#metric-httpserverduration) + * [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) * [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) * [Metric: `http.server.request.size`](#metric-httpserverrequestsize) * [Metric: `http.server.response.size`](#metric-httpserverresponsesize) - [HTTP Client](#http-client) - * [Metric: `http.client.duration`](#metric-httpclientduration) + * [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) * [Metric: `http.client.request.size`](#metric-httpclientrequestsize) * [Metric: `http.client.response.size`](#metric-httpclientresponsesize) @@ -53,7 +53,7 @@ operations. By adding HTTP attributes to metric events it allows for finely tune ## HTTP Server -### Metric: `http.server.duration` +### Metric: `http.server.request.duration` **Status**: [Experimental, Feature-freeze][DocumentStatus] @@ -65,13 +65,13 @@ This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.duration` | Histogram | `s` | Measures the duration of inbound HTTP requests. | +| `http.server.request.duration` | Histogram | `s` | Measures the duration of inbound HTTP requests. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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 | @@ -364,7 +364,7 @@ SHOULD NOT be set if only IP address is available and capturing name would requi ## HTTP Client -### Metric: `http.client.duration` +### Metric: `http.client.request.duration` **Status**: [Experimental, Feature-freeze][DocumentStatus] @@ -376,13 +376,13 @@ This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.duration` | Histogram | `s` | Measures the duration of outbound HTTP requests. | +| `http.client.request.duration` | Histogram | `s` | Measures the duration of outbound HTTP requests. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `http.request.method` | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 385242ddbb..813179a005 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -48,9 +48,9 @@ groups: - ref: network.protocol.version - ref: server.socket.address - - id: metric.http.server.duration + - id: metric.http.server.request.duration type: metric - metric_name: http.server.duration + metric_name: http.server.request.duration brief: "Measures the duration of inbound HTTP requests." instrument: histogram unit: "s" @@ -110,9 +110,9 @@ groups: unit: "By" extends: metric_attributes.http.server - - id: metric.http.client.duration + - id: metric.http.client.request.duration type: metric - metric_name: http.client.duration + metric_name: http.client.request.duration brief: "Measures the duration of outbound HTTP requests." instrument: histogram unit: "s" diff --git a/schema-next.yaml b/schema-next.yaml index 37d35efc84..14e82faac1 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,12 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/1.21.0 versions: next: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration 1.21.0: spans: changes: From 007a4a8bedc6593e19394bb8e192a020cf8c189d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Sun, 6 Aug 2023 13:50:56 -0700 Subject: [PATCH 013/482] HTTP version should be 2 and 3 instead of 2.0 and 3.0 (#228) --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 2 +- model/http-common.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b633c9659..cf8ad93306 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ release. - BREAKING: Rename `http.client.duration` and `http.server.duration` metrics to `http.client.request.duration` and `http.server.request.duration` respectively. ([#224](https://github.com/open-telemetry/semantic-conventions/pull/224)) +- Update HTTP `network.protocol.version` examples to match HTTP RFCs. + ([#228](https://github.com/open-telemetry/semantic-conventions/pull/228)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 946e1be2ca..dd15d32552 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -101,7 +101,7 @@ sections below. | `http.response.body.size` | 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.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `1.0`; `1.1`; `2.0` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [4] | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | diff --git a/model/http-common.yaml b/model/http-common.yaml index 682b2cb984..9db84ce583 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -68,7 +68,7 @@ groups: requirement_level: recommended: if not default (`http`). - ref: network.protocol.version - examples: ['1.0', '1.1', '2.0'] + examples: ['1.0', '1.1', '2', '3'] - id: attributes.http.client prefix: http From 9d45283f7a39e450beddf0880724f08c46e695f1 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 7 Aug 2023 17:27:53 +0200 Subject: [PATCH 014/482] Generate FaaS metrics semconv from YAML (#88) --- CHANGELOG.md | 4 + docs/faas/faas-metrics.md | 275 ++++++++++++++++++++++++++++---- docs/faas/faas-spans.md | 36 ++--- model/faas-common.yaml | 77 +++++++++ model/metrics/faas-metrics.yaml | 81 ++++++++++ model/trace/faas.yaml | 94 ++--------- 6 files changed, 438 insertions(+), 129 deletions(-) create mode 100644 model/faas-common.yaml create mode 100644 model/metrics/faas-metrics.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8ad93306..10ee6bcda1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ release. ([#224](https://github.com/open-telemetry/semantic-conventions/pull/224)) - Update HTTP `network.protocol.version` examples to match HTTP RFCs. ([#228](https://github.com/open-telemetry/semantic-conventions/pull/228)) +- Generate FaaS metric semantic conventions from YAML. + ([#88](https://github.com/open-telemetry/semantic-conventions/pull/88)) + The conventions cover metrics that are recorded by the FaaS itself and not by + clients invoking them. ## v1.21.0 (2023-07-13) diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index 376ec3dc7d..ab1f395c13 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -13,15 +13,21 @@ The conventions described in this section are FaaS (function as a service) speci metric events about those operations will be generated and reported to provide insights into the operations. By adding FaaS attributes to metric events it allows for finely tuned filtering. -**Disclaimer:** These are initial FaaS metric instruments and attributes but more may be added in the future. - - [Metric Instruments](#metric-instruments) - * [FaaS Invocations](#faas-invocations) -- [Attributes](#attributes) + * [FaaS Instance](#faas-instance) + + [Metric: `faas.invoke_duration`](#metric-faasinvoke_duration) + + [Metric: `faas.init_duration`](#metric-faasinit_duration) + + [Metric: `faas.coldstarts`](#metric-faascoldstarts) + + [Metric: `faas.errors`](#metric-faaserrors) + + [Metric: `faas.invocations`](#metric-faasinvocations) + + [Metric: `faas.timeouts`](#metric-faastimeouts) + + [Metric: `faas.mem_usage`](#metric-faasmem_usage) + + [Metric: `faas.cpu_usage`](#metric-faascpu_usage) + + [Metric: `faas.net_io`](#metric-faasnet_io) - [References](#references) * [Metric References](#metric-references) @@ -29,45 +35,245 @@ operations. By adding FaaS attributes to metric events it allows for finely tune ## Metric Instruments -The following metric instruments MUST be used to describe FaaS operations. They MUST be of the specified -type and units. +The following metric instruments describe FaaS operations. + +### FaaS Instance + +The following metrics are recorded by the FaaS instance. + +#### Metric: `faas.invoke_duration` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.invoke_duration` | Histogram | `ms` | Measures the duration of the function's logic execution | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.init_duration` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.init_duration` | Histogram | `ms` | Measures the duration of the function's initialization, such as a cold start | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.coldstarts` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.coldstarts` | Counter | `{coldstart}` | Number of invocation cold starts | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.errors` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.errors` | Counter | `{error}` | Number of invocation errors | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.invocations` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.invocations` | Counter | `{invocation}` | Number of successful invocations | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.timeouts` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.timeouts` | Counter | `{timeout}` | Number of invocation timeouts | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.mem_usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.mem_usage` | Histogram | `By` | Distribution of max memory usage per invocation | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + + +#### Metric: `faas.cpu_usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.cpu_usage` | Histogram | `ms` | Distribution of CPU usage per invocation | + -### FaaS Invocations + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | -Below is a table of FaaS invocation metric instruments. +`faas.trigger` MUST be one of the following: -| Name | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | -|------------------------|---------------------------------------------------|--------------|-------------------------------------------|------------------------------------------------------------------------------| -| `faas.invoke_duration` | Histogram | milliseconds | `ms` | Measures the duration of the invocation | -| `faas.init_duration` | Histogram | milliseconds | `ms` | Measures the duration of the function's initialization, such as a cold start | -| `faas.coldstarts` | Counter | default unit | `{coldstart}` | Number of invocation cold starts. | -| `faas.errors` | Counter | default unit | `{error}` | Number of invocation errors. | -| `faas.invocations` | Counter | default unit | `{invocation}` | Number of successful invocations. | -| `faas.timeouts` | Counter | default unit | `{timeout}` | Number of invocation timeouts. | +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + -Optionally, when applicable: +#### Metric: `faas.net_io` -| Name | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | -|------------------|---------------------------------------------------|--------------|-------------------------------------------|-------------------------------------------------| -| `faas.mem_usage` | Histogram | Bytes | `By` | Distribution of max memory usage per invocation | -| `faas.cpu_usage` | Histogram | milliseconds | `ms` | Distribution of CPU usage per invocation | -| `faas.net_io` | Histogram | Bytes | `By` | Distribution of net I/O usage per invocation | +This metric is [recommended][MetricRecommended]. -## Attributes + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `faas.net_io` | Histogram | `By` | Distribution of net I/O usage per invocation | + -Below is a table of the attributes to be included on FaaS metric events. + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | -| Name | Requirement Level | Notes and examples | -|-------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------| -| `faas.trigger` | Required | Type of the trigger on which the function is invoked. SHOULD be one of: `datasource`, `http`, `pubsub`, `timer`, `other` | -| `faas.invoked_name` | Required | Name of the invoked function. Example: `my-function` | -| `faas.invoked_provider` | Required | Cloud provider of the invoked function. Corresponds to the resource `cloud.provider`. Example: `aws` | -| `faas.invoked_region` | Required | Cloud provider region of invoked function. Corresponds to resource `cloud.region`. Example: `us-east-1` | +`faas.trigger` MUST be one of the following: -More details on these attributes, the function name and the difference compared to the faas.invoked_name can be found at the related [FaaS tracing specification](faas-spans.md). -For incoming FaaS invocations, the function for which metrics are reported is already described by its [FaaS resource attributes](../resource/faas.md). -Outgoing FaaS invocations are identified using the `faas.invoked_*` attributes above. -`faas.trigger` SHOULD be included in all metric events while `faas.invoked_*` attributes apply on outgoing FaaS invocation events only. +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + ## References @@ -83,3 +289,4 @@ FaaS providers. This list is not exhaustive. * [OpenFaas Metrics](https://docs.openfaas.com/architecture/metrics/) [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 2a06a3c1ec..8a90312273 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -38,24 +38,14 @@ Span `name` should be set to the function name being executed. Depending on the If Spans following this convention are produced, a Resource of type `faas` MUST exist following the [Resource semantic convention](../resource/faas.md). - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. [1] | `datasource` | Recommended | | `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | -| [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [2] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| `faas.trigger` | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | -**[1]:** For the server/consumer span on the incoming side, -`faas.trigger` MUST be set. - -Clients invoking FaaS instances usually cannot set `faas.trigger`, -since they would typically need to look in the payload to determine -the event type. If clients set it, it should be the same as the -trigger that corresponding incoming would have (i.e., this has -nothing to do with the underlying transport used to make the API -call to invoke the lambda, which is often HTTP). - -**[2]:** On some cloud providers, it may not be possible to determine the full ID at startup, +**[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. The exact value to use for `cloud.resource_id` depends on the cloud provider. @@ -73,14 +63,24 @@ The following well-known definitions MUST be used if you set this attribute and This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. +**[2]:** For the server/consumer span on the incoming side, +`faas.trigger` MUST be set. + +Clients invoking FaaS instances usually cannot set `faas.trigger`, +since they would typically need to look in the payload to determine +the event type. If clients set it, it should be the same as the +trigger that corresponding incoming would have (i.e., this has +nothing to do with the underlying transport used to make the API +call to invoke the lambda, which is often HTTP). + `faas.trigger` MUST be one of the following: | Value | Description | |---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write. | +| `datasource` | A response to some data source operation such as a database or filesystem read/write | | `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system. | -| `timer` | A function is scheduled to be executed regularly. | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | | `other` | If none of the others apply | @@ -158,7 +158,7 @@ The values reported by the client for the attributes listed below SHOULD be equa the corresponding [FaaS resource attributes][] and [Cloud resource attributes][], which the invoked FaaS instance reports about itself, if it's instrumented. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `faas.invoked_name` | string | The name of the invoked function. [1] | `my-function` | Required | diff --git a/model/faas-common.yaml b/model/faas-common.yaml new file mode 100644 index 0000000000..7f903bb57f --- /dev/null +++ b/model/faas-common.yaml @@ -0,0 +1,77 @@ +groups: + - id: attributes.faas.common + type: attribute_group + brief: "Describes FaaS attributes." + prefix: faas + attributes: + - id: trigger + brief: 'Type of the trigger which caused this function invocation.' + type: + allow_custom_values: false + members: + - id: datasource + value: 'datasource' + brief: 'A response to some data source operation such as a database or filesystem read/write' + - id: http + value: 'http' + brief: 'To provide an answer to an inbound HTTP request' + - id: pubsub + value: 'pubsub' + brief: 'A function is set to be executed when messages are sent to a messaging system' + - id: timer + value: 'timer' + brief: 'A function is scheduled to be executed regularly' + - id: other + value: 'other' + brief: 'If none of the others apply' + - id: invoked_name + type: string + requirement_level: required + brief: > + The name of the invoked function. + note: > + SHOULD be equal to the `faas.name` resource attribute of the + invoked function. + examples: 'my-function' + - id: invoked_provider + type: + allow_custom_values: true + members: + - id: 'alibaba_cloud' + value: 'alibaba_cloud' + brief: 'Alibaba Cloud' + - id: 'aws' + value: 'aws' + brief: 'Amazon Web Services' + - id: 'azure' + value: 'azure' + brief: 'Microsoft Azure' + - id: 'gcp' + value: 'gcp' + brief: 'Google Cloud Platform' + - id: 'tencent_cloud' + value: 'tencent_cloud' + brief: 'Tencent Cloud' + requirement_level: required + brief: > + The cloud provider of the invoked function. + note: > + SHOULD be equal to the `cloud.provider` resource attribute of the + invoked function. + - id: invoked_region + type: string + requirement_level: + conditionally_required: > + For some cloud providers, like AWS or GCP, the region in which a + function is hosted is essential to uniquely identify the function + and also part of its endpoint. Since it's part of the endpoint + being called, the region is always known to clients. In these cases, + `faas.invoked_region` MUST be set accordingly. If the region is + unknown to the client or not required for identifying the invoked + function, setting `faas.invoked_region` is optional. + brief: > + The cloud region of the invoked function. + note: > + SHOULD be equal to the `cloud.region` resource attribute of the + invoked function. + examples: 'eu-central-1' diff --git a/model/metrics/faas-metrics.yaml b/model/metrics/faas-metrics.yaml new file mode 100644 index 0000000000..6a753a7351 --- /dev/null +++ b/model/metrics/faas-metrics.yaml @@ -0,0 +1,81 @@ +groups: + - id: metric.faas.invoke_duration + type: metric + metric_name: faas.invoke_duration + brief: "Measures the duration of the function's logic execution" + instrument: histogram + unit: "ms" + attributes: + - ref: faas.trigger + + - id: metric.faas.init_duration + type: metric + metric_name: faas.init_duration + brief: "Measures the duration of the function's initialization, such as a cold start" + instrument: histogram + unit: "ms" + attributes: + - ref: faas.trigger + + - id: metric.faas.coldstarts + type: metric + metric_name: faas.coldstarts + brief: "Number of invocation cold starts" + instrument: counter + unit: "{coldstart}" + attributes: + - ref: faas.trigger + + - id: metric.faas.errors + type: metric + metric_name: faas.errors + brief: "Number of invocation errors" + instrument: counter + unit: "{error}" + attributes: + - ref: faas.trigger + + - id: metric.faas.invocations + type: metric + metric_name: faas.invocations + brief: "Number of successful invocations" + instrument: counter + unit: "{invocation}" + attributes: + - ref: faas.trigger + + - id: metric.faas.timeouts + type: metric + metric_name: faas.timeouts + brief: "Number of invocation timeouts" + instrument: counter + unit: "{timeout}" + attributes: + - ref: faas.trigger + + - id: metric.faas.mem_usage + type: metric + metric_name: faas.mem_usage + brief: "Distribution of max memory usage per invocation" + instrument: histogram + unit: "By" + attributes: + - ref: faas.trigger + + - id: metric.faas.cpu_usage + type: metric + metric_name: faas.cpu_usage + brief: "Distribution of CPU usage per invocation" + instrument: histogram + unit: "ms" + attributes: + - ref: faas.trigger + + - id: metric.faas.net_io + type: metric + metric_name: faas.net_io + brief: "Distribution of net I/O usage per invocation" + instrument: histogram + unit: "By" + attributes: + - ref: faas.trigger diff --git a/model/trace/faas.yaml b/model/trace/faas.yaml index d30d41920a..84b7141b38 100644 --- a/model/trace/faas.yaml +++ b/model/trace/faas.yaml @@ -7,8 +7,7 @@ groups: runs without provisioning or managing of servers (also known as serverless functions or Function as a Service (FaaS)) with spans. attributes: - - id: trigger - brief: 'Type of the trigger which caused this function invocation.' + - ref: faas.trigger note: | For the server/consumer span on the incoming side, `faas.trigger` MUST be set. @@ -19,33 +18,15 @@ groups: trigger that corresponding incoming would have (i.e., this has nothing to do with the underlying transport used to make the API call to invoke the lambda, which is often HTTP). - type: - allow_custom_values: false - members: - - id: datasource - value: 'datasource' - brief: 'A response to some data source operation such as a database or filesystem read/write.' - - id: http - value: 'http' - brief: 'To provide an answer to an inbound HTTP request' - - id: pubsub - value: 'pubsub' - brief: 'A function is set to be executed when messages are sent to a messaging system.' - - id: timer - value: 'timer' - brief: 'A function is scheduled to be executed regularly.' - - id: other - value: 'other' - brief: 'If none of the others apply' - id: invocation_id type: string brief: 'The invocation ID of the current function invocation.' examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' - ref: cloud.resource_id + - id: faas_span.datasource prefix: faas.document type: span - extends: faas_span brief: > Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write. @@ -90,24 +71,23 @@ groups: - id: faas_span.http type: span - extends: faas_span brief: > Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write. constraints: - include: trace.http.server + attributes: [] - id: faas_span.pubsub type: span - extends: faas_span brief: > Semantic Convention for FaaS set to be executed when messages are sent to a messaging system. constraints: - include: messaging + attributes: [] - id: faas_span.timer - extends: faas_span prefix: faas type: span brief: > @@ -128,7 +108,6 @@ groups: examples: "0/5 * * * ? *" - id: faas_span.in - extends: faas_span span_kind: server prefix: faas type: span @@ -142,63 +121,24 @@ groups: first time (aka cold-start). - ref: faas.trigger requirement_level: required + note: | + For the server/consumer span on the incoming side, + `faas.trigger` MUST be set. + + Clients invoking FaaS instances usually cannot set `faas.trigger`, + since they would typically need to look in the payload to determine + the event type. If clients set it, it should be the same as the + trigger that corresponding incoming would have (i.e., this has + nothing to do with the underlying transport used to make the API + call to invoke the lambda, which is often HTTP). - id: faas_span.out - extends: faas_span span_kind: client prefix: faas type: span brief: > Contains additional attributes for outgoing FaaS spans. attributes: - - id: invoked_name - type: string - requirement_level: required - brief: > - The name of the invoked function. - note: > - SHOULD be equal to the `faas.name` resource attribute of the - invoked function. - examples: 'my-function' - - id: invoked_provider - type: - allow_custom_values: true - members: - - id: 'alibaba_cloud' - value: 'alibaba_cloud' - brief: 'Alibaba Cloud' - - id: 'aws' - value: 'aws' - brief: 'Amazon Web Services' - - id: 'azure' - value: 'azure' - brief: 'Microsoft Azure' - - id: 'gcp' - value: 'gcp' - brief: 'Google Cloud Platform' - - id: 'tencent_cloud' - value: 'tencent_cloud' - brief: 'Tencent Cloud' - requirement_level: required - brief: > - The cloud provider of the invoked function. - note: > - SHOULD be equal to the `cloud.provider` resource attribute of the - invoked function. - - id: invoked_region - type: string - requirement_level: - conditionally_required: > - For some cloud providers, like AWS or GCP, the region in which a - function is hosted is essential to uniquely identify the function - and also part of its endpoint. Since it's part of the endpoint - being called, the region is always known to clients. In these cases, - `faas.invoked_region` MUST be set accordingly. If the region is - unknown to the client or not required for identifying the invoked - function, setting `faas.invoked_region` is optional. - brief: > - The cloud region of the invoked function. - note: > - SHOULD be equal to the `cloud.region` resource attribute of the - invoked function. - examples: 'eu-central-1' + - ref: faas.invoked_name + - ref: faas.invoked_provider + - ref: faas.invoked_region From 6c0c6a04767404be87fae44120ac376e70f85c7d Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 7 Aug 2023 18:58:19 +0200 Subject: [PATCH 015/482] Re-introduce namespace to describe the original destination (#156) Co-authored-by: Armin Ruech --- CHANGELOG.md | 3 +++ docs/messaging/messaging-spans.md | 30 +++++++++++++++++++++++++++--- model/trace/messaging.yaml | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10ee6bcda1..2009f95066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ release. ([#224](https://github.com/open-telemetry/semantic-conventions/pull/224)) - Update HTTP `network.protocol.version` examples to match HTTP RFCs. ([#228](https://github.com/open-telemetry/semantic-conventions/pull/228)) +- Re-introduce namespace and attributes to describe the original destination messages were + published to (`messaging.destination_publish.*`). + ([#156](https://github.com/open-telemetry/semantic-conventions/pull/156)) - Generate FaaS metric semantic conventions from YAML. ([#88](https://github.com/open-telemetry/semantic-conventions/pull/88)) The conventions cover metrics that are recorded by the FaaS itself and not by diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index cee92e4815..a8a642acff 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -105,6 +105,12 @@ A destination is usually uniquely identified by its name within the messaging system instance. Examples of a destination name would be an URL or a simple one-word identifier. +In some use cases, messages are routed within one or multiple brokers. In such +cases, the destination the message was originally published to is different +from the destination it is being consumed from. When information about the +destination where the message was originally published to is available, consumers +can record them under the `destination_publish` namespace. + Typical examples of destinations include Kafka topics, RabbitMQ queues and topics. ### Message consumption @@ -281,9 +287,8 @@ These attributes should be set to the broker to which the message is sent/from w ### Attribute namespaces - `messaging.message`: Contains attributes that describe individual messages -- `messaging.destination`: Contains attributes that describe the logical entity - messages are published to and received from. - See [Destinations](#destinations) for more details +- `messaging.destination`: Contains attributes that describe the logical entity messages are published to. See [Destinations](#destinations) for more details +- `messaging.destination_publish`: Contains attributes that describe the logical entity messages were originally published to. See [Destinations](#destinations) for more details - `messaging.batch`: Contains attributes that describe batch operations - `messaging.consumer`: Contains attributes that describe application instance that consumes a message. See [consumer](#consumer) for more details @@ -298,6 +303,25 @@ as described in [Attributes specific to certain messaging systems](#attributes-s ### Consumer attributes +The following additional attributes describe message consumer operations. + +Since messages could be routed by brokers, the destination messages are published +to may not match with the destination they are consumed from. + +If information about the original destination is available on the consumer, +consumer instrumentations SHOULD populate the attributes +under the namespace `messaging.destination_publish.*` + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | +| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | Recommended | + +**[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If +the broker does not have such notion, the original destination name SHOULD uniquely identify the broker. + + The *receive* span is used to track the time used for receiving the message(s), whereas the *process* span(s) track the time for processing the message(s). Note that one or multiple Spans with `messaging.operation` = `process` may often be the children of a Span with `messaging.operation` = `receive`. The distinction between receiving and processing of messages is not always of particular interest or sometimes hidden away in a framework (see the [Message consumption](#message-consumption) section above) and therefore the attribute can be left out. diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 5df3c54698..bb7a768638 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -64,6 +64,34 @@ groups: type: boolean brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' + - id: messaging.destination_publish + prefix: messaging.destination_publish + type: attribute_group + brief: > + Semantic convention for attributes that describe the publish messaging destination on broker. + The term Publish Destination refers to the destination the message was originally published to. + These attributes should be used on the consumer side when information about + the publish destination is available and different than the destination message are consumed from. + note: | + Publish destination attributes should be set on publish, receive, + or other spans describing messaging operations. + Destination attributes should be set when the messaging operation handles + single messages. When the operation handles a batch of messages, + the destination attributes should only be applied when the attribute value + applies to all messages in the batch. + In other cases, destination attributes may be set on links. + attributes: + - id: name + type: string + brief: 'The name of the original destination the message was published to' + note: | + The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If + the broker does not have such notion, the original destination name SHOULD uniquely identify the broker. + examples: ['MyQueue', 'MyTopic'] + - id: anonymous + type: boolean + brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' + - id: messaging prefix: messaging type: span From 761ddca493c5ca6105bfeafda7e0d1cd0f66eb11 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 8 Aug 2023 10:17:52 -0700 Subject: [PATCH 016/482] Move Joao Grassi from approver to maintainer (#239) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 73e784ec82..4b8b2cf6f6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/ope - [Alexander Wert](https://github.com/AlexanderWert), Elastic - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian -- [Joao Grassi](https://github.com/joaopgrassi), Dynatrace - [Johannes Tax](https://github.com/pyohannes), Grafana Labs - [Liudmila Molkova](https://github.com/lmolkova), Microsoft - [Sean Marciniak](https://github.com/MovieStoreGuy), Atlassian @@ -30,9 +29,10 @@ _Find more about the approver role in [community repository](https://github.com/ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs/open-telemetry/teams/specs-semconv-maintainers)): -- [Armin Ruech](https://github.com/arminru) -- [Josh Suereth](https://github.com/jsuereth) -- [Reiley Yang](https://github.com/reyang) +- [Armin Ruech](https://github.com/arminru), Dynatrace +- [Joao Grassi](https://github.com/joaopgrassi), Dynatrace +- [Josh Suereth](https://github.com/jsuereth), Google +- [Reiley Yang](https://github.com/reyang), Microsoft _Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)._ From 313092ccf180c6e4e178587aa5391954bb36ed09 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 10 Aug 2023 09:56:09 -0700 Subject: [PATCH 017/482] Update destination attribute briefs (#243) --- docs/general/attributes.md | 4 ++-- model/destination.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 13e98d5595..289badc7cd 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -221,8 +221,8 @@ Destination fields capture details about the receiver of a network exchange/pack | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `destination.domain` | string | The domain name of the destination system. [1] | `foo.example.com` | Recommended | -| `destination.address` | string | Peer address, for example IP address or UNIX socket name. | `10.5.3.2` | Recommended | -| `destination.port` | int | Peer port number | `3389`; `2888` | Recommended | +| `destination.address` | string | Destination address, for example IP address or UNIX socket name. | `10.5.3.2` | Recommended | +| `destination.port` | int | Destination port number | `3389`; `2888` | Recommended | **[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. diff --git a/model/destination.yaml b/model/destination.yaml index 2df72bd9f3..a2fd8fd65f 100644 --- a/model/destination.yaml +++ b/model/destination.yaml @@ -16,9 +16,9 @@ groups: note: This value may be a host name, a fully qualified domain name, or another host naming format. - id: address type: string - brief: 'Peer address, for example IP address or UNIX socket name.' + brief: 'Destination address, for example IP address or UNIX socket name.' examples: ['10.5.3.2'] - id: port type: int - brief: 'Peer port number' + brief: 'Destination port number' examples: [3389, 2888] From d5b8de488c46ae5424fd1c519fdd784edf99ef65 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 10 Aug 2023 14:23:48 -0700 Subject: [PATCH 018/482] Rename all JVM metrics from process.runtime.jvm.* to jvm.* (#241) --- CHANGELOG.md | 2 + docs/system/runtime-environment-metrics.md | 174 +++++++++--------- ...cess-runtime-jvm-metrics-experimental.yaml | 34 ++-- .../metrics/process-runtime-jvm-metrics.yaml | 54 +++--- schema-next.yaml | 19 ++ 5 files changed, 152 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2009f95066..9089400e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ release. ([#88](https://github.com/open-telemetry/semantic-conventions/pull/88)) The conventions cover metrics that are recorded by the FaaS itself and not by clients invoking them. +- BREAKING: Rename all JVM metrics from `process.runtime.jvm.*` to `jvm.*` + ([#241](https://github.com/open-telemetry/semantic-conventions/pull/241)) ## v1.21.0 (2023-07-13) diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index 280450102c..03f338b881 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -20,24 +20,24 @@ semantic conventions when instrumenting runtime environments. * [Runtime Environment Specific Metrics - `process.runtime.{environment}.`](#runtime-environment-specific-metrics---processruntimeenvironment) - [Attributes](#attributes) - [JVM Metrics](#jvm-metrics) - * [Metric: `process.runtime.jvm.memory.usage`](#metric-processruntimejvmmemoryusage) - * [Metric: `process.runtime.jvm.memory.committed`](#metric-processruntimejvmmemorycommitted) - * [Metric: `process.runtime.jvm.memory.limit`](#metric-processruntimejvmmemorylimit) - * [Metric: `process.runtime.jvm.memory.usage_after_last_gc`](#metric-processruntimejvmmemoryusage_after_last_gc) - * [Metric: `process.runtime.jvm.gc.duration`](#metric-processruntimejvmgcduration) - * [Metric: `process.runtime.jvm.threads.count`](#metric-processruntimejvmthreadscount) - * [Metric: `process.runtime.jvm.classes.loaded`](#metric-processruntimejvmclassesloaded) - * [Metric: `process.runtime.jvm.classes.unloaded`](#metric-processruntimejvmclassesunloaded) - * [Metric: `process.runtime.jvm.classes.current_loaded`](#metric-processruntimejvmclassescurrent_loaded) - * [Metric: `process.runtime.jvm.cpu.time`](#metric-processruntimejvmcputime) - * [Metric: `process.runtime.jvm.cpu.recent_utilization`](#metric-processruntimejvmcpurecent_utilization) + * [Metric: `jvm.memory.usage`](#metric-jvmmemoryusage) + * [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) + * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) + * [Metric: `jvm.memory.usage_after_last_gc`](#metric-jvmmemoryusage_after_last_gc) + * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) + * [Metric: `jvm.threads.count`](#metric-jvmthreadscount) + * [Metric: `jvm.classes.loaded`](#metric-jvmclassesloaded) + * [Metric: `jvm.classes.unloaded`](#metric-jvmclassesunloaded) + * [Metric: `jvm.classes.current_loaded`](#metric-jvmclassescurrent_loaded) + * [Metric: `jvm.cpu.time`](#metric-jvmcputime) + * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) - [JVM Metrics (Experimental)](#jvm-metrics-experimental) - * [Metric: `process.runtime.jvm.memory.init`](#metric-processruntimejvmmemoryinit) - * [Metric: `process.runtime.jvm.system.cpu.utilization`](#metric-processruntimejvmsystemcpuutilization) - * [Metric: `process.runtime.jvm.system.cpu.load_1m`](#metric-processruntimejvmsystemcpuload_1m) - * [Metric: `process.runtime.jvm.buffer.usage`](#metric-processruntimejvmbufferusage) - * [Metric: `process.runtime.jvm.buffer.limit`](#metric-processruntimejvmbufferlimit) - * [Metric: `process.runtime.jvm.buffer.count`](#metric-processruntimejvmbuffercount) + * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) + * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) + * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) + * [Metric: `jvm.buffer.usage`](#metric-jvmbufferusage) + * [Metric: `jvm.buffer.limit`](#metric-jvmbufferlimit) + * [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) @@ -75,20 +75,20 @@ consider, for example pthreads vs green thread implementations. ## JVM Metrics -**Description:** Java Virtual Machine (JVM) metrics captured under `process.runtime.jvm.` +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.` -### Metric: `process.runtime.jvm.memory.usage` +### Metric: `jvm.memory.usage` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.memory.usage` | UpDownCounter | `By` | Measure of memory used. | +| `jvm.memory.usage` | UpDownCounter | `By` | Measure of memory used. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | @@ -104,18 +104,18 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | `non_heap` | Non-heap memory | -### Metric: `process.runtime.jvm.memory.committed` +### Metric: `jvm.memory.committed` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | +| `jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | @@ -131,18 +131,18 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | `non_heap` | Non-heap memory | -### Metric: `process.runtime.jvm.memory.limit` +### Metric: `jvm.memory.limit` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | +| `jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | @@ -158,18 +158,18 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | `non_heap` | Non-heap memory | -### Metric: `process.runtime.jvm.memory.usage_after_last_gc` +### Metric: `jvm.memory.usage_after_last_gc` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getCollectionUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.memory.usage_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | +| `jvm.memory.usage_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | @@ -185,7 +185,7 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | `non_heap` | Non-heap memory | -### Metric: `process.runtime.jvm.gc.duration` +### Metric: `jvm.gc.duration` This metric is [recommended][MetricRecommended]. This metric is obtained by subscribing to @@ -195,13 +195,13 @@ This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) of `[]` (single bucket histogram capturing count, sum, min, max). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | +| `jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `gc` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | @@ -212,117 +212,117 @@ of `[]` (single bucket histogram capturing count, sum, min, max). **[2]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). -### Metric: `process.runtime.jvm.threads.count` +### Metric: `jvm.threads.count` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ThreadMXBean#getDaemonThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getDaemonThreadCount--) and [`ThreadMXBean#getThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadCount--). Note that this is the number of platform threads (as opposed to virtual threads). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.threads.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | +| `jvm.threads.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `daemon` | boolean | Whether the thread is daemon or not. | | Recommended | -### Metric: `process.runtime.jvm.classes.loaded` +### Metric: `jvm.classes.loaded` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getTotalLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getTotalLoadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.classes.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | +| `jvm.classes.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | - + -### Metric: `process.runtime.jvm.classes.unloaded` +### Metric: `jvm.classes.unloaded` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getUnloadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.classes.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | +| `jvm.classes.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | - + -### Metric: `process.runtime.jvm.classes.current_loaded` +### Metric: `jvm.classes.current_loaded` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.classes.current_loaded` | UpDownCounter | `{class}` | Number of classes currently loaded. | +| `jvm.classes.current_loaded` | UpDownCounter | `{class}` | Number of classes currently loaded. | - + -### Metric: `process.runtime.jvm.cpu.time` +### Metric: `jvm.cpu.time` This metric is [recommended][MetricRecommended]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuTime()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuTime()) on HotSpot and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on J9. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | +| `jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | - + -### Metric: `process.runtime.jvm.cpu.recent_utilization` +### Metric: `jvm.cpu.recent_utilization` This metric is [recommended][MetricRecommended]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()) on HotSpot and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuLoad--) on J9. Note that the JVM does not provide a definition of what "recent" means. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | +| `jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | **[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). - + ## JVM Metrics (Experimental) -**Description:** Experimental Java Virtual Machine (JVM) metrics captured under `process.runtime.jvm.` +**Description:** Experimental Java Virtual Machine (JVM) metrics captured under `jvm.` -### Metric: `process.runtime.jvm.memory.init` +### Metric: `jvm.memory.init` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | +| `jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | @@ -338,51 +338,51 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | `non_heap` | Non-heap memory | -### Metric: `process.runtime.jvm.system.cpu.utilization` +### Metric: `jvm.system.cpu.utilization` This metric is [Opt-In][MetricOptIn]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getSystemCpuLoad()) on Java version 8..13, [`com.sun.management.OperatingSystemMXBean#getCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()) on Java version 14+, and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on J9. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | +| `jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | **[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()). - + -### Metric: `process.runtime.jvm.system.cpu.load_1m` +### Metric: `jvm.system.cpu.load_1m` This metric is [Opt-In][MetricOptIn]. This metric is obtained from [`OperatingSystemMXBean#getSystemLoadAverage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | +| `jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | **[1]:** The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage()). - + -### Metric: `process.runtime.jvm.buffer.usage` +### Metric: `jvm.buffer.usage` This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getMemoryUsed--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.buffer.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | +| `jvm.buffer.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | @@ -390,18 +390,18 @@ This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.o **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). -### Metric: `process.runtime.jvm.buffer.limit` +### Metric: `jvm.buffer.limit` This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getTotalCapacity--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.buffer.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | +| `jvm.buffer.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | @@ -409,18 +409,18 @@ This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://doc **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). -### Metric: `process.runtime.jvm.buffer.count` +### Metric: `jvm.buffer.count` This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `process.runtime.jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | +| `jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | diff --git a/model/metrics/process-runtime-jvm-metrics-experimental.yaml b/model/metrics/process-runtime-jvm-metrics-experimental.yaml index 3956368631..06c8090838 100644 --- a/model/metrics/process-runtime-jvm-metrics-experimental.yaml +++ b/model/metrics/process-runtime-jvm-metrics-experimental.yaml @@ -1,15 +1,15 @@ groups: - - id: metric.process.runtime.jvm.memory.init + - id: metric.jvm.memory.init type: metric - metric_name: process.runtime.jvm.memory.init - extends: attributes.process.runtime.jvm.memory + metric_name: jvm.memory.init + extends: attributes.jvm.memory brief: "Measure of initial memory requested." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.system.cpu.utilization + - id: metric.jvm.system.cpu.utilization type: metric - metric_name: process.runtime.jvm.system.cpu.utilization + metric_name: jvm.system.cpu.utilization brief: "Recent CPU utilization for the whole system as reported by the JVM." note: > The value range is [0.0,1.0]. @@ -19,9 +19,9 @@ groups: instrument: gauge unit: "1" - - id: metric.process.runtime.jvm.system.cpu.load_1m + - id: metric.jvm.system.cpu.load_1m type: metric - metric_name: process.runtime.jvm.system.cpu.load_1m + metric_name: jvm.system.cpu.load_1m brief: "Average CPU load of the whole system for the last minute as reported by the JVM." note: > The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. @@ -31,7 +31,7 @@ groups: instrument: gauge unit: "{run_queue_item}" - - id: attributes.process.runtime.jvm.buffer + - id: attributes.jvm.buffer type: attribute_group brief: "Describes JVM buffer metric attributes." attributes: @@ -42,26 +42,26 @@ groups: Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - - id: metric.process.runtime.jvm.buffer.usage + - id: metric.jvm.buffer.usage type: metric - metric_name: process.runtime.jvm.buffer.usage - extends: attributes.process.runtime.jvm.buffer + metric_name: jvm.buffer.usage + extends: attributes.jvm.buffer brief: "Measure of memory used by buffers." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.buffer.limit + - id: metric.jvm.buffer.limit type: metric - metric_name: process.runtime.jvm.buffer.limit - extends: attributes.process.runtime.jvm.buffer + metric_name: jvm.buffer.limit + extends: attributes.jvm.buffer brief: "Measure of total memory capacity of buffers." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.buffer.count + - id: metric.jvm.buffer.count type: metric - metric_name: process.runtime.jvm.buffer.count - extends: attributes.process.runtime.jvm.buffer + metric_name: jvm.buffer.count + extends: attributes.jvm.buffer brief: "Number of buffers in the pool." instrument: updowncounter unit: "{buffer}" diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/process-runtime-jvm-metrics.yaml index 1721b8e956..b08c3f72d5 100644 --- a/model/metrics/process-runtime-jvm-metrics.yaml +++ b/model/metrics/process-runtime-jvm-metrics.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.process.runtime.jvm.memory + - id: attributes.jvm.memory type: attribute_group brief: "Describes JVM memory metric attributes." attributes: @@ -25,41 +25,41 @@ groups: Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - - id: metric.process.runtime.jvm.memory.usage + - id: metric.jvm.memory.usage type: metric - metric_name: process.runtime.jvm.memory.usage - extends: attributes.process.runtime.jvm.memory + metric_name: jvm.memory.usage + extends: attributes.jvm.memory brief: "Measure of memory used." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.memory.committed + - id: metric.jvm.memory.committed type: metric - metric_name: process.runtime.jvm.memory.committed - extends: attributes.process.runtime.jvm.memory + metric_name: jvm.memory.committed + extends: attributes.jvm.memory brief: "Measure of memory committed." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.memory.limit + - id: metric.jvm.memory.limit type: metric - metric_name: process.runtime.jvm.memory.limit - extends: attributes.process.runtime.jvm.memory + metric_name: jvm.memory.limit + extends: attributes.jvm.memory brief: "Measure of max obtainable memory." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.memory.usage_after_last_gc + - id: metric.jvm.memory.usage_after_last_gc type: metric - metric_name: process.runtime.jvm.memory.usage_after_last_gc - extends: attributes.process.runtime.jvm.memory + metric_name: jvm.memory.usage_after_last_gc + extends: attributes.jvm.memory brief: "Measure of memory used, as measured after the most recent garbage collection event on this pool." instrument: updowncounter unit: "By" - - id: metric.process.runtime.jvm.gc.duration + - id: metric.jvm.gc.duration type: metric - metric_name: process.runtime.jvm.gc.duration + metric_name: jvm.gc.duration brief: "Duration of JVM garbage collection actions." instrument: histogram unit: "s" @@ -81,9 +81,9 @@ groups: Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). - - id: metric.process.runtime.jvm.threads.count + - id: metric.jvm.threads.count type: metric - metric_name: process.runtime.jvm.threads.count + metric_name: jvm.threads.count brief: "Number of executing platform threads." instrument: updowncounter unit: "{thread}" @@ -93,37 +93,37 @@ groups: type: boolean requirement_level: recommended - - id: metric.process.runtime.jvm.classes.loaded + - id: metric.jvm.classes.loaded type: metric - metric_name: process.runtime.jvm.classes.loaded + metric_name: jvm.classes.loaded brief: "Number of classes loaded since JVM start." instrument: counter unit: "{class}" - - id: metric.process.runtime.jvm.classes.unloaded + - id: metric.jvm.classes.unloaded type: metric - metric_name: process.runtime.jvm.classes.unloaded + metric_name: jvm.classes.unloaded brief: "Number of classes unloaded since JVM start." instrument: counter unit: "{class}" - - id: metric.process.runtime.jvm.classes.current_loaded + - id: metric.jvm.classes.current_loaded type: metric - metric_name: process.runtime.jvm.classes.current_loaded + metric_name: jvm.classes.current_loaded brief: "Number of classes currently loaded." instrument: updowncounter unit: "{class}" - - id: metric.process.runtime.jvm.cpu.time + - id: metric.jvm.cpu.time type: metric - metric_name: process.runtime.jvm.cpu.time + metric_name: jvm.cpu.time brief: "CPU time used by the process as reported by the JVM." instrument: counter unit: "s" - - id: metric.process.runtime.jvm.cpu.recent_utilization + - id: metric.jvm.cpu.recent_utilization type: metric - metric_name: process.runtime.jvm.cpu.recent_utilization + metric_name: jvm.cpu.recent_utilization brief: "Recent CPU utilization for the process as reported by the JVM." note: > The value range is [0.0,1.0]. diff --git a/schema-next.yaml b/schema-next.yaml index 14e82faac1..612200a0bc 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -8,6 +8,25 @@ versions: - rename_metrics: http.client.duration: http.client.request.duration http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + process.runtime.jvm.threads.count: jvm.threads.count + process.runtime.jvm.classes.loaded: jvm.classes.loaded + process.runtime.jvm.classes.unloaded: jvm.classes.unloaded + process.runtime.jvm.classes.current_loaded: jvm.classes.current_loaded + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + process.runtime.jvm.buffer.usage: jvm.buffer.usage + process.runtime.jvm.buffer.limit: jvm.buffer.limit + process.runtime.jvm.buffer.count: jvm.buffer.count 1.21.0: spans: changes: From a0143da118e7ddc48062ac11133ee39821d56edd Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 14 Aug 2023 09:02:04 -0700 Subject: [PATCH 019/482] Improve symmetry in client/server address/port text (#244) --- docs/database/database-spans.md | 21 ++++++++--- docs/database/elasticsearch.md | 13 ++++--- docs/general/attributes.md | 41 ++++++++++++++------- docs/http/http-metrics.md | 15 ++++++-- docs/http/http-spans.md | 60 ++++++++++++++++++++----------- docs/messaging/messaging-spans.md | 18 ++++++---- docs/rpc/rpc-metrics.md | 16 ++++++--- docs/rpc/rpc-spans.md | 36 +++++++++++++------ model/client.yaml | 20 +++++++---- model/server.yaml | 26 ++++++++++---- 10 files changed, 187 insertions(+), 79 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 9c60f6001e..2de954defa 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,12 +67,23 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the database host. | `example.com` | Conditionally Required: See alternative attributes below. | -| [`server.port`](../general/attributes.md) | int | Logical server port number | `80`; `8080`; `443` | Conditionally Required: [1] | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Physical server port. | `16456` | Recommended: If different than `server.port`. | +| [`server.address`](../general/attributes.md) | string | Name of the database host. [1] | `example.com` | Conditionally Required: See alternative attributes below. | +| [`server.port`](../general/attributes.md) | int | Server port number [2] | `80`; `8080`; `443` | Conditionally Required: [3] | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [4] | `10.5.3.2` | See below | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [5] | `16456` | Recommended: If different than `server.port`. | -**[1]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +the server address behind any intermediaries (e.g. proxies) if it's available. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[3]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[4]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + +**[5]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index bf1aa46360..58bbc5bb6f 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -40,9 +40,9 @@ in order to map the path part values to their names. | [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [1] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [2] | | `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Logical server hostname, matches server FQDN if available, and IP or socket address if FQDN is not known. | `example.com` | See below | -| [`server.port`](../general/attributes.md) | int | Logical server port number | `80`; `8080`; `443` | Recommended | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [4] | `example.com` | See below | +| [`server.port`](../general/attributes.md) | int | Server port number [5] | `80`; `8080`; `443` | Recommended | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [6] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. @@ -64,7 +64,12 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +the server address behind any intermediaries (e.g. proxies) if it's available. + +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[6]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 289badc7cd..6c4c8d321f 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -55,13 +55,24 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `server.address` | string | Logical server hostname, matches server FQDN if available, and IP or socket address if FQDN is not known. | `example.com` | Recommended | -| `server.port` | int | Logical server port number | `80`; `8080`; `443` | Recommended | -| `server.socket.domain` | string | The domain name of an immediate peer. [1] | `proxy.example.com` | Recommended: If different than `server.address`. | -| `server.socket.address` | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | -| `server.socket.port` | int | Physical server port. | `16456` | Recommended: If different than `server.port`. | +| `server.address` | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `example.com` | Recommended | +| `server.port` | int | Server port number [2] | `80`; `8080`; `443` | Recommended | +| `server.socket.domain` | string | Immediate server peer's domain name if available without reverse DNS lookup [3] | `proxy.example.com` | Recommended: If different than `server.address`. | +| `server.socket.address` | string | Server address of the socket connection - IP address or Unix domain socket name. [4] | `10.5.3.2` | Recommended: If different than `server.address`. | +| `server.socket.port` | int | Server port number of the socket connection. [5] | `16456` | Recommended: If different than `server.port`. | -**[1]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +the server address behind any intermediaries (e.g. proxies) if it's available. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[3]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. + +**[4]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + +**[5]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. `server.address` and `server.port` represent logical server name and port. Semantic conventions that refer to these attributes SHOULD @@ -117,14 +128,20 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | Client address - unix domain socket name, IPv4 or IPv6 address. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | -| `client.port` | int | Client port number [2] | `65123` | Recommended | -| `client.socket.address` | string | Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| `client.socket.port` | int | Immediate client peer port number | `35555` | Recommended: If different than `client.port`. | +| `client.address` | string | Client address - IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| `client.port` | int | Client port number. [2] | `65123` | Recommended | +| `client.socket.address` | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | +| `client.socket.port` | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | + +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. + +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent client address behind any intermediaries (e.g. proxies) if it's available. +**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. +When observed from the client side, this SHOULD represent the physical client address. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent client port behind any intermediaries (e.g. proxies) if it's available. +**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. +When observed from the client side, this SHOULD represent the physical client port. `client.socket.address` and `client.socket.port` represent physical client name and port. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index fe9c4da823..e532b10307 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -391,7 +391,7 @@ of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -423,6 +423,9 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + `http.request.method` 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 | @@ -460,7 +463,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -492,6 +495,9 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + `http.request.method` 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 | @@ -529,7 +535,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -561,6 +567,9 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + `http.request.method` 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 | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index dd15d32552..b16b5caa5d 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -199,10 +199,10 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | `http.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | | [`server.address`](../general/attributes.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 | | [`server.port`](../general/attributes.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] | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | The domain name of an immediate peer. [5] | `proxy.example.com` | Recommended: If different than `server.address`. | -| [`server.socket.port`](../general/attributes.md) | int | Physical server port. | `16456` | Recommended: If different than `server.port`. | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [6] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [6] | `proxy.example.com` | Recommended: If different than `server.address`. | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [7] | `16456` | Recommended: If different than `server.port`. | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [8] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | **[1]:** 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). @@ -219,9 +219,15 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. **[4]:** If not default (`80` for `http` scheme, `443` for `https`). -**[5]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. +**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. -**[6]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[6]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. + +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. + +**[8]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. @@ -327,16 +333,16 @@ If the route cannot be determined, the `name` attribute MUST be set as defined i | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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 | -| [`client.address`](../general/attributes.md) | string | Client address - unix domain socket name, IPv4 or IPv6 address. [2] | `83.164.160.102` | Recommended | +| [`client.address`](../general/attributes.md) | string | Client address - IP address or Unix domain socket name. [2] | `83.164.160.102` | Recommended | | [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [3] | `65123` | Recommended | -| [`client.socket.address`](../general/attributes.md) | string | Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| [`client.socket.port`](../general/attributes.md) | int | Immediate client peer port number | `35555` | Recommended: If different than `client.port`. | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Recommended: [6] | -| [`server.socket.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.5.3.2` | Opt-In | -| [`server.socket.port`](../general/attributes.md) | int | Local socket port. Useful in case of a multi-port host. | `16456` | Opt-In | -| [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | -| [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [4] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | +| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [5] | `35555` | Recommended: If different than `client.port`. | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Recommended | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Recommended: [8] | +| [`server.socket.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. [9] | `10.5.3.2` | Opt-In | +| [`server.socket.port`](../general/attributes.md) | int | Local socket port. Useful in case of a multi-port host. [10] | `16456` | Opt-In | +| [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [11] | `/search` | Required | +| [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [12] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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. @@ -344,9 +350,15 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[2]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[3]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent client port behind any intermediaries (e.g. proxies) if it's available. +**[3]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. + +**[4]:** When observed from the server side, this SHOULD represent the immediate client peer address. +When observed from the client side, this SHOULD represent the physical client address. -**[4]:** Determined by using the first of the following that applies +**[5]:** When observed from the server side, this SHOULD represent the immediate client peer port. +When observed from the client side, this SHOULD represent the physical client port. + +**[6]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -356,18 +368,24 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[5]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 -**[6]:** If not default (`80` for `http` scheme, `443` for `https`). +**[8]:** If not default (`80` for `http` scheme, `443` for `https`). + +**[9]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + +**[10]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. -**[7]:** When missing, the value is assumed to be `/` +**[11]:** When missing, the value is assumed to be `/` -**[8]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[12]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index a8a642acff..72179fd6ce 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -231,10 +231,10 @@ The following operations related to messages are defined for these semantic conv | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [14] | `3.1.1` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Logical server hostname, matches server FQDN if available, and IP or socket address if FQDN is not known. [15] | `example.com` | Conditionally Required: If available. | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | The domain name of an immediate peer. [16] | `proxy.example.com` | Recommended: [17] | -| [`server.socket.port`](../general/attributes.md) | int | Physical server port. | `16456` | Recommended: If different than `server.port`. | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [15] | `example.com` | Conditionally Required: If available. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [16] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [17] | `proxy.example.com` | Recommended: [18] | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [19] | `16456` | Recommended: If different than `server.port`. | **[1]:** If a custom value is used, it MUST be of low cardinality. @@ -267,9 +267,15 @@ the broker does not have such notion, the destination name SHOULD uniquely ident **[15]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. -**[16]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. +**[16]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. -**[17]:** If different than `server.address` and if `server.socket.address` is set. +**[17]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. + +**[18]:** If different than `server.address` and if `server.socket.address` is set. + +**[19]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. `messaging.operation` 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. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 98d444be96..6cb5768f3d 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -196,9 +196,9 @@ measurements. | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Logical server port number | `80`; `8080`; `443` | Conditionally Required: See below | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Physical server port. | `16456` | Recommended: [4] | +| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | See below | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [6] | `16456` | Recommended: [7] | **[1]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). @@ -206,7 +206,15 @@ measurements. **[3]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[4]:** If different than `server.port` and if `server.socket.address` is set. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. + +**[7]:** If different than `server.port` and if `server.socket.address` is set. **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index c86dfc3cac..c82bfa02f4 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -89,9 +89,9 @@ Examples of span names: | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Logical server port number | `80`; `8080`; `443` | Conditionally Required: See below | -| [`server.socket.address`](../general/attributes.md) | string | Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Physical server port. | `16456` | Recommended: [4] | +| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | See below | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [6] | `16456` | Recommended: [7] | **[1]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). @@ -99,7 +99,15 @@ Examples of span names: **[3]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[4]:** If different than `server.port` and if `server.socket.address` is set. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. +When observed from the server side, this SHOULD represent the physical server address. + +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer port. +When observed from the server side, this SHOULD represent the physical server port. + +**[7]:** If different than `server.port` and if `server.socket.address` is set. **Additional attribute requirements:** At least one of the following sets of attributes is required: @@ -139,7 +147,7 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`server.socket.domain`](../general/attributes.md) | string | The domain name of an immediate peer. [1] | `proxy.example.com` | Recommended: [2] | +| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [1] | `proxy.example.com` | Recommended: [2] | **[1]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. @@ -151,16 +159,22 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - unix domain socket name, IPv4 or IPv6 address. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | -| [`client.port`](../general/attributes.md) | int | Client port number [2] | `65123` | Recommended | -| [`client.socket.address`](../general/attributes.md) | string | Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| [`client.socket.port`](../general/attributes.md) | int | Immediate client peer port number | `35555` | Recommended: If different than `client.port`. | +| [`client.address`](../general/attributes.md) | string | Client address - IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | +| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | +| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent client address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. + +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. + +**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. +When observed from the client side, this SHOULD represent the physical client address. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent client port behind any intermediaries (e.g. proxies) if it's available. +**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. +When observed from the client side, this SHOULD represent the physical client port. ### Events diff --git a/model/client.yaml b/model/client.yaml index 1b54ced8cc..51fbb636f2 100644 --- a/model/client.yaml +++ b/model/client.yaml @@ -12,27 +12,35 @@ groups: attributes: - id: address type: string - brief: Client address - unix domain socket name, IPv4 or IPv6 address. + brief: Client address - IP address or Unix domain socket name. note: > When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent - client address behind any intermediaries (e.g. proxies) if it's available. + the client address behind any intermediaries (e.g. proxies) if it's available. examples: ['/tmp/my.sock', '10.1.2.80'] - id: port type: int - brief: 'Client port number' + brief: Client port number. examples: [65123] note: > When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent - client port behind any intermediaries (e.g. proxies) if it's available. + the client port behind any intermediaries (e.g. proxies) if it's available. - id: socket.address type: string - brief: Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. + brief: Client address of the socket connection - IP address or Unix domain socket name. + note: > + When observed from the server side, this SHOULD represent the immediate client peer address. + + When observed from the client side, this SHOULD represent the physical client address. examples: ['/tmp/my.sock', '127.0.0.1'] requirement_level: recommended: If different than `client.address`. - id: socket.port type: int - brief: 'Immediate client peer port number' + brief: Client port number of the socket connection. + note: > + When observed from the server side, this SHOULD represent the immediate client peer port. + + When observed from the client side, this SHOULD represent the physical client port. examples: [35555] requirement_level: recommended: If different than `client.port`. diff --git a/model/server.yaml b/model/server.yaml index 3aa189e249..aed9184905 100644 --- a/model/server.yaml +++ b/model/server.yaml @@ -12,30 +12,42 @@ groups: attributes: - id: address type: string - brief: 'Logical server hostname, matches server FQDN if available, and IP or socket address if FQDN is not known.' + brief: Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + note: | + When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent + the server address behind any intermediaries (e.g. proxies) if it's available. examples: ['example.com'] - id: port type: int - brief: 'Logical server port number' + brief: Server port number + note: > + When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent + the server port behind any intermediaries (e.g. proxies) if it's available. examples: [80, 8080, 443] - id: socket.domain type: string - brief: The domain name of an immediate peer. + brief: Immediate server peer's domain name if available without reverse DNS lookup examples: ['proxy.example.com'] note: Typically observed from the client side, and represents a proxy or other intermediary domain name. requirement_level: recommended: If different than `server.address`. - id: socket.address type: string - brief: > - Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from - client, this may represent some proxy server instead of the logical server). + brief: Server address of the socket connection - IP address or Unix domain socket name. + note: > + When observed from the client side, this SHOULD represent the immediate server peer address. + + When observed from the server side, this SHOULD represent the physical server address. examples: ['10.5.3.2'] requirement_level: recommended: If different than `server.address`. - id: socket.port type: int - brief: Physical server port. + brief: Server port number of the socket connection. + note: > + When observed from the client side, this SHOULD represent the immediate server peer port. + + When observed from the server side, this SHOULD represent the physical server port. examples: [16456] requirement_level: recommended: If different than `server.port`. From 2927d5809bb68765ee39e263fcfb93d1e77d1620 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 14 Aug 2023 22:35:25 +0200 Subject: [PATCH 020/482] add namespace to jvm metric attributes (#20) --- CHANGELOG.md | 19 +++++++++ docs/general/attributes.md | 1 + docs/system/runtime-environment-metrics.md | 42 +++++++++---------- ...cess-runtime-jvm-metrics-experimental.yaml | 5 ++- .../metrics/process-runtime-jvm-metrics.yaml | 10 ++--- model/trace/general.yaml | 3 ++ schema-next.yaml | 29 +++++++++++++ 7 files changed, 82 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9089400e69..d22fd89a75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,25 @@ release. clients invoking them. - BREAKING: Rename all JVM metrics from `process.runtime.jvm.*` to `jvm.*` ([#241](https://github.com/open-telemetry/semantic-conventions/pull/241)) +- BREAKING: Add namespaces to JVM metric attributes ([#20](https://github.com/open-telemetry/semantic-conventions/pull/20)). + - Rename attributes `type` to `jvm.memory.type`, `pool` to `jvm.memory.pool.name` + - Applies to metrics: + - `jvm.memory.usage` + - `jvm.memory.init` + - `jvm.memory.committed` + - `jvm.memory.limit` + - `jvm.memory.usage_after_last_gc` + - Rename attributes `gc` to `jvm.gc.name`, `action` to `jvm.gc.action` + - Applies to metrics: + - `jvm.gc.duration` + - Rename attribute `daemon` to `thread.daemon` + - Applies to metrics: + - `jvm.threads.count` + - Rename attribute `pool` to `jvm.buffer.pool.name` + - Applies to metrics: + - `jvm.buffer.usage` + - `jvm.buffer.limit` + - `jvm.buffer.count` ## v1.21.0 (2023-07-13) diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 6c4c8d321f..b1bc6e0ff6 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -368,6 +368,7 @@ a thread that started a span. |---|---|---|---|---| | `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | | `thread.name` | string | Current thread name. | `main` | Recommended | +| `thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | Examples of where `thread.id` and `thread.name` can be extracted from: diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index 03f338b881..c0843daf01 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -91,12 +91,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `pool` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`type` MUST be one of the following: +`jvm.memory.type` MUST be one of the following: | Value | Description | |---|---| @@ -118,12 +118,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `pool` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`type` MUST be one of the following: +`jvm.memory.type` MUST be one of the following: | Value | Description | |---|---| @@ -145,12 +145,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `pool` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`type` MUST be one of the following: +`jvm.memory.type` MUST be one of the following: | Value | Description | |---|---| @@ -172,12 +172,12 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `pool` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`type` MUST be one of the following: +`jvm.memory.type` MUST be one of the following: | Value | Description | |---|---| @@ -204,8 +204,8 @@ of `[]` (single bucket histogram capturing count, sum, min, max). | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `gc` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | -| `action` | string | Name of the garbage collector action. [2] | `end of minor GC`; `end of major GC` | Recommended | +| `jvm.gc.name` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | +| `jvm.gc.action` | string | Name of the garbage collector action. [2] | `end of minor GC`; `end of major GC` | Recommended | **[1]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). @@ -228,7 +228,7 @@ Note that this is the number of platform threads (as opposed to virtual threads) | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `daemon` | boolean | Whether the thread is daemon or not. | | Recommended | +| [`thread.daemon`](../general/attributes.md) | boolean | Whether the thread is daemon or not. | | Recommended | ### Metric: `jvm.classes.loaded` @@ -325,12 +325,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `pool` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`type` MUST be one of the following: +`jvm.memory.type` MUST be one of the following: | Value | Description | |---|---| @@ -385,7 +385,7 @@ This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.o | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -404,7 +404,7 @@ This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://doc | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -423,7 +423,7 @@ This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). diff --git a/model/metrics/process-runtime-jvm-metrics-experimental.yaml b/model/metrics/process-runtime-jvm-metrics-experimental.yaml index 06c8090838..da74d34423 100644 --- a/model/metrics/process-runtime-jvm-metrics-experimental.yaml +++ b/model/metrics/process-runtime-jvm-metrics-experimental.yaml @@ -34,8 +34,11 @@ groups: - id: attributes.jvm.buffer type: attribute_group brief: "Describes JVM buffer metric attributes." + prefix: jvm.buffer attributes: - - ref: pool + - id: pool.name + type: string + requirement_level: recommended brief: Name of the buffer pool. examples: [ "mapped", "direct" ] note: > diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/process-runtime-jvm-metrics.yaml index b08c3f72d5..d6b4c502a8 100644 --- a/model/metrics/process-runtime-jvm-metrics.yaml +++ b/model/metrics/process-runtime-jvm-metrics.yaml @@ -2,6 +2,7 @@ groups: - id: attributes.jvm.memory type: attribute_group brief: "Describes JVM memory metric attributes." + prefix: jvm.memory attributes: - id: type type: @@ -16,7 +17,7 @@ groups: requirement_level: recommended brief: The type of memory. examples: ["heap", "non_heap"] - - id: pool + - id: pool.name type: string requirement_level: recommended brief: Name of the memory pool. @@ -63,8 +64,9 @@ groups: brief: "Duration of JVM garbage collection actions." instrument: histogram unit: "s" + prefix: jvm.gc attributes: - - id: gc + - id: name type: string requirement_level: recommended brief: Name of the garbage collector. @@ -88,9 +90,7 @@ groups: instrument: updowncounter unit: "{thread}" attributes: - - id: daemon - brief: "Whether the thread is daemon or not." - type: boolean + - ref: thread.daemon requirement_level: recommended - id: metric.jvm.classes.loaded diff --git a/model/trace/general.yaml b/model/trace/general.yaml index 545bce5cab..478937c110 100644 --- a/model/trace/general.yaml +++ b/model/trace/general.yaml @@ -215,6 +215,9 @@ groups: brief: > Current thread name. examples: main + - id: daemon + brief: "Whether the thread is daemon or not." + type: boolean - id: code prefix: code type: span diff --git a/schema-next.yaml b/schema-next.yaml index 612200a0bc..e19ff8a65e 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -27,6 +27,35 @@ versions: process.runtime.jvm.buffer.usage: jvm.buffer.usage process.runtime.jvm.buffer.limit: jvm.buffer.limit process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.usage + - jvm.buffer.limit + - jvm.buffer.count 1.21.0: spans: changes: From 2cfb136715fe453591c4b2556552e75e1e5ea0d2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 14 Aug 2023 13:53:40 -0700 Subject: [PATCH 021/482] Remove unnecessary portion of http.request.method note (#248) --- docs/database/elasticsearch.md | 3 +-- docs/http/http-metrics.md | 21 +++++++-------------- docs/http/http-spans.md | 3 +-- model/http-common.yaml | 3 +-- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 58bbc5bb6f..ae329f7e5e 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -52,8 +52,7 @@ in order to map the path part values to their names. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e532b10307..c70d6fdfde 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -90,8 +90,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -161,8 +160,7 @@ This metric is optional. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -237,8 +235,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -315,8 +312,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -397,8 +393,7 @@ of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -469,8 +464,7 @@ This metric is optional. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named @@ -541,8 +535,7 @@ This metric is optional. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index b16b5caa5d..eb058e928e 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -112,8 +112,7 @@ sections below. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST -set the exact method received in the request line as value of the `http.request.method_original` attribute. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named diff --git a/model/http-common.yaml b/model/http-common.yaml index 9db84ce583..2b481800e1 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -46,8 +46,7 @@ groups: By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST - set the exact method received in the request line as value of the `http.request.method_original` attribute. + If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named From 728c3ca60db2fcd6e53767b859695b04e9714eff Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 14 Aug 2023 13:58:21 -0700 Subject: [PATCH 022/482] `http/dup` has higher precedence than `http` in `OTEL_SEMCONV_STABILITY_OPT_IN` (#249) --- CHANGELOG.md | 3 +++ docs/database/database-spans.md | 1 + docs/http/README.md | 1 + docs/http/http-metrics.md | 1 + docs/http/http-spans.md | 1 + docs/messaging/messaging-spans.md | 1 + docs/rpc/rpc-metrics.md | 1 + docs/rpc/rpc-spans.md | 1 + 8 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d22fd89a75..c8c5f52301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,9 @@ release. - `jvm.buffer.usage` - `jvm.buffer.limit` - `jvm.buffer.count` +- Clarify that `http/dup` has higher precedence than `http` in case both values are present + in `OTEL_SEMCONV_STABILITY_OPT_IN` + ([#249](https://github.com/open-telemetry/semantic-conventions/pull/249)) ## v1.21.0 (2023-07-13) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 2de954defa..15174ac9f6 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -37,6 +37,7 @@ linkTitle: Client Calls > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/http/README.md b/docs/http/README.md index c12ecc2998..e3bc209b16 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -33,6 +33,7 @@ and various HTTP versions like 1.1, 2 and SPDY. > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental HTTP and networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index c70d6fdfde..5f8c192706 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -46,6 +46,7 @@ operations. By adding HTTP attributes to metric events it allows for finely tune > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental HTTP and networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index eb058e928e..871dc221b9 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -52,6 +52,7 @@ and various HTTP versions like 1.1, 2 and SPDY. > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental HTTP and networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 72179fd6ce..d25a0c57b0 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -53,6 +53,7 @@ > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 6cb5768f3d..d80d0c5df4 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -55,6 +55,7 @@ metrics can be filtered for finer grain analysis. > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index c82bfa02f4..cf6a054ccc 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -45,6 +45,7 @@ This document defines how to describe remote procedure calls > * The default behavior (in the absence of one of these values) is to continue > emitting whatever version of the old experimental networking attributes > the instrumentation was emitting previously. +> * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of attributes. > * SHOULD drop the environment variable in the next major version (stable From c83a10a9c33c18a769835e959200d0e24dc708fe Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 15 Aug 2023 04:33:53 -0700 Subject: [PATCH 023/482] Move network attributes out of trace folder (#256) --- model/{trace/general.yaml => network.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename model/{trace/general.yaml => network.yaml} (100%) diff --git a/model/trace/general.yaml b/model/network.yaml similarity index 100% rename from model/trace/general.yaml rename to model/network.yaml From 0669ca5b81d366dc21647b8ed967194bb0868a4c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 16 Aug 2023 14:59:43 -0700 Subject: [PATCH 024/482] Add `jvm.cpu.count` metric (#52) Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 ++ docs/system/runtime-environment-metrics.md | 16 ++++++++++++++++ model/metrics/process-runtime-jvm-metrics.yaml | 7 +++++++ 3 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8c5f52301..a79fc4b3d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ release. - Clarify that `http/dup` has higher precedence than `http` in case both values are present in `OTEL_SEMCONV_STABILITY_OPT_IN` ([#249](https://github.com/open-telemetry/semantic-conventions/pull/249)) +- Add `jvm.cpu.count` metric. + ([#52](https://github.com/open-telemetry/semantic-conventions/pull/52)) ## v1.21.0 (2023-07-13) diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index c0843daf01..b3c7b8cb88 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -30,6 +30,7 @@ semantic conventions when instrumenting runtime environments. * [Metric: `jvm.classes.unloaded`](#metric-jvmclassesunloaded) * [Metric: `jvm.classes.current_loaded`](#metric-jvmclassescurrent_loaded) * [Metric: `jvm.cpu.time`](#metric-jvmcputime) + * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) - [JVM Metrics (Experimental)](#jvm-metrics-experimental) * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) @@ -289,6 +290,21 @@ and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https: +### Metric: `jvm.cpu.count` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`Runtime#availableProcessors()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors--). +Note that this is always an integer value (i.e. fractional or millicores are not represented). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.cpu.count` | UpDownCounter | `{cpu}` | Number of processors available to the Java virtual machine. | + + + + + ### Metric: `jvm.cpu.recent_utilization` This metric is [recommended][MetricRecommended]. diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/process-runtime-jvm-metrics.yaml index d6b4c502a8..683b42ba92 100644 --- a/model/metrics/process-runtime-jvm-metrics.yaml +++ b/model/metrics/process-runtime-jvm-metrics.yaml @@ -114,6 +114,13 @@ groups: instrument: updowncounter unit: "{class}" + - id: metric.jvm.cpu.count + type: metric + metric_name: jvm.cpu.count + brief: "Number of processors available to the Java virtual machine." + instrument: updowncounter + unit: "{cpu}" + - id: metric.jvm.cpu.time type: metric metric_name: jvm.cpu.time From 3bd1c39e5f6aae7ea942c50bd771fa2e7e408249 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 16 Aug 2023 16:01:04 -0700 Subject: [PATCH 025/482] Rename `jvm.classes.current_loaded` to `jvm.classes.count` (#60) --- CHANGELOG.md | 2 ++ docs/system/runtime-environment-metrics.md | 10 +++++----- model/metrics/process-runtime-jvm-metrics.yaml | 4 ++-- schema-next.yaml | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a79fc4b3d6..054066f8fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ release. ([#249](https://github.com/open-telemetry/semantic-conventions/pull/249)) - Add `jvm.cpu.count` metric. ([#52](https://github.com/open-telemetry/semantic-conventions/pull/52)) +- BREAKING: Rename `jvm.classes.current_loaded` metrics to `jvm.classes.count` + ([#60](https://github.com/open-telemetry/semantic-conventions/pull/60)) ## v1.21.0 (2023-07-13) diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index b3c7b8cb88..e884bf5765 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -28,7 +28,7 @@ semantic conventions when instrumenting runtime environments. * [Metric: `jvm.threads.count`](#metric-jvmthreadscount) * [Metric: `jvm.classes.loaded`](#metric-jvmclassesloaded) * [Metric: `jvm.classes.unloaded`](#metric-jvmclassesunloaded) - * [Metric: `jvm.classes.current_loaded`](#metric-jvmclassescurrent_loaded) + * [Metric: `jvm.classes.count`](#metric-jvmclassescount) * [Metric: `jvm.cpu.time`](#metric-jvmcputime) * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) @@ -260,18 +260,18 @@ This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](http -### Metric: `jvm.classes.current_loaded` +### Metric: `jvm.classes.count` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.classes.current_loaded` | UpDownCounter | `{class}` | Number of classes currently loaded. | +| `jvm.classes.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | - + ### Metric: `jvm.cpu.time` diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/process-runtime-jvm-metrics.yaml index 683b42ba92..5008665b6b 100644 --- a/model/metrics/process-runtime-jvm-metrics.yaml +++ b/model/metrics/process-runtime-jvm-metrics.yaml @@ -107,9 +107,9 @@ groups: instrument: counter unit: "{class}" - - id: metric.jvm.classes.current_loaded + - id: metric.jvm.classes.count type: metric - metric_name: jvm.classes.current_loaded + metric_name: jvm.classes.count brief: "Number of classes currently loaded." instrument: updowncounter unit: "{class}" diff --git a/schema-next.yaml b/schema-next.yaml index e19ff8a65e..bb558406e4 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -18,7 +18,8 @@ versions: process.runtime.jvm.threads.count: jvm.threads.count process.runtime.jvm.classes.loaded: jvm.classes.loaded process.runtime.jvm.classes.unloaded: jvm.classes.unloaded - process.runtime.jvm.classes.current_loaded: jvm.classes.current_loaded + # https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.classes.count process.runtime.jvm.cpu.time: jvm.cpu.time process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization process.runtime.jvm.memory.init: jvm.memory.init From a42aecc6b8e2a374027419ce590d856909c953bb Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 17 Aug 2023 04:15:20 -0700 Subject: [PATCH 026/482] Rename jvm.buffer.(usage|limit) to jvm.buffer.memory.(usage|limit) (#253) Co-authored-by: Armin Ruech --- CHANGELOG.md | 3 +++ docs/system/runtime-environment-metrics.md | 20 +++++++++---------- ...cess-runtime-jvm-metrics-experimental.yaml | 8 ++++---- schema-next.yaml | 6 ++++-- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054066f8fe..bcee1a1486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,9 @@ release. ([#249](https://github.com/open-telemetry/semantic-conventions/pull/249)) - Add `jvm.cpu.count` metric. ([#52](https://github.com/open-telemetry/semantic-conventions/pull/52)) +- BREAKING: Rename metrics `jvm.buffer.usage` to `jvm.buffer.memory.usage` + and `jvm.buffer.limit` to `jvm.buffer.memory.limit`. + ([#253](https://github.com/open-telemetry/semantic-conventions/pull/253)) - BREAKING: Rename `jvm.classes.current_loaded` metrics to `jvm.classes.count` ([#60](https://github.com/open-telemetry/semantic-conventions/pull/60)) diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index e884bf5765..9967d03805 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -36,8 +36,8 @@ semantic conventions when instrumenting runtime environments. * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) - * [Metric: `jvm.buffer.usage`](#metric-jvmbufferusage) - * [Metric: `jvm.buffer.limit`](#metric-jvmbufferlimit) + * [Metric: `jvm.buffer.memory.usage`](#metric-jvmbuffermemoryusage) + * [Metric: `jvm.buffer.memory.limit`](#metric-jvmbuffermemorylimit) * [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) @@ -387,18 +387,18 @@ This metric is obtained from [`OperatingSystemMXBean#getSystemLoadAverage()`](ht -### Metric: `jvm.buffer.usage` +### Metric: `jvm.buffer.memory.usage` This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getMemoryUsed--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | +| `jvm.buffer.memory.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | @@ -406,18 +406,18 @@ This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.o **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). -### Metric: `jvm.buffer.limit` +### Metric: `jvm.buffer.memory.limit` This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getTotalCapacity--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | +| `jvm.buffer.memory.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | diff --git a/model/metrics/process-runtime-jvm-metrics-experimental.yaml b/model/metrics/process-runtime-jvm-metrics-experimental.yaml index da74d34423..8ea4fa57c5 100644 --- a/model/metrics/process-runtime-jvm-metrics-experimental.yaml +++ b/model/metrics/process-runtime-jvm-metrics-experimental.yaml @@ -45,17 +45,17 @@ groups: Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - - id: metric.jvm.buffer.usage + - id: metric.jvm.buffer.memory.usage type: metric - metric_name: jvm.buffer.usage + metric_name: jvm.buffer.memory.usage extends: attributes.jvm.buffer brief: "Measure of memory used by buffers." instrument: updowncounter unit: "By" - - id: metric.jvm.buffer.limit + - id: metric.jvm.buffer.memory.limit type: metric - metric_name: jvm.buffer.limit + metric_name: jvm.buffer.memory.limit extends: attributes.jvm.buffer brief: "Measure of total memory capacity of buffers." instrument: updowncounter diff --git a/schema-next.yaml b/schema-next.yaml index bb558406e4..7c3c73c3d6 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -25,8 +25,10 @@ versions: process.runtime.jvm.memory.init: jvm.memory.init process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m - process.runtime.jvm.buffer.usage: jvm.buffer.usage - process.runtime.jvm.buffer.limit: jvm.buffer.limit + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit process.runtime.jvm.buffer.count: jvm.buffer.count # https://github.com/open-telemetry/semantic-conventions/pull/20 - rename_attributes: From 098db1ca510da01fe941f6c6308aad5000def910 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 17 Aug 2023 08:45:02 -0700 Subject: [PATCH 027/482] Remove pluralization from JVM metric namespaces (#252) --- CHANGELOG.md | 2 + docs/system/runtime-environment-metrics.md | 40 +++++++++---------- .../metrics/process-runtime-jvm-metrics.yaml | 16 ++++---- schema-next.yaml | 14 ++++--- 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcee1a1486..006acac363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,8 @@ release. ([#253](https://github.com/open-telemetry/semantic-conventions/pull/253)) - BREAKING: Rename `jvm.classes.current_loaded` metrics to `jvm.classes.count` ([#60](https://github.com/open-telemetry/semantic-conventions/pull/60)) +- BREAKING: Remove pluralization from JVM metric namespaces. + ([#252](https://github.com/open-telemetry/semantic-conventions/pull/252)) ## v1.21.0 (2023-07-13) diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index 9967d03805..c8b8ce25a9 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -25,10 +25,10 @@ semantic conventions when instrumenting runtime environments. * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) * [Metric: `jvm.memory.usage_after_last_gc`](#metric-jvmmemoryusage_after_last_gc) * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) - * [Metric: `jvm.threads.count`](#metric-jvmthreadscount) - * [Metric: `jvm.classes.loaded`](#metric-jvmclassesloaded) - * [Metric: `jvm.classes.unloaded`](#metric-jvmclassesunloaded) - * [Metric: `jvm.classes.count`](#metric-jvmclassescount) + * [Metric: `jvm.thread.count`](#metric-jvmthreadcount) + * [Metric: `jvm.class.loaded`](#metric-jvmclassloaded) + * [Metric: `jvm.class.unloaded`](#metric-jvmclassunloaded) + * [Metric: `jvm.class.count`](#metric-jvmclasscount) * [Metric: `jvm.cpu.time`](#metric-jvmcputime) * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) @@ -213,65 +213,65 @@ of `[]` (single bucket histogram capturing count, sum, min, max). **[2]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). -### Metric: `jvm.threads.count` +### Metric: `jvm.thread.count` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ThreadMXBean#getDaemonThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getDaemonThreadCount--) and [`ThreadMXBean#getThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadCount--). Note that this is the number of platform threads (as opposed to virtual threads). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.threads.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | +| `jvm.thread.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`thread.daemon`](../general/attributes.md) | boolean | Whether the thread is daemon or not. | | Recommended | -### Metric: `jvm.classes.loaded` +### Metric: `jvm.class.loaded` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getTotalLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getTotalLoadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.classes.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | +| `jvm.class.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | - + -### Metric: `jvm.classes.unloaded` +### Metric: `jvm.class.unloaded` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getUnloadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.classes.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | +| `jvm.class.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | - + -### Metric: `jvm.classes.count` +### Metric: `jvm.class.count` This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.classes.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | +| `jvm.class.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | - + ### Metric: `jvm.cpu.time` diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/process-runtime-jvm-metrics.yaml index 5008665b6b..4306fc239c 100644 --- a/model/metrics/process-runtime-jvm-metrics.yaml +++ b/model/metrics/process-runtime-jvm-metrics.yaml @@ -83,9 +83,9 @@ groups: Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). - - id: metric.jvm.threads.count + - id: metric.jvm.thread.count type: metric - metric_name: jvm.threads.count + metric_name: jvm.thread.count brief: "Number of executing platform threads." instrument: updowncounter unit: "{thread}" @@ -93,23 +93,23 @@ groups: - ref: thread.daemon requirement_level: recommended - - id: metric.jvm.classes.loaded + - id: metric.jvm.class.loaded type: metric - metric_name: jvm.classes.loaded + metric_name: jvm.class.loaded brief: "Number of classes loaded since JVM start." instrument: counter unit: "{class}" - - id: metric.jvm.classes.unloaded + - id: metric.jvm.class.unloaded type: metric - metric_name: jvm.classes.unloaded + metric_name: jvm.class.unloaded brief: "Number of classes unloaded since JVM start." instrument: counter unit: "{class}" - - id: metric.jvm.classes.count + - id: metric.jvm.class.count type: metric - metric_name: jvm.classes.count + metric_name: jvm.class.count brief: "Number of classes currently loaded." instrument: updowncounter unit: "{class}" diff --git a/schema-next.yaml b/schema-next.yaml index 7c3c73c3d6..acc97ca7b8 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -15,11 +15,15 @@ versions: process.runtime.jvm.memory.limit: jvm.memory.limit process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc process.runtime.jvm.gc.duration: jvm.gc.duration - process.runtime.jvm.threads.count: jvm.threads.count - process.runtime.jvm.classes.loaded: jvm.classes.loaded - process.runtime.jvm.classes.unloaded: jvm.classes.unloaded - # https://github.com/open-telemetry/semantic-conventions/pull/60 - process.runtime.jvm.classes.current_loaded: jvm.classes.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count process.runtime.jvm.cpu.time: jvm.cpu.time process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization process.runtime.jvm.memory.init: jvm.memory.init From 99f3f9d4aff8afb94dd2f09f7cde73dbfd0335fc Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 21 Aug 2023 07:26:07 -0700 Subject: [PATCH 028/482] Move JVM metrics to their own page (#271) --- docs/jvm/jvm-metrics.md | 430 ++++++++++++++++++ docs/system/runtime-environment-metrics.md | 392 ---------------- ...tal.yaml => jvm-metrics-experimental.yaml} | 0 ...time-jvm-metrics.yaml => jvm-metrics.yaml} | 0 4 files changed, 430 insertions(+), 392 deletions(-) create mode 100644 docs/jvm/jvm-metrics.md rename model/metrics/{process-runtime-jvm-metrics-experimental.yaml => jvm-metrics-experimental.yaml} (100%) rename model/metrics/{process-runtime-jvm-metrics.yaml => jvm-metrics.yaml} (100%) diff --git a/docs/jvm/jvm-metrics.md b/docs/jvm/jvm-metrics.md new file mode 100644 index 0000000000..6272e494fe --- /dev/null +++ b/docs/jvm/jvm-metrics.md @@ -0,0 +1,430 @@ + + +# Semantic Conventions for JVM Metrics + +**Status**: [Experimental][DocumentStatus] + +This document describes semantic conventions for JVM metrics in OpenTelemetry. + + + + + +- [JVM Memory](#jvm-memory) + * [Metric: `jvm.memory.usage`](#metric-jvmmemoryusage) + * [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) + * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) + * [Metric: `jvm.memory.usage_after_last_gc`](#metric-jvmmemoryusage_after_last_gc) +- [JVM Garbage Collection](#jvm-garbage-collection) + * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) +- [JVM Threads](#jvm-threads) + * [Metric: `jvm.thread.count`](#metric-jvmthreadcount) +- [JVM Classes](#jvm-classes) + * [Metric: `jvm.class.loaded`](#metric-jvmclassloaded) + * [Metric: `jvm.class.unloaded`](#metric-jvmclassunloaded) + * [Metric: `jvm.class.count`](#metric-jvmclasscount) +- [JVM CPU](#jvm-cpu) + * [Metric: `jvm.cpu.time`](#metric-jvmcputime) + * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) + * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) +- [Very experimental](#very-experimental) + * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) + * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) + * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) + * [Metric: `jvm.buffer.memory.usage`](#metric-jvmbuffermemoryusage) + * [Metric: `jvm.buffer.memory.limit`](#metric-jvmbuffermemorylimit) + * [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) + + + +## JVM Memory + +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.memory.*` + +### Metric: `jvm.memory.usage` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.memory.usage` | UpDownCounter | `By` | Measure of memory used. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | + +**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `heap` | Heap memory. | +| `non_heap` | Non-heap memory | + + +### Metric: `jvm.memory.committed` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | + +**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `heap` | Heap memory. | +| `non_heap` | Non-heap memory | + + +### Metric: `jvm.memory.limit` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | + +**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `heap` | Heap memory. | +| `non_heap` | Non-heap memory | + + +### Metric: `jvm.memory.usage_after_last_gc` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getCollectionUsage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.memory.usage_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | + +**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `heap` | Heap memory. | +| `non_heap` | Non-heap memory | + + +## JVM Garbage Collection + +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.gc.*` + +### Metric: `jvm.gc.duration` + +This metric is [recommended][MetricRecommended]. +This metric is obtained by subscribing to +[`GarbageCollectionNotificationInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html) events provided by [`GarbageCollectorMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/GarbageCollectorMXBean.html). The duration value is obtained from [`GcInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GcInfo.html#getDuration--) + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) +of `[]` (single bucket histogram capturing count, sum, min, max). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.gc.name` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | +| `jvm.gc.action` | string | Name of the garbage collector action. [2] | `end of minor GC`; `end of major GC` | Recommended | + +**[1]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +**[2]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + + +## JVM Threads + +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.thread.*` + +### Metric: `jvm.thread.count` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`ThreadMXBean#getDaemonThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getDaemonThreadCount--) and +[`ThreadMXBean#getThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadCount--). +Note that this is the number of platform threads (as opposed to virtual threads). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.thread.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`thread.daemon`](../general/attributes.md) | boolean | Whether the thread is daemon or not. | | Recommended | + + +## JVM Classes + +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.class.*` + +### Metric: `jvm.class.loaded` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`ClassLoadingMXBean#getTotalLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getTotalLoadedClassCount--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.class.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | + + + + + +### Metric: `jvm.class.unloaded` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getUnloadedClassCount--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.class.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | + + + + + +### Metric: `jvm.class.count` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.class.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | + + + + + +## JVM CPU + +**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.cpu.*` + +### Metric: `jvm.cpu.time` + +This metric is [recommended][MetricRecommended]. + +This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuTime()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuTime()) on HotSpot +and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on J9. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | + + + + + +### Metric: `jvm.cpu.count` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`Runtime#availableProcessors()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors--). +Note that this is always an integer value (i.e. fractional or millicores are not represented). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.cpu.count` | UpDownCounter | `{cpu}` | Number of processors available to the Java virtual machine. | + + + + + +### Metric: `jvm.cpu.recent_utilization` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()) on HotSpot +and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuLoad--) on J9. +Note that the JVM does not provide a definition of what "recent" means. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | + +**[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). + + + + + +## Very experimental + +**Description:** Very experimental Java Virtual Machine (JVM) metrics captured under `jvm.` + +### Metric: `jvm.memory.init` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | + +**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `heap` | Heap memory. | +| `non_heap` | Non-heap memory | + + +### Metric: `jvm.system.cpu.utilization` + +This metric is [Opt-In][MetricOptIn]. +This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getSystemCpuLoad()) on Java version 8..13, [`com.sun.management.OperatingSystemMXBean#getCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()) on Java version 14+, +and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on J9. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | + +**[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()). + + + + + +### Metric: `jvm.system.cpu.load_1m` + +This metric is [Opt-In][MetricOptIn]. +This metric is obtained from [`OperatingSystemMXBean#getSystemLoadAverage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | + +**[1]:** The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage()). + + + + + +### Metric: `jvm.buffer.memory.usage` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getMemoryUsed--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.buffer.memory.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | + +**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). + + +### Metric: `jvm.buffer.memory.limit` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getTotalCapacity--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.buffer.memory.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | + +**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). + + +### Metric: `jvm.buffer.count` + +This metric is [recommended][MetricRecommended]. +This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getCount--). + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | + +**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#opt-in +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/system/runtime-environment-metrics.md b/docs/system/runtime-environment-metrics.md index c8b8ce25a9..c77222063a 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/system/runtime-environment-metrics.md @@ -19,26 +19,6 @@ semantic conventions when instrumenting runtime environments. - [Metric Instruments](#metric-instruments) * [Runtime Environment Specific Metrics - `process.runtime.{environment}.`](#runtime-environment-specific-metrics---processruntimeenvironment) - [Attributes](#attributes) -- [JVM Metrics](#jvm-metrics) - * [Metric: `jvm.memory.usage`](#metric-jvmmemoryusage) - * [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) - * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) - * [Metric: `jvm.memory.usage_after_last_gc`](#metric-jvmmemoryusage_after_last_gc) - * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) - * [Metric: `jvm.thread.count`](#metric-jvmthreadcount) - * [Metric: `jvm.class.loaded`](#metric-jvmclassloaded) - * [Metric: `jvm.class.unloaded`](#metric-jvmclassunloaded) - * [Metric: `jvm.class.count`](#metric-jvmclasscount) - * [Metric: `jvm.cpu.time`](#metric-jvmcputime) - * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) - * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) -- [JVM Metrics (Experimental)](#jvm-metrics-experimental) - * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) - * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) - * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) - * [Metric: `jvm.buffer.memory.usage`](#metric-jvmbuffermemoryusage) - * [Metric: `jvm.buffer.memory.limit`](#metric-jvmbuffermemorylimit) - * [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) @@ -74,376 +54,4 @@ consider, for example pthreads vs green thread implementations. [`process.runtime`](/docs/resource/process.md#process-runtimes) resource attributes SHOULD be included on runtime metric events as appropriate. -## JVM Metrics - -**Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.` - -### Metric: `jvm.memory.usage` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.usage` | UpDownCounter | `By` | Measure of memory used. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | - -**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - -`jvm.memory.type` MUST be one of the following: - -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | - - -### Metric: `jvm.memory.committed` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | - -**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - -`jvm.memory.type` MUST be one of the following: - -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | - - -### Metric: `jvm.memory.limit` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | - -**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - -`jvm.memory.type` MUST be one of the following: - -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | - - -### Metric: `jvm.memory.usage_after_last_gc` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getCollectionUsage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.usage_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | - -**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - -`jvm.memory.type` MUST be one of the following: - -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | - - -### Metric: `jvm.gc.duration` - -This metric is [recommended][MetricRecommended]. -This metric is obtained by subscribing to -[`GarbageCollectionNotificationInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html) events provided by [`GarbageCollectorMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/GarbageCollectorMXBean.html). The duration value is obtained from [`GcInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GcInfo.html#getDuration--) - -This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) -of `[]` (single bucket histogram capturing count, sum, min, max). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.gc.name` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | -| `jvm.gc.action` | string | Name of the garbage collector action. [2] | `end of minor GC`; `end of major GC` | Recommended | - -**[1]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). - -**[2]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). - - -### Metric: `jvm.thread.count` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`ThreadMXBean#getDaemonThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getDaemonThreadCount--) and -[`ThreadMXBean#getThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadCount--). -Note that this is the number of platform threads (as opposed to virtual threads). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.thread.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`thread.daemon`](../general/attributes.md) | boolean | Whether the thread is daemon or not. | | Recommended | - - -### Metric: `jvm.class.loaded` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`ClassLoadingMXBean#getTotalLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getTotalLoadedClassCount--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | - - - - - -### Metric: `jvm.class.unloaded` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getUnloadedClassCount--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | - - - - - -### Metric: `jvm.class.count` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | - - - - - -### Metric: `jvm.cpu.time` - -This metric is [recommended][MetricRecommended]. - -This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuTime()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuTime()) on HotSpot -and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on J9. - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | - - - - - -### Metric: `jvm.cpu.count` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`Runtime#availableProcessors()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors--). -Note that this is always an integer value (i.e. fractional or millicores are not represented). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.count` | UpDownCounter | `{cpu}` | Number of processors available to the Java virtual machine. | - - - - - -### Metric: `jvm.cpu.recent_utilization` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()) on HotSpot -and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuLoad--) on J9. -Note that the JVM does not provide a definition of what "recent" means. - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | - -**[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). - - - - - -## JVM Metrics (Experimental) - -**Description:** Experimental Java Virtual Machine (JVM) metrics captured under `jvm.` - -### Metric: `jvm.memory.init` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | - -**[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - -`jvm.memory.type` MUST be one of the following: - -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | - - -### Metric: `jvm.system.cpu.utilization` - -This metric is [Opt-In][MetricOptIn]. -This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getSystemCpuLoad()) on Java version 8..13, [`com.sun.management.OperatingSystemMXBean#getCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()) on Java version 14+, -and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on J9. - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | - -**[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()). - - - - - -### Metric: `jvm.system.cpu.load_1m` - -This metric is [Opt-In][MetricOptIn]. -This metric is obtained from [`OperatingSystemMXBean#getSystemLoadAverage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | - -**[1]:** The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage()). - - - - - -### Metric: `jvm.buffer.memory.usage` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getMemoryUsed--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.memory.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | - -**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - - -### Metric: `jvm.buffer.memory.limit` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getTotalCapacity--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.memory.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | - -**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - - -### Metric: `jvm.buffer.count` - -This metric is [recommended][MetricRecommended]. -This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getCount--). - - -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | - - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | - -**[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - - [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#opt-in -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/model/metrics/process-runtime-jvm-metrics-experimental.yaml b/model/metrics/jvm-metrics-experimental.yaml similarity index 100% rename from model/metrics/process-runtime-jvm-metrics-experimental.yaml rename to model/metrics/jvm-metrics-experimental.yaml diff --git a/model/metrics/process-runtime-jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml similarity index 100% rename from model/metrics/process-runtime-jvm-metrics.yaml rename to model/metrics/jvm-metrics.yaml From 4bbb8c907402caa90bc077214e8a2c78807c1ab9 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 22 Aug 2023 10:10:01 -0700 Subject: [PATCH 029/482] Simplify HTTP metric briefs (#276) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 16 ++++++++++++---- model/metrics/http.yaml | 12 ++++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 006acac363..6faafa19c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,8 @@ release. ([#60](https://github.com/open-telemetry/semantic-conventions/pull/60)) - BREAKING: Remove pluralization from JVM metric namespaces. ([#252](https://github.com/open-telemetry/semantic-conventions/pull/252)) +- Simplify HTTP metric briefs. + ([#276](https://github.com/open-telemetry/semantic-conventions/pull/276)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 5f8c192706..26ad37b78e 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -214,7 +214,9 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.request.size` | Histogram | `By` | Measures the size of HTTP request messages (compressed). | +| `http.server.request.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | + +**[1]:** Size as measured over the wire (compressed size if messages are compressed). @@ -291,7 +293,9 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.response.size` | Histogram | `By` | Measures the size of HTTP response messages (compressed). | +| `http.server.response.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | + +**[1]:** Size as measured over the wire (compressed size if messages are compressed). @@ -447,7 +451,9 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.request.size` | Histogram | `By` | Measures the size of HTTP request messages (compressed). | +| `http.client.request.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | + +**[1]:** Size as measured over the wire (compressed size if messages are compressed). @@ -518,7 +524,9 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.response.size` | Histogram | `By` | Measures the size of HTTP response messages (compressed). | +| `http.client.response.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | + +**[1]:** Size as measured over the wire (compressed size if messages are compressed). diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 813179a005..34d6baaa2d 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -97,17 +97,19 @@ groups: - id: metric.http.server.request.size type: metric metric_name: http.server.request.size - brief: "Measures the size of HTTP request messages (compressed)." + brief: "Measures the size of HTTP request messages." instrument: histogram unit: "By" + note: Size as measured over the wire (compressed size if messages are compressed). extends: metric_attributes.http.server - id: metric.http.server.response.size type: metric metric_name: http.server.response.size - brief: "Measures the size of HTTP response messages (compressed)." + brief: "Measures the size of HTTP response messages." instrument: histogram unit: "By" + note: Size as measured over the wire (compressed size if messages are compressed). extends: metric_attributes.http.server - id: metric.http.client.request.duration @@ -121,15 +123,17 @@ groups: - id: metric.http.client.request.size type: metric metric_name: http.client.request.size - brief: "Measures the size of HTTP request messages (compressed)." + brief: "Measures the size of HTTP request messages." instrument: histogram unit: "By" + note: Size as measured over the wire (compressed size if messages are compressed). extends: metric_attributes.http.client - id: metric.http.client.response.size type: metric metric_name: http.client.response.size - brief: "Measures the size of HTTP response messages (compressed)." + brief: "Measures the size of HTTP response messages." instrument: histogram unit: "By" + note: Size as measured over the wire (compressed size if messages are compressed). extends: metric_attributes.http.client From 4fcf4dfd795eccec8018f628c1331b3aa1aee99d Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 30 Aug 2023 04:59:18 -0700 Subject: [PATCH 030/482] Clarify stabilization plan does not just apply to attributes (#278) --- docs/database/database-spans.md | 17 +++++++++-------- docs/http/README.md | 17 +++++++++-------- docs/http/http-metrics.md | 17 +++++++++-------- docs/http/http-spans.md | 17 +++++++++-------- docs/messaging/messaging-spans.md | 17 +++++++++-------- docs/rpc/rpc-metrics.md | 17 +++++++++-------- docs/rpc/rpc-spans.md | 17 +++++++++-------- 7 files changed, 63 insertions(+), 56 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 15174ac9f6..d208eebd7a 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -22,24 +22,25 @@ linkTitle: Client Calls > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/database.md) > (or prior): > -> * SHOULD NOT change the version of the networking attributes that they emit +> * SHOULD NOT change the version of the networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in Database instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in Database instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable networking attributes, -> and stop emitting the old experimental networking attributes +> * `http` - emit the new, stable networking conventions, +> and stop emitting the old experimental networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking attributes, +> * `http/dup` - emit both the old and the stable networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking attributes +> emitting whatever version of the old experimental networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/http/README.md b/docs/http/README.md index e3bc209b16..a5249266f1 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -18,24 +18,25 @@ and various HTTP versions like 1.1, 2 and SPDY. > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md) > (or prior): > -> * SHOULD NOT change the version of the HTTP or networking attributes that they emit +> * SHOULD NOT change the version of the HTTP or networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in HTTP instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in HTTP instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable HTTP and networking attributes, -> and stop emitting the old experimental HTTP and networking attributes +> * `http` - emit the new, stable HTTP and networking conventions, +> and stop emitting the old experimental HTTP and networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable HTTP and networking attributes, +> * `http/dup` - emit both the old and the stable HTTP and networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental HTTP and networking attributes +> emitting whatever version of the old experimental HTTP and networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 26ad37b78e..e97aebdd8e 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -31,24 +31,25 @@ operations. By adding HTTP attributes to metric events it allows for finely tune > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md) > (or prior): > -> * SHOULD NOT change the version of the HTTP or networking attributes that they emit +> * SHOULD NOT change the version of the HTTP or networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in HTTP instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in HTTP instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable HTTP and networking attributes, -> and stop emitting the old experimental HTTP and networking attributes +> * `http` - emit the new, stable HTTP and networking conventions, +> and stop emitting the old experimental HTTP and networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable HTTP and networking attributes, +> * `http/dup` - emit both the old and the stable HTTP and networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental HTTP and networking attributes +> emitting whatever version of the old experimental HTTP and networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 871dc221b9..7ea7529359 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -37,24 +37,25 @@ and various HTTP versions like 1.1, 2 and SPDY. > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md) > (or prior): > -> * SHOULD NOT change the version of the HTTP or networking attributes that they emit +> * SHOULD NOT change the version of the HTTP or networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in HTTP instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in HTTP instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable HTTP and networking attributes, -> and stop emitting the old experimental HTTP and networking attributes +> * `http` - emit the new, stable HTTP and networking conventions, +> and stop emitting the old experimental HTTP and networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable HTTP and networking attributes, +> * `http/dup` - emit both the old and the stable HTTP and networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental HTTP and networking attributes +> emitting whatever version of the old experimental HTTP and networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index d25a0c57b0..c1814ad8d9 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -38,24 +38,25 @@ > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/messaging.md) > (or prior): > -> * SHOULD NOT change the version of the networking attributes that they emit +> * SHOULD NOT change the version of the networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in Messaging instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in Messaging instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable networking attributes, -> and stop emitting the old experimental networking attributes +> * `http` - emit the new, stable networking conventions, +> and stop emitting the old experimental networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking attributes, +> * `http/dup` - emit both the old and the stable networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking attributes +> emitting whatever version of the old experimental networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index d80d0c5df4..d431dd6652 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -40,24 +40,25 @@ metrics can be filtered for finer grain analysis. > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/rpc-metrics.md) > (or prior): > -> * SHOULD NOT change the version of the networking attributes that they emit +> * SHOULD NOT change the version of the networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in RPC instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in RPC instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable networking attributes, -> and stop emitting the old experimental networking attributes +> * `http` - emit the new, stable networking conventions, +> and stop emitting the old experimental networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking attributes, +> * `http/dup` - emit both the old and the stable networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking attributes +> emitting whatever version of the old experimental networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index cf6a054ccc..e5bdaaf29d 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -30,24 +30,25 @@ This document defines how to describe remote procedure calls > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/rpc.md) > (or prior): > -> * SHOULD NOT change the version of the networking attributes that they emit +> * SHOULD NOT change the version of the networking conventions that they emit > until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking attributes which are also used -> in RPC instrumentations). +> include stabilization of a core set of networking conventions which are also used +> in RPC instrumentations). Conventions include, but are not limited to, attributes, +> metric and span names, and unit of measure. > * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` > in the existing major version which is a comma-separated list of values. > The only values defined so far are: -> * `http` - emit the new, stable networking attributes, -> and stop emitting the old experimental networking attributes +> * `http` - emit the new, stable networking conventions, +> and stop emitting the old experimental networking conventions > that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking attributes, +> * `http/dup` - emit both the old and the stable networking conventions, > allowing for a seamless transition. > * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking attributes +> emitting whatever version of the old experimental networking conventions > the instrumentation was emitting previously. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of attributes. +> for at least six months after it starts emitting both sets of conventions. > * SHOULD drop the environment variable in the next major version (stable > next major version SHOULD NOT be released prior to October 1, 2023). From 6c20838957be97f9a87c4c7467ece03499003670 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 6 Sep 2023 07:43:11 -0700 Subject: [PATCH 031/482] Update CODEOWNERS jvm paths (#301) --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4ef9633c60..67fd007ee9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,8 +28,8 @@ /docs/logs/ @open-telemetry/specs-semconv-approvers @tigrannajaryan # JVM semantic conventions approvers -/model/metrics/process-runtime-jvm-metrics.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-jvm-approvers -/model/metrics/process-runtime-jvm-metrics-experimental.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-jvm-approvers +/model/metrics/jvm-* @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-jvm-approvers +/docs/jvm/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-jvm-approvers # HTTP semantic conventions approvers /model/metrics/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers From fcad0aa62ea9d0fcf2582f003a2abf0484693619 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 7 Sep 2023 12:11:00 +0300 Subject: [PATCH 032/482] Add host cpu info (#209) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/host.md | 15 +++++++++++++ model/resource/host.yaml | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6faafa19c4..ed0bba815c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ release. ([#252](https://github.com/open-telemetry/semantic-conventions/pull/252)) - Simplify HTTP metric briefs. ([#276](https://github.com/open-telemetry/semantic-conventions/pull/276)) +- Add host cpu resource attributes. + ([#209](https://github.com/open-telemetry/semantic-conventions/pull/209)) ## v1.21.0 (2023-07-13) diff --git a/docs/resource/host.md b/docs/resource/host.md index 96d7da4dea..150755dc19 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -31,6 +31,21 @@ | `x86` | 32-bit x86 | +**type:** `host.cpu` + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | +| `host.cpu.family` | int | Numeric value specifying the family or generation of the CPU. | `6` | Opt-In | +| `host.cpu.model.id` | int | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6` | Opt-In | +| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | +| `host.cpu.stepping` | int | Stepping or core revisions. | `1` | Opt-In | +| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | + +**[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. + + ## Collecting host.id from non-containerized systems ### Non-privileged Machine ID Lookup diff --git a/model/resource/host.yaml b/model/resource/host.yaml index 457aa1c8ae..2839d8f660 100644 --- a/model/resource/host.yaml +++ b/model/resource/host.yaml @@ -70,3 +70,49 @@ groups: The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). examples: ['0.1'] + - id: host.cpu + prefix: host.cpu + type: resource + brief: > + A host's CPU information + attributes: + - id: vendor.id + requirement_level: opt_in + type: string + brief: > + Processor manufacturer identifier. A maximum 12-character string. + note: > + [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. + Writing these to memory in this order results in a 12-character string. + examples: [ 'GenuineIntel' ] + - id: family + requirement_level: opt_in + type: int + brief: > + Numeric value specifying the family or generation of the CPU. + examples: [ 6 ] + - id: model.id + requirement_level: opt_in + type: int + brief: > + Model identifier. It provides more granular information about the CPU, distinguishing it from + other CPUs within the same family. + examples: [ 6 ] + - id: model.name + requirement_level: opt_in + type: string + brief: > + Model designation of the processor. + examples: [ '11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz' ] + - id: stepping + requirement_level: opt_in + type: int + brief: > + Stepping or core revisions. + examples: [ 1 ] + - id: cache.l2.size + requirement_level: opt_in + type: int + brief: > + The amount of level 2 memory cache available to the processor (in Bytes). + examples: [ 12288000 ] From ff200826aec224851e754cefe1c857d4f47e36a5 Mon Sep 17 00:00:00 2001 From: Bertrand Martin <32521698+bertysentry@users.noreply.github.com> Date: Thu, 7 Sep 2023 18:58:06 +0200 Subject: [PATCH 033/482] Fix unit for hw.network.bandwidth.limit metric (#91) --- docs/system/hardware-metrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index 7c45d8bdcf..516674d5e6 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -270,7 +270,7 @@ fiber channel port or a Wi-Fi adapter. | `hw.errors` | Number of errors encountered by the network adapter | {error} | Counter | Int64 | `hw.error.type` (Recommended) | `zero_buffer_credit`, `crc`, etc. | | | | | | | `hw.type` (**Required**) | `network` | | | | | | | `direction` (Recommended) | `receive`, `transmit` | -| `hw.network.bandwidth.limit` | Link speed | By | UpDownCounter | Int64 | | | +| `hw.network.bandwidth.limit` | Link speed | By/s | UpDownCounter | Int64 | | | | `hw.network.bandwidth.utilization` | Utilization of the network bandwidth as a fraction | 1 | Gauge | Double | | | | `hw.network.io` | Received and transmitted network traffic in bytes | By | Counter | Int64 | `direction` (**Required**) | `receive`, `transmit` | | `hw.network.packets` | Received and transmitted network traffic in packets (or frames) | {packet} | Counter | Int64 | `direction` (**Required**) | `receive`, `transmit` | From 9e3ac90443cabde129db03d8a2a1e887f6e3fdf2 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 11 Sep 2023 12:22:44 +0300 Subject: [PATCH 034/482] Add oci.manifest.digest, container.image.repo_digests and make container.image.tag array (#159) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/container.md | 35 +++++++++++++++++++++++++++++++---- model/resource/container.yaml | 26 +++++++++++++++++++++----- model/resource/oci.yaml | 21 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 model/resource/oci.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index ed0bba815c..66573a09cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ release. - Update `.count` metric naming convention so that it only applies to UpDownCounters, and add that `.total` should not be used by either Counters or UpDownCounters ([#107](https://github.com/open-telemetry/semantic-conventions/pull/107)) +- Add `oci.manifest.digest`, `container.image.repo_digests` attributes. Make `container.image.tag` array and in plural form. + ([#159](https://github.com/open-telemetry/semantic-conventions/pull/159)) - BREAKING: Rename `http.client.duration` and `http.server.duration` metrics to `http.client.request.duration` and `http.server.request.duration` respectively. ([#224](https://github.com/open-telemetry/semantic-conventions/pull/224)) diff --git a/docs/resource/container.md b/docs/resource/container.md index 264a7d53bc..b0017c4b36 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -13,17 +13,44 @@ | `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | Recommended | | `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | | `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | -| `container.image.tag` | string | Container image tag. | `0.1` | Recommended | +| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | | `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [1] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | -| `container.command` | string | The command used to run the container (i.e. the command name). [2] | `otelcontribcol` | Opt-In | +| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [2] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | +| `container.command` | string | The command used to run the container (i.e. the command name). [3] | `otelcontribcol` | Opt-In | | `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | | `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | **[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. -OCI defines a digest of manifest. +The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. -**[2]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. +**[2]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. + +**[3]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + + +## Open Container Initiative (OCI) + +The [Open Container Initiative](https://opencontainers.org/) defines open industry standards around container formats and runtimes. + +### OCI Image Manifest + +This section refers to the [specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md) +that defines an OCI Image manifest. + +**Status**: [Experimental][DocumentStatus] + +**type:** `oci` + +**Description:** Attributes of an OCI image manifest. + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | Recommended | + +**[1]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). +An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/resource/container.yaml b/model/resource/container.yaml index f3f52c7cfa..3dbac9641b 100644 --- a/model/resource/container.yaml +++ b/model/resource/container.yaml @@ -27,11 +27,14 @@ groups: brief: > Name of the image the container was built on. examples: ['gcr.io/opentelemetry/operator'] - - id: image.tag - type: string + - id: image.tags + type: string[] brief: > - Container image tag. - examples: ['0.1'] + Container image tags. An example can be found in + [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). + Should be only the `` section of the full name for example + from `registry.example.com/my-org/my-image:`. + examples: ['v1.27.1', '3.5.7-0'] - id: image.id type: string brief: > @@ -44,8 +47,21 @@ groups: K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. - OCI defines a digest of manifest. + The ID is assinged by the container runtime and can vary in different environments. + Consider using `oci.manifest.digest` if it is important to identify the same + image in different environments/runtimes. examples: ['sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f'] + - id: image.repo_digests + type: string[] + brief: > + Repo digests of the container image as provided by the container runtime. + note: > + [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and + [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) + report those under the `RepoDigests` field. + examples: + - 'example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb' + - 'internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578' - id: command type: string requirement_level: opt_in diff --git a/model/resource/oci.yaml b/model/resource/oci.yaml new file mode 100644 index 0000000000..fc1ff2ebb3 --- /dev/null +++ b/model/resource/oci.yaml @@ -0,0 +1,21 @@ +groups: + - id: oci.manifest + prefix: oci.manifest + type: resource + brief: > + An OCI image manifest. + attributes: + - id: digest + type: string + brief: > + The digest of the OCI image manifest. For container images specifically is the + digest by which the container image is known. + note: > + Follows + [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), + and specifically the + [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). + + An example can be found in + [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). + examples: [ 'sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4' ] From 58b08c9dfbe4516b8ba8bdd73c403dd3c3931d69 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Mon, 11 Sep 2023 10:30:14 +0100 Subject: [PATCH 035/482] Add `cluster.name` and `node.name` attributes to Elasticsearch semantic conventions. (#285) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/database/elasticsearch.md | 42 +++++++++++++++++++++------------- model/trace/database.yaml | 19 +++++++++++++++ 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66573a09cd..3fbe4268e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ release. ## Unreleased +- Add `cluster.name` and `node.name` attributes to Elasticsearch semantic conventions. + ([#285](https://github.com/open-telemetry/semantic-conventions/pull/285)) - Fix the unit of metric.process.runtime.jvm.system.cpu.load_1m to be {run_queue_item} ([#95](https://github.com/open-telemetry/semantic-conventions/pull/95)) - Update `.count` metric naming convention so that it only applies to UpDownCounters, diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index ae329f7e5e..43003ddc8b 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -6,7 +6,11 @@ linkTitle: Elasticsearch **Status**: [Experimental][DocumentStatus] -This document defines semantic conventions to apply when creating a span for requests to Elasticsearch. +The Semantic Conventions for [Elasticsearch](https://www.elastic.co/) extend and override the [Database Semantic Conventions](database-spans.md) +that describe common database operations attributes in addition to the Semantic Conventions +described on this page. + +`db.system` MUST be set to `"elasticsearch"`. ## Span Name @@ -30,25 +34,29 @@ in order to map the path part values to their names. **[1]:** when the url has dynamic values -## Span attributes - -`db.system` MUST be set to `"elasticsearch"`. +## Call-level attributes | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [1] | `search`; `ml.close_job`; `cat.aliases` | Required | -| [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [2] | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [4] | `example.com` | See below | -| [`server.port`](../general/attributes.md) | int | Server port number [5] | `80`; `8080`; `443` | Recommended | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [6] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | +| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | Recommended: [2] | +| [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [3] | `search`; `ml.close_job`; `cat.aliases` | Required | +| [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [4] | +| `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [6] | `example.com` | See below | +| [`server.port`](../general/attributes.md) | int | Server port number [7] | `80`; `8080`; `443` | Recommended | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [8] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | + +**[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. + +**[2]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. -**[1]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +**[3]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. -**[2]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. +**[4]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[5]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -63,12 +71,12 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. -**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[6]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[8]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. @@ -86,5 +94,7 @@ the server address behind any intermediaries (e.g. proxies) if it's available. | `db.operation` | `"search"` | | `url.full` | `"https://elasticsearch.mydomain.com:9200/my-index-000001/_search?from=40&size=20"` | | `db.elasticsearch.path_parts.index` | `"my-index-000001"` | +| `db.elasticsearch.cluster.name` | `"e9106fc68e3044f0b1475b04bf4ffd5f"` | +| `db.elasticsearch.node.name` | `"instance-0000000001"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 73f6005d08..2348a2a0f0 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -413,6 +413,7 @@ groups: note: > For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. + - id: db.mongodb prefix: db.mongodb type: span @@ -453,6 +454,24 @@ groups: examples: [ '"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"' ] - ref: server.address - ref: server.port + - id: cluster.name + type: string + requirement_level: + recommended: > + When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. + tag: call-level-tech-specific + brief: > + Represents the identifier of an Elasticsearch cluster. + examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + - id: node.name + type: string + requirement_level: + recommended: > + When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. + tag: call-level-tech-specific + brief: > + Represents the human-readable identifier of the node/instance to which a request was routed. + examples: ["instance-0000000001"] - id: db.sql prefix: 'db.sql' From d7930d3ca56dd7f0ee2de56aaefe539421a74ab5 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 11 Sep 2023 06:37:44 -0700 Subject: [PATCH 036/482] Move RPC streaming notes from metric brief section to notes section (#275) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 + docs/rpc/rpc-metrics.md | 48 +++++++++++++++++++----- model/metrics/rpc-metrics.yaml | 68 +++++++++++++++++++--------------- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fbe4268e9..f5bb6bd12a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ release. ([#276](https://github.com/open-telemetry/semantic-conventions/pull/276)) - Add host cpu resource attributes. ([#209](https://github.com/open-telemetry/semantic-conventions/pull/209)) +- Moved RPC streaming notes from metric brief section to notes section. + ([#275](https://github.com/open-telemetry/semantic-conventions/pull/275)) ## v1.21.0 (2023-07-13) diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index d431dd6652..d51e609be6 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -80,10 +80,12 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.server.duration` | Histogram | `ms` | Measures the duration of inbound RPC. **Streaming**: N/A. [1] | +| `rpc.server.duration` | Histogram | `ms` | Measures the duration of inbound RPC. [1] | **[1]:** While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. + +**Streaming**: N/A. #### Metric: `rpc.server.request.size` @@ -93,7 +95,9 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.server.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). **Streaming**: Recorded per message in a streaming batch | +| `rpc.server.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | + +**[1]:** **Streaming**: Recorded per message in a streaming batch #### Metric: `rpc.server.response.size` @@ -103,7 +107,9 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.server.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). **Streaming**: Recorded per response in a streaming batch | +| `rpc.server.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | + +**[1]:** **Streaming**: Recorded per response in a streaming batch #### Metric: `rpc.server.requests_per_rpc` @@ -113,7 +119,11 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.server.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | +| `rpc.server.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | + +**[1]:** Should be 1 for all non-streaming RPCs. + +**Streaming** : This metric is required for server and client streaming RPCs #### Metric: `rpc.server.responses_per_rpc` @@ -123,7 +133,11 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.server.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | +| `rpc.server.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | + +**[1]:** Should be 1 for all non-streaming RPCs. + +**Streaming**: This metric is required for server and client streaming RPCs ### RPC Client @@ -138,10 +152,12 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.client.duration` | Histogram | `ms` | Measures the duration of outbound RPC **Streaming**: N/A. [1] | +| `rpc.client.duration` | Histogram | `ms` | Measures the duration of outbound RPC. [1] | **[1]:** While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. + +**Streaming**: N/A. #### Metric: `rpc.client.request.size` @@ -151,7 +167,9 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.client.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). **Streaming**: Recorded per message in a streaming batch | +| `rpc.client.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | + +**[1]:** **Streaming**: Recorded per message in a streaming batch #### Metric: `rpc.client.response.size` @@ -161,7 +179,9 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.client.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). **Streaming**: Recorded per response in a streaming batch | +| `rpc.client.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | + +**[1]:** **Streaming**: Recorded per response in a streaming batch #### Metric: `rpc.client.requests_per_rpc` @@ -171,7 +191,11 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.client.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | +| `rpc.client.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | + +**[1]:** Should be 1 for all non-streaming RPCs. + +**Streaming**: This metric is required for server and client streaming RPCs #### Metric: `rpc.client.responses_per_rpc` @@ -181,7 +205,11 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `rpc.client.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. **Streaming**: This metric is required for server and client streaming RPCs | +| `rpc.client.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | + +**[1]:** Should be 1 for all non-streaming RPCs. + +**Streaming**: This metric is required for server and client streaming RPCs ## Attributes diff --git a/model/metrics/rpc-metrics.yaml b/model/metrics/rpc-metrics.yaml index 38755d4bf2..237107e6d8 100644 --- a/model/metrics/rpc-metrics.yaml +++ b/model/metrics/rpc-metrics.yaml @@ -20,96 +20,104 @@ groups: - id: metric.rpc.server.duration type: metric metric_name: rpc.server.duration - brief: > - Measures the duration of inbound RPC. - **Streaming**: N/A. + brief: Measures the duration of inbound RPC. instrument: histogram unit: "ms" note: | While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. + **Streaming**: N/A. + - id: metric.rpc.server.request.size type: metric metric_name: rpc.server.request.size - brief: > - Measures the size of RPC request messages (uncompressed). - **Streaming**: Recorded per message in a streaming batch + brief: Measures the size of RPC request messages (uncompressed). instrument: histogram unit: "By" + note: | + **Streaming**: Recorded per message in a streaming batch - id: metric.rpc.server.response.size type: metric metric_name: rpc.server.response.size - brief: > - Measures the size of RPC response messages (uncompressed). - **Streaming**: Recorded per response in a streaming batch + brief: Measures the size of RPC response messages (uncompressed). instrument: histogram unit: "By" + note: | + **Streaming**: Recorded per response in a streaming batch - id: metric.rpc.server.requests_per_rpc type: metric metric_name: rpc.server.requests_per_rpc - brief: > - Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. - **Streaming**: This metric is required for server and client streaming RPCs + brief: Measures the number of messages received per RPC. instrument: histogram unit: "{count}" + note: | + Should be 1 for all non-streaming RPCs. + + **Streaming** : This metric is required for server and client streaming RPCs - id: metric.rpc.server.responses_per_rpc type: metric metric_name: rpc.server.responses_per_rpc - brief: > - Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. - **Streaming**: This metric is required for server and client streaming RPCs + brief: Measures the number of messages sent per RPC. instrument: histogram unit: "{count}" + note: | + Should be 1 for all non-streaming RPCs. + + **Streaming**: This metric is required for server and client streaming RPCs # RPC Client metrics - id: metric.rpc.client.duration type: metric metric_name: rpc.client.duration - brief: > - Measures the duration of outbound RPC - **Streaming**: N/A. + brief: Measures the duration of outbound RPC. instrument: histogram unit: "ms" note: | While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. + **Streaming**: N/A. + - id: metric.rpc.client.request.size type: metric metric_name: rpc.client.request.size - brief: > - Measures the size of RPC request messages (uncompressed). - **Streaming**: Recorded per message in a streaming batch + brief: Measures the size of RPC request messages (uncompressed). instrument: histogram unit: "By" + note: | + **Streaming**: Recorded per message in a streaming batch - id: metric.rpc.client.response.size type: metric metric_name: rpc.client.response.size - brief: > - Measures the size of RPC response messages (uncompressed). - **Streaming**: Recorded per response in a streaming batch + brief: Measures the size of RPC response messages (uncompressed). instrument: histogram unit: "By" + note: | + **Streaming**: Recorded per response in a streaming batch - id: metric.rpc.client.requests_per_rpc type: metric metric_name: rpc.client.requests_per_rpc - brief: > - Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. - **Streaming**: This metric is required for server and client streaming RPCs + brief: Measures the number of messages received per RPC. instrument: histogram unit: "{count}" + note: | + Should be 1 for all non-streaming RPCs. + + **Streaming**: This metric is required for server and client streaming RPCs - id: metric.rpc.client.responses_per_rpc type: metric metric_name: rpc.client.responses_per_rpc - brief: > - Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. - **Streaming**: This metric is required for server and client streaming RPCs + brief: Measures the number of messages sent per RPC. instrument: histogram unit: "{count}" + note: | + Should be 1 for all non-streaming RPCs. + + **Streaming**: This metric is required for server and client streaming RPCs From 3e16365a273b325aa0dff1160a6d89bc15900124 Mon Sep 17 00:00:00 2001 From: Karming <41309630+karmingc@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:48:34 -0400 Subject: [PATCH 037/482] chore: fix doc reference to docs (#305) Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b8b2cf6f6..e1c1b8dbb9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This repository is currently using [this specification version][SpecificationVer ## Read the docs -The documentation currently resides in the [doc](docs/README.md) folder. +The documentation currently resides in the [docs](docs/README.md) folder. ## Contributing From 5f6558d259cc10b5f151e4d1230fea3ad24abb41 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 11 Sep 2023 08:19:57 -0700 Subject: [PATCH 038/482] Use `HTTP` instead of `_OTHER` in HTTP span names (if method is unknown) (#270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Trask Stalnaker Co-authored-by: Joao Grassi Co-authored-by: Christian Neumüller Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 22 ++++++++++++++++------ package.json | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5bb6bd12a..07f5034aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ release. ([#276](https://github.com/open-telemetry/semantic-conventions/pull/276)) - Add host cpu resource attributes. ([#209](https://github.com/open-telemetry/semantic-conventions/pull/209)) +- BREAKING: Change HTTP span name when method is unknown (use `HTTP` instead of `_OTHER`) + ([#270](https://github.com/open-telemetry/semantic-conventions/pull/270)) - Moved RPC streaming notes from metric brief section to notes section. ([#275](https://github.com/open-telemetry/semantic-conventions/pull/275)) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 7ea7529359..b5d828c9e6 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -62,13 +62,23 @@ and various HTTP versions like 1.1, 2 and SPDY. ## Name HTTP spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#span). -HTTP server span names SHOULD be `{http.request.method} {http.route}` if there is a -(low-cardinality) `http.route` available. -HTTP server span names SHOULD be `{http.request.method}` if there is no (low-cardinality) -`http.route` available. + + + +HTTP server span names SHOULD be `{method} {http.route}` if there is a +(low-cardinality) `http.route` available (see below for the exact definition of the [`{method}`](#method-placeholder) placeholder). + +If there is no (low-cardinality) `http.route` available, HTTP server span names +SHOULD be [`{method}`](#method-placeholder). + 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.request.method}`. +is not generally aware of the "route", and therefore HTTP client spans SHOULD be +[`{method}`](#method-placeholder). + + +The `{method}` MUST be `{http.request.method}` if the method represents the original method known to the instrumentation. +In other cases (when `{http.request.method}` is set to `_OTHER`), `{method}` MUST be `HTTP`. + 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. diff --git a/package.json b/package.json index d51304272a..90d26767c2 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "devDependencies": { "gulp": "^4.0.2", "js-yaml": "^4.1.0", - "markdown-link-check": "3.10.3", + "markdown-link-check": "^3.11.2", "markdown-toc": "^1.2.0", "markdownlint": "^0.29.0", "markdownlint-cli": "0.31.0", From 2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 11 Sep 2023 08:37:09 -0700 Subject: [PATCH 039/482] Introduce request error type attribute (#205) Co-authored-by: Joao Grassi Co-authored-by: Trask Stalnaker Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 + docs/http/http-metrics.md | 252 +++++++++++++++++++++++++++++--------- docs/http/http-spans.md | 86 +++++++++++-- model/error.yaml | 31 +++++ model/http-common.yaml | 20 +++ model/metrics/http.yaml | 40 ++++++ 6 files changed, 367 insertions(+), 64 deletions(-) create mode 100644 model/error.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 07f5034aed..5e438617ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ release. ([#276](https://github.com/open-telemetry/semantic-conventions/pull/276)) - Add host cpu resource attributes. ([#209](https://github.com/open-telemetry/semantic-conventions/pull/209)) +- Introduce `error.type` attribute and use it in HTTP conventions + ([#205](https://github.com/open-telemetry/semantic-conventions/pull/205)) - BREAKING: Change HTTP span name when method is unknown (use `HTTP` instead of `_OTHER`) ([#270](https://github.com/open-telemetry/semantic-conventions/pull/270)) - Moved RPC streaming notes from metric brief section to notes section. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e97aebdd8e..07c065f2ab 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -77,18 +77,35 @@ of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -103,9 +120,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[4]:** Determined by using the first of the following that applies +**[5]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -115,13 +132,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[5]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -224,18 +247,35 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -250,9 +290,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[4]:** Determined by using the first of the following that applies +**[5]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -262,13 +302,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[5]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -303,18 +349,35 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -329,9 +392,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[4]:** Determined by using the first of the following that applies +**[5]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -341,13 +404,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[5]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -387,15 +456,32 @@ of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.request.method` | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | -**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -410,9 +496,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[3]:** Determined by using the first of the following that applies +**[4]:** 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 @@ -420,13 +506,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[4]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -460,15 +552,32 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.request.method` | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | -**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -483,9 +592,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[3]:** Determined by using the first of the following that applies +**[4]:** 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 @@ -493,13 +602,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[4]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -533,15 +648,32 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.request.method` | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [2] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | -**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -556,9 +688,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[3]:** Determined by using the first of the following that applies +**[4]:** 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 @@ -566,13 +698,19 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[4]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[5]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index b5d828c9e6..2fa3121bb9 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -29,6 +29,9 @@ and various HTTP versions like 1.1, 2 and SPDY. * [HTTP client retries examples](#http-client-retries-examples) * [HTTP client authorization retry examples](#http-client-authorization-retry-examples) * [HTTP client redirects examples](#http-client-redirects-examples) + * [HTTP client call: DNS error](#http-client-call-dns-error) + * [HTTP client call: Internal Server Error](#http-client-call-internal-server-error) + * [HTTP server call: connection dropped before response body was sent](#http-server-call-connection-dropped-before-response-body-was-sent) @@ -98,6 +101,12 @@ failed to interpret, span status MUST be set to `Error`. Don't set the span status description if the reason can be inferred from `http.response.status_code`. +HTTP request may fail if it was cancelled or an error occurred preventing +the client or server from sending/receiving the request/response fully. + +When instrumentation detects such errors it MUST set span status to `Error` +and MUST set the `error.type` attribute. + ## Common Attributes The common attributes listed in this section apply to both HTTP clients and servers in addition to @@ -111,16 +120,33 @@ sections below. | `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [1] | | `http.request.body.size` | 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.body.size` | 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.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [4] | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [5] | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | **[1]:** If and only if it's different than `http.request.method`. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -135,14 +161,20 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[4]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). +**[5]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: * `http.request.method` +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | + `http.request.method` 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 | @@ -422,7 +454,7 @@ Span name: `GET` | Attribute name | Value | | :------------------- | :-------------------------------------------------------| | `http.request.method`| `"GET"` | -| `network.protocol.version` | `"1.1"` | +| `network.protocol.version` | `"1.1"` | | `url.full` | `"https://example.com:8080/webshop/articles/4?s=1"` | | `server.address` | `example.com` | | `server.port` | 8080 | @@ -540,4 +572,44 @@ GET /hello - 200 (CLIENT, trace=t2, span=s1, http.resend_count=1) --- server (SERVER, trace=t2, span=s2) ``` +### HTTP client call: DNS error + +As an example, if a user requested `https://does-not-exist-123.com`, we may have the following span on the client side: + +| Attribute name | Value | +| :------------------- | :-------------------------------------------------------| +| `http.request.method`| `"GET"` | +| `network.protocol.version` | `"1.1"` | +| `url.full` | `"https://does-not-exist-123.com"` | +| `server.address` | `"does-not-exist-123.com"` | +| `error.type` | `"java.net.UnknownHostException"` | + +### HTTP client call: Internal Server Error + +As an example, if a user requested `https://example.com` and server returned 500, we may have the following span on the client side: + +| Attribute name | Value | +| :------------------- | :-------------------------------------------------------| +| `http.request.method`| `"GET"` | +| `network.protocol.version` | `"1.1"` | +| `url.full` | `"https://example.com"` | +| `server.address` | `"example.com"` | +| `http.response.status_code` | `500` | +| `error.type` | `"500"` | + +### HTTP server call: connection dropped before response body was sent + +As an example, if a user sent a `POST` request with a body to `https://example.com:8080/uploads/4`, we may see the following span on a server side: + +Span name: `POST /uploads/:document_id`. + +| Attribute name | Value | +| :------------------- | :---------------------------------------------- | +| `http.request.method`| `"GET"` | +| `url.path` | `"/uploads/4"` | +| `url.scheme` | `"https"` | +| `http.route` | `"/uploads/:document_id"` | +| `http.response.status_code` | `201` | +| `error.type` | `WebSocketDisconnect` | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/error.yaml b/model/error.yaml new file mode 100644 index 0000000000..cdfc587800 --- /dev/null +++ b/model/error.yaml @@ -0,0 +1,31 @@ +groups: + - id: error + type: attribute_group + prefix: error + brief: > + This document defines the shared attributes used to + report an error. + attributes: + - id: type + brief: 'Describes a class of error the operation ended with.' + type: + allow_custom_values: true + members: + - id: other + value: "_OTHER" + brief: 'A fallback error value to be used when the instrumentation does not define a custom value for it.' + examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] + note: | + The `error.type` SHOULD be predictable and SHOULD have low cardinality. + Instrumentations SHOULD document the list of errors they report. + + The cardinality of `error.type` within one instrumentation library SHOULD be low, but + telemetry consumers that aggregate data from multiple instrumentation libraries and applications + should be prepared for `error.type` to have high cardinality at query time, when no + additional filters are applied. + + If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + + If a specific domain defines its own set of error codes (such as HTTP or gRPC status codes), + it's RECOMMENDED to use a domain-specific attribute and also set `error.type` to capture + all errors, regardless of whether they are defined within the domain-specific set or not. diff --git a/model/http-common.yaml b/model/http-common.yaml index 2b481800e1..b6643676db 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -62,6 +62,26 @@ groups: 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] + - ref: error.type + requirement_level: + conditionally_required: If request has ended with an error. + examples: ['timeout', 'name_resolution_error', '500'] + note: | + If the request fails with an error before response status code was sent or received, + `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + + If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), + `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + + The `error.type` value SHOULD be predictable and SHOULD have low cardinality. + Instrumentations SHOULD document the list of errors they report. + + The cardinality of `error.type` within one instrumentation library SHOULD be low, but + telemetry consumers that aggregate data from multiple instrumentation libraries and applications + should be prepared for `error.type` to have high cardinality at query time, when no + additional filters are applied. + + If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: network.protocol.name examples: ['http', 'spdy'] requirement_level: diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 34d6baaa2d..f6354aa7d5 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -31,6 +31,26 @@ groups: if it's sent in absolute-form. - Port identifier of the `Host` header # todo (lmolkova) build tools don't populate grandparent attributes + - ref: error.type + requirement_level: + conditionally_required: If request has ended with an error. + examples: ['timeout', 'name_resolution_error', '500'] + note: | + If the request fails with an error before response status code was sent or received, + `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + + If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), + `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + + The `error.type` value SHOULD be predictable and SHOULD have low cardinality. + Instrumentations SHOULD document the list of errors they report. + + The cardinality of `error.type` within one instrumentation library SHOULD be low, but + telemetry consumers that aggregate data from multiple instrumentation libraries and applications + should be prepared for `error.type` to have high cardinality at query time, when no + additional filters are applied. + + If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: http.request.method - ref: http.response.status_code - ref: network.protocol.name @@ -47,6 +67,26 @@ groups: - ref: network.protocol.name - ref: network.protocol.version - ref: server.socket.address + - ref: error.type + requirement_level: + conditionally_required: If request has ended with an error. + examples: ['timeout', 'name_resolution_error', '500'] + note: | + If the request fails with an error before response status code was sent or received, + `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + + If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), + `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + + The `error.type` value SHOULD be predictable and SHOULD have low cardinality. + Instrumentations SHOULD document the list of errors they report. + + The cardinality of `error.type` within one instrumentation library SHOULD be low, but + telemetry consumers that aggregate data from multiple instrumentation libraries and applications + should be prepared for `error.type` to have high cardinality at query time, when no + additional filters are applied. + + If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - id: metric.http.server.request.duration type: metric From db3a9aaf669aded5696a26f57c74703a97e6f3c6 Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Mon, 11 Sep 2023 20:34:49 +0200 Subject: [PATCH 040/482] [.github/CODEOWNERS] Add semconv system approvers (#309) Co-authored-by: Reiley Yang --- .github/CODEOWNERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 67fd007ee9..0c016ce011 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -35,4 +35,10 @@ /model/metrics/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers /model/trace/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +# System semantic conventions approvers +/docs/system/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers +/model/metrics/system-* @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers +/docs/resource/host.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers +/model/resource/host.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers + # TODO - Add semconv area experts From d80c8e317ff8709cb6dc85dc6cd9472f153e81dc Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Tue, 12 Sep 2023 16:54:28 +0200 Subject: [PATCH 041/482] BREAKING: Generate System metrics semconv from YAML + move attributes to their own namespace (#89) Co-authored-by: Armin Ruech Co-authored-by: Pablo Baeyens --- CHANGELOG.md | 27 + docs/system/system-metrics.md | 840 ++++++++++++++++++++++++------ model/metrics/system-metrics.yaml | 492 +++++++++++++++++ schema-next.yaml | 64 +++ 4 files changed, 1277 insertions(+), 146 deletions(-) create mode 100644 model/metrics/system-metrics.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e438617ba..4612cb77e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,33 @@ release. ([#270](https://github.com/open-telemetry/semantic-conventions/pull/270)) - Moved RPC streaming notes from metric brief section to notes section. ([#275](https://github.com/open-telemetry/semantic-conventions/pull/275)) +- BREAKING: Generate System metrics semconv from YAML. + ([#89](https://github.com/open-telemetry/semantic-conventions/pull/89)) + - Rename attributes for `system.cpu.*` metrics: + - `state` to `system.cpu.state` + - `cpu` to `system.cpu.logical_number` + - Rename attributes for `system.memory.*` metrics: + - `state` to `system.memory.state` + - Rename attributes for `system.paging.*` metrics: + - `state` to `system.paging.state` + - `type` to `system.paging.type` + - `direction` to `system.paging.direction` + - Rename attributes for `system.disk.*` metrics: + - `device` to `system.device` + - `direction` to `system.disk.direction` + - Rename attributes for `system.filesystem.*` metrics: + - `device` to `system.device` + - `state` to `system.filesystem.state` + - `type` to `system.filesystem.type` + - `mode` to `system.filesystem.mode` + - `mountpoint` to `system.filesystem.mountpoint` + - Rename attributes for `system.network.*` metrics: + - `device` to `system.device` + - `direction` to `system.network.direction` + - `protocol` to `network.protocol` + - `state` to `system.network.state` + - Rename attributes for `system.processes.*` metrics: + - `status` to `system.processes.status` ## v1.21.0 (2023-07-13) diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 2f71ef86af..f17b799050 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -15,154 +15,701 @@ instruments not explicitly defined in the specification. -- [Metric Instruments](#metric-instruments) - * [`system.cpu.` - Processor metrics](#systemcpu---processor-metrics) - * [`system.memory.` - Memory metrics](#systemmemory---memory-metrics) - * [`system.paging.` - Paging/swap metrics](#systempaging---pagingswap-metrics) - * [`system.disk.` - Disk controller metrics](#systemdisk---disk-controller-metrics) - * [`system.filesystem.` - Filesystem metrics](#systemfilesystem---filesystem-metrics) - * [`system.network.` - Network metrics](#systemnetwork---network-metrics) - * [`system.processes.` - Aggregate system process metrics](#systemprocesses---aggregate-system-process-metrics) - * [`system.{os}.` - OS Specific System Metrics](#systemos---os-specific-system-metrics) +- [Processor Metrics](#processor-metrics) + * [Metric: `system.cpu.time`](#metric-systemcputime) + * [Metric: `system.cpu.utilization`](#metric-systemcpuutilization) + * [Metric: `system.cpu.physical.count`](#metric-systemcpuphysicalcount) + * [Metric: `system.cpu.logical.count`](#metric-systemcpulogicalcount) +- [Memory Metrics](#memory-metrics) + * [Metric: `system.memory.usage`](#metric-systemmemoryusage) + * [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) +- [Paging/Swap Metrics](#pagingswap-metrics) + * [Metric: `system.paging.usage`](#metric-systempagingusage) + * [Metric: `system.paging.utilization`](#metric-systempagingutilization) + * [Metric: `system.paging.faults`](#metric-systempagingfaults) + * [Metric: `system.paging.operations`](#metric-systempagingoperations) +- [Disk Controller Metrics](#disk-controller-metrics) + * [Metric: `system.disk.io`](#metric-systemdiskio) + * [Metric: `system.disk.operations`](#metric-systemdiskoperations) + * [Metric: `system.disk.io_time`](#metric-systemdiskio_time) + * [Metric: `system.disk.operation_time`](#metric-systemdiskoperation_time) + * [Metric: `system.disk.merged`](#metric-systemdiskmerged) +- [Filesystem Metrics](#filesystem-metrics) + * [Metric: `system.filesystem.usage`](#metric-systemfilesystemusage) + * [Metric: `system.filesystem.utilization`](#metric-systemfilesystemutilization) +- [Network Metrics](#network-metrics) + * [Metric: `system.network.dropped`](#metric-systemnetworkdropped) + * [Metric: `system.network.packets`](#metric-systemnetworkpackets) + * [Metric: `system.network.errors`](#metric-systemnetworkerrors) + * [Metric: `system.network.io`](#metric-systemnetworkio) + * [Metric: `system.network.connections`](#metric-systemnetworkconnections) +- [Aggregate System Process Metrics](#aggregate-system-process-metrics) + * [Metric: `system.processes.count`](#metric-systemprocessescount) + * [Metric: `system.processes.created`](#metric-systemprocessescreated) +- [`system.{os}.` - OS Specific System Metrics](#systemos---os-specific-system-metrics) -## Metric Instruments - -### `system.cpu.` - Processor metrics - -**Description:** System level processor metrics. - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key(s) | Attribute Values | -| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----- | ------------------------------------------------- | ---------- | ---------------- | ----------------------------------- | -| system.cpu.time | Seconds each logical CPU spent on each mode | s | Counter | Double | state | idle, user, system, interrupt, etc. | -| | | | | | cpu | Logical CPU number [0..n-1] | -| system.cpu.utilization | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs | 1 | Gauge | Double | state | idle, user, system, interrupt, etc. | -| | | | | | cpu | Logical CPU number (0..n) | -| system.cpu.physical.count | Reports the number of actual physical processor cores on the hardware | {cpu} | UpDownCounter | Int64 | | | -| system.cpu.logical.count | Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking | {cpu} | UpDownCounter | Int64 | | | - -### `system.memory.` - Memory metrics - -**Description:** System level memory metrics. This does not include [paging/swap -memory](#systempaging---pagingswap-metrics). - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -| ------------------------- | ----------- | ----- | ------------------------------------------------- | ---------- | ------------- | ------------------------ | -| system.memory.usage | | By | UpDownCounter | Int64 | state | used, free, cached, etc. | -| system.memory.utilization | | 1 | Gauge | Double | state | used, free, cached, etc. | - -### `system.paging.` - Paging/swap metrics - -**Description:** System level paging/swap memory metrics. - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -|---------------------------|-------------------------------------|--------------|---------------------------------------------------|------------|---------------|------------------| -| system.paging.usage | Unix swap or windows pagefile usage | By | UpDownCounter | Int64 | state | used, free | -| system.paging.utilization | | 1 | Gauge | Double | state | used, free | -| system.paging.faults | | {fault} | Counter | Int64 | type | major, minor | -| system.paging.operations | | {operation} | Counter | Int64 | type | major, minor | -| | | | | | direction | in, out | - -### `system.disk.` - Disk controller metrics - -**Description:** System level disk performance metrics. - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -|--------------------------------------------|-------------------------------------------------|--------------|---------------------------------------------------|------------|---------------|------------------| -| system.disk.io | | By | Counter | Int64 | device | (identifier) | -| | | | | | direction | read, write | -| system.disk.operations | | {operation} | Counter | Int64 | device | (identifier) | -| | | | | | direction | read, write | -| system.disk.io_time\[1\] | Time disk spent activated | s | Counter | Double | device | (identifier) | -| system.disk.operation_time\[2\] | Sum of the time each operation took to complete | s | Counter | Double | device | (identifier) | -| | | | | | direction | read, write | -| system.disk.merged | | {operation} | Counter | Int64 | device | (identifier) | -| | | | | | direction | read, write | - -1 The real elapsed time ("wall clock") -used in the I/O path (time from operations running in parallel are not -counted). Measured as: - -- Linux: Field 13 from -[procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) -- Windows: The complement of ["Disk\% Idle -Time"](https://docs.microsoft.com/en-us/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained:~:text=%25%20Idle%20Time,Idle\)%20to%200%20(meaning%20always%20busy).) -performance counter: `uptime * (100 - "Disk\% Idle Time") / 100` - -2 Because it is the sum of time each -request took, parallel-issued requests each contribute to make the count -grow. Measured as: - -- Linux: Fields 7 & 11 from -[procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) -- Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" -perf counter (similar for Writes) - -### `system.filesystem.` - Filesystem metrics - -**Description:** System level filesystem metrics. - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -| ----------------------------- | ----------- | ----- | ------------------------------------------------- | ---------- | ------------- | -------------------- | -| system.filesystem.usage | | By | UpDownCounter | Int64 | device | (identifier) | -| | | | | | state | used, free, reserved | -| | | | | | type | ext4, tmpfs, etc. | -| | | | | | mode | rw, ro, etc. | -| | | | | | mountpoint | (path) | -| system.filesystem.utilization | | 1 | Gauge | Double | device | (identifier) | -| | | | | | state | used, free, reserved | -| | | | | | type | ext4, tmpfs, etc. | -| | | | | | mode | rw, ro, etc. | -| | | | | | mountpoint | (path) | - -### `system.network.` - Network metrics - -**Description:** System level network metrics. - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -|----------------------------------------|-------------------------------------------------------------------------------|---------------|---------------------------------------------------|------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| system.network.dropped\[1\] | Count of packets that are dropped or discarded even though there was no error | {packet} | Counter | Int64 | device | (identifier) | -| | | | | | direction | transmit, receive | -| system.network.packets | | {packet} | Counter | Int64 | device | (identifier) | -| | | | | | direction | transmit, receive | -| system.network.errors\[2\] | Count of network errors detected | {error} | Counter | Int64 | device | (identifier) | -| | | | | | direction | transmit, receive | -| system.network.io | | By | Counter | Int64 | device | (identifier) | -| | | | | | direction | transmit, receive | -| system.network.connections | | {connection} | UpDownCounter | Int64 | device | (identifier) | -| | | | | | protocol | tcp, udp, [etc.](https://en.wikipedia.org/wiki/Transport_layer#Protocols) | -| | | | | | state | If specified, SHOULD be one of: close, close_wait, closing, delete, established, fin_wait_1, fin_wait_2, last_ack, listen, syn_recv, syn_sent, time_wait. A stateless protocol MUST NOT set this attribute. | - -1 Measured as: - -- Linux: the `drop` column in `/proc/dev/net` -([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). -- Windows: -[`InDiscards`/`OutDiscards`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) -from -[`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). - -2 Measured as: - -- Linux: the `errs` column in `/proc/dev/net` -([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). -- Windows: -[`InErrors`/`OutErrors`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) -from -[`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). - -### `system.processes.` - Aggregate system process metrics - -**Description:** System level aggregate process metrics. For metrics at the -individual process level, see [process metrics](process-metrics.md). - -| Name | Description | Units | Instrument Type ([*](/docs/general/metrics.md#instrument-types)) | Value Type | Attribute Key | Attribute Values | -| ------------------------ | --------------------------------------------------------- | ----------- | ------------------------------------------------- | ---------- | ------------- | ---------------------------------------------------------------------------------------------- | -| system.processes.count | Total number of processes in each state | {process} | UpDownCounter | Int64 | status | running, sleeping, [etc.](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | -| system.processes.created | Total number of processes created over uptime of the host | {process} | Counter | Int64 | - | - | - -### `system.{os}.` - OS Specific System Metrics +## Processor Metrics + +**Description:** System level processor metrics captured under the namespace `system.cpu`. + +### Metric: `system.cpu.time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.cpu.time` | Counter | `s` | Seconds each logical CPU spent on each mode | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | +| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | Recommended | + +`system.cpu.state` 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 | +|---|---| +| `user` | user | +| `system` | system | +| `nice` | nice | +| `idle` | idle | +| `iowait` | iowait | +| `interrupt` | interrupt | +| `steal` | steal | + + +### Metric: `system.cpu.utilization` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.cpu.utilization` | Gauge | `1` | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | +| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | Recommended | + +`system.cpu.state` 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 | +|---|---| +| `user` | user | +| `system` | system | +| `nice` | nice | +| `idle` | idle | +| `iowait` | iowait | +| `interrupt` | interrupt | +| `steal` | steal | + + +### Metric: `system.cpu.physical.count` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.cpu.physical.count` | UpDownCounter | `{cpu}` | Reports the number of actual physical processor cores on the hardware | + + + + + +### Metric: `system.cpu.logical.count` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.cpu.logical.count` | UpDownCounter | `{cpu}` | Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking | + + + + + +## Memory Metrics + +**Description:** System level memory metrics capture under the namespace `system.memory`. +This does not include [paging/swap memory](#pagingswap-metrics). + +### Metric: `system.memory.usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.memory.usage` | UpDownCounter | `By` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.memory.state` | string | The memory state | `free`; `cached` | Recommended | + +`system.memory.state` 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 | +|---|---| +| `total` | total | +| `used` | used | +| `free` | free | +| `shared` | shared | +| `buffers` | buffers | +| `cached` | cached | + + +### Metric: `system.memory.utilization` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.memory.utilization` | Gauge | `1` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.memory.state` | string | The memory state | `free`; `cached` | Recommended | + +`system.memory.state` 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 | +|---|---| +| `total` | total | +| `used` | used | +| `free` | free | +| `shared` | shared | +| `buffers` | buffers | +| `cached` | cached | + + +## Paging/Swap Metrics + +**Description:** System level paging/swap memory metrics captured under the namespace `system.paging`. + +### Metric: `system.paging.usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.paging.usage` | UpDownCounter | `By` | Unix swap or windows pagefile usage | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.paging.state` | string | The memory paging state | `free` | Recommended | + +`system.paging.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `used` | used | +| `free` | free | + + +### Metric: `system.paging.utilization` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.paging.utilization` | Gauge | `1` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.paging.state` | string | The memory paging state | `free` | Recommended | + +`system.paging.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `used` | used | +| `free` | free | + + +### Metric: `system.paging.faults` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.paging.faults` | Counter | `{fault}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.paging.type` | string | The memory paging type | `minor` | Recommended | + +`system.paging.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `major` | major | +| `minor` | minor | + + +### Metric: `system.paging.operations` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.paging.operations` | Counter | `{operation}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.paging.direction` | string | The paging access direction | `in` | Recommended | +| `system.paging.type` | string | The memory paging type | `minor` | Recommended | + +`system.paging.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `in` | in | +| `out` | out | + +`system.paging.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `major` | major | +| `minor` | minor | + + +## Disk Controller Metrics + +**Description:** System level disk performance metrics captured under the namespace `system.disk`. + +### Metric: `system.disk.io` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.disk.io` | Counter | `By` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | + +`system.disk.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +### Metric: `system.disk.operations` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.disk.operations` | Counter | `{operation}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | + +`system.disk.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +### Metric: `system.disk.io_time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.disk.io_time` | Counter | `s` | Time disk spent activated [1] | + +**[1]:** The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not counted). Measured as: + +- Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) +- Windows: The complement of + ["Disk\% Idle Time"](https://learn.microsoft.com/en-us/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) + performance counter: `uptime * (100 - "Disk\% Idle Time") / 100` + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | + + +### Metric: `system.disk.operation_time` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.disk.operation_time` | Counter | `s` | Sum of the time each operation took to complete [1] | + +**[1]:** Because it is the sum of time each request took, parallel-issued requests each contribute to make the count grow. Measured as: + +- Linux: Fields 7 & 11 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) +- Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" perf counter (similar for Writes) + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | + +`system.disk.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +### Metric: `system.disk.merged` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.disk.merged` | Counter | `{operation}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | + +`system.disk.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +## Filesystem Metrics + +**Description:** System level filesystem metrics captured under the namespace `system.filesystem`. + +### Metric: `system.filesystem.usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.filesystem.usage` | UpDownCounter | `By` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | Recommended | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | Recommended | +| `system.filesystem.state` | string | The filesystem state | `used` | Recommended | +| `system.filesystem.type` | string | The filesystem type | `ext4` | Recommended | + +`system.filesystem.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `used` | used | +| `free` | free | +| `reserved` | reserved | + +`system.filesystem.type` 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 | +|---|---| +| `fat32` | fat32 | +| `exfat` | exfat | +| `ntfs` | ntfs | +| `refs` | refs | +| `hfsplus` | hfsplus | +| `ext4` | ext4 | + + +### Metric: `system.filesystem.utilization` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.filesystem.utilization` | Gauge | `1` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | Recommended | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | Recommended | +| `system.filesystem.state` | string | The filesystem state | `used` | Recommended | +| `system.filesystem.type` | string | The filesystem type | `ext4` | Recommended | + +`system.filesystem.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `used` | used | +| `free` | free | +| `reserved` | reserved | + +`system.filesystem.type` 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 | +|---|---| +| `fat32` | fat32 | +| `exfat` | exfat | +| `ntfs` | ntfs | +| `refs` | refs | +| `hfsplus` | hfsplus | +| `ext4` | ext4 | + + +## Network Metrics + +**Description:** System level network metrics captured under the namespace `system.network`. + +### Metric: `system.network.dropped` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.network.dropped` | Counter | `{packet}` | Count of packets that are dropped or discarded even though there was no error [1] | + +**[1]:** Measured as: + +- Linux: the `drop` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) +- Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2) + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.network.direction` | string | | `transmit` | Recommended | + +`system.network.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +### Metric: `system.network.packets` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.network.packets` | Counter | `{packet}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.network.direction` | string | | `transmit` | Recommended | + +`system.network.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +### Metric: `system.network.errors` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.network.errors` | Counter | `{error}` | Count of network errors detected [1] | + +**[1]:** Measured as: + +- Linux: the `errs` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). +- Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.network.direction` | string | | `transmit` | Recommended | + +`system.network.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +### Metric: `system.network.io` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.network.io` | Counter | `By` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.network.direction` | string | | `transmit` | Recommended | + +`system.network.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +### Metric: `system.network.connections` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.network.connections` | UpDownCounter | `{connection}` | | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. See note below. | +| `unix` | Unix domain socket | + +`system.network.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `close` | close | +| `close_wait` | close_wait | +| `closing` | closing | +| `delete` | delete | +| `established` | established | +| `fin_wait_1` | fin_wait_1 | +| `fin_wait_2` | fin_wait_2 | +| `last_ack` | last_ack | +| `listen` | listen | +| `syn_recv` | syn_recv | +| `syn_sent` | syn_sent | +| `time_wait` | time_wait | + +## Aggregate System Process Metrics + +**Description:** System level aggregate process metrics captured under the namespace `system.process`. +For metrics at the individual process level, see [process metrics](process-metrics.md). + +### Metric: `system.processes.count` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.processes.count` | UpDownCounter | `{process}` | Total number of processes in each state | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.processes.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | Recommended | + +`system.processes.status` 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 | +|---|---| +| `running` | running | +| `sleeping` | sleeping | +| `stopped` | stopped | +| `defunct` | defunct | + + +### Metric: `system.processes.created` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.processes.created` | Counter | `{process}` | Total number of processes created over uptime of the host | + + + + + +## `system.{os}.` - OS Specific System Metrics Instrument names for system level metrics that have different and conflicting meaning across multiple OSes should be prefixed with `system.{os}.` and @@ -190,4 +737,5 @@ An instrument for load average over 1 minute on Linux could be named `system.linux.cpu.load_1m`, reusing the `cpu` name proposed above and having an `{os}` prefix to split this metric across OSes. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml new file mode 100644 index 0000000000..41c508f3d2 --- /dev/null +++ b/model/metrics/system-metrics.yaml @@ -0,0 +1,492 @@ +groups: + # General system attributes + - id: attributes.system + prefix: system + type: attribute_group + brief: "Describes System metric attributes" + attributes: + - id: device + type: string + brief: "The device identifier" + examples: ["(identifier)"] + + # system.cpu.* metrics and attribute group + - id: attributes.system.cpu + prefix: system.cpu + type: attribute_group + brief: "Describes System CPU metric attributes" + attributes: + - id: state + type: + allow_custom_values: true + members: + - id: user + value: 'user' + - id: system + value: 'system' + - id: nice + value: 'nice' + - id: idle + value: 'idle' + - id: iowait + value: 'iowait' + - id: interrupt + value: 'interrupt' + - id: steal + value: 'steal' + brief: "The state of the CPU" + examples: ["idle", "interrupt"] + - id: logical_number + type: int + brief: "The logical CPU number [0..n-1]" + examples: [1] + + - id: metric.system.cpu.time + type: metric + metric_name: system.cpu.time + brief: "Seconds each logical CPU spent on each mode" + instrument: counter + unit: "s" + attributes: + - ref: system.cpu.state + - ref: system.cpu.logical_number + + - id: metric.system.cpu.utilization + type: metric + metric_name: system.cpu.utilization + brief: "Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs" + instrument: gauge + unit: "1" + attributes: + - ref: system.cpu.state + - ref: system.cpu.logical_number + + - id: metric.system.cpu.physical.count + type: metric + metric_name: system.cpu.physical.count + brief: "Reports the number of actual physical processor cores on the hardware" + instrument: updowncounter + unit: "{cpu}" + attributes: [] + + - id: metric.system.cpu.logical.count + type: metric + metric_name: system.cpu.logical.count + brief: "Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking" + instrument: updowncounter + unit: "{cpu}" + attributes: [] + + # sytem.memory.* metrics and attribute group + - id: attributes.system.memory + prefix: system.memory + type: attribute_group + brief: "Describes System Memory metric attributes" + attributes: + - id: state + type: + allow_custom_values: true + members: + - id: total + value: 'total' + - id: used + value: 'used' + - id: free + value: 'free' + - id: shared + value: 'shared' + - id: buffers + value: 'buffers' + - id: cached + value: 'cached' + brief: "The memory state" + examples: ["free", "cached"] + + - id: metric.system.memory.usage + type: metric + metric_name: system.memory.usage + brief: "" + instrument: updowncounter + unit: "By" + attributes: + - ref: system.memory.state + + - id: metric.system.memory.utilization + type: metric + metric_name: system.memory.utilization + brief: "" + instrument: gauge + unit: "1" + attributes: + - ref: system.memory.state + + # system.paging.* metrics and attribute group + - id: attributes.system.paging + prefix: system.paging + type: attribute_group + brief: "Describes System Memory Paging metric attributes" + attributes: + - id: state + type: + allow_custom_values: false + members: + - id: used + value: 'used' + - id: free + value: 'free' + brief: "The memory paging state" + examples: ["free"] + - id: type + type: + allow_custom_values: false + members: + - id: major + value: 'major' + - id: minor + value: 'minor' + brief: "The memory paging type" + examples: ["minor"] + - id: direction + type: + allow_custom_values: false + members: + - id: in + value: 'in' + - id: out + value: 'out' + brief: "The paging access direction" + examples: ["in"] + - id: metric.system.paging.usage + type: metric + metric_name: system.paging.usage + brief: "Unix swap or windows pagefile usage" + instrument: updowncounter + unit: "By" + attributes: + - ref: system.paging.state + + - id: metric.system.paging.utilization + type: metric + metric_name: system.paging.utilization + brief: "" + instrument: gauge + unit: "1" + attributes: + - ref: system.paging.state + + - id: metric.system.paging.faults + type: metric + metric_name: system.paging.faults + brief: "" + instrument: counter + unit: "{fault}" + attributes: + - ref: system.paging.type + + - id: metric.system.paging.operations + type: metric + metric_name: system.paging.operations + brief: "" + instrument: counter + unit: "{operation}" + attributes: + - ref: system.paging.type + - ref: system.paging.direction + + # system.disk.* metrics and attribute group + - id: attributes.system.disk + prefix: system.disk + type: attribute_group + brief: "Describes System Disk metric attributes" + attributes: + - id: direction + type: + allow_custom_values: false + members: + - id: read + value: 'read' + - id: write + value: 'write' + brief: "The disk operation direction" + examples: ["read"] + + - id: metric.system.disk.io + type: metric + metric_name: system.disk.io + brief: "" + instrument: counter + unit: "By" + attributes: + - ref: system.device + - ref: system.disk.direction + + - id: metric.system.disk.operations + type: metric + metric_name: system.disk.operations + brief: "" + instrument: counter + unit: "{operation}" + attributes: + - ref: system.device + - ref: system.disk.direction + + - id: metric.system.disk.io_time + type: metric + metric_name: system.disk.io_time + brief: "Time disk spent activated" + instrument: counter + unit: "s" + note: | + The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not counted). Measured as: + + - Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) + - Windows: The complement of + ["Disk\% Idle Time"](https://learn.microsoft.com/en-us/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) + performance counter: `uptime * (100 - "Disk\% Idle Time") / 100` + attributes: + - ref: system.device + + - id: metric.system.disk.operation_time + type: metric + metric_name: system.disk.operation_time + brief: "Sum of the time each operation took to complete" + instrument: counter + unit: "s" + note: | + Because it is the sum of time each request took, parallel-issued requests each contribute to make the count grow. Measured as: + + - Linux: Fields 7 & 11 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) + - Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" perf counter (similar for Writes) + attributes: + - ref: system.device + - ref: system.disk.direction + + - id: metric.system.disk.merged + type: metric + metric_name: system.disk.merged + brief: "" + instrument: counter + unit: "{operation}" + attributes: + - ref: system.device + - ref: system.disk.direction + + # system.filesystem.* metrics and attribute group + - id: attributes.system.filesystem + prefix: system.filesystem + type: attribute_group + brief: "Describes Filesystem metric attributes" + attributes: + - id: state + brief: "The filesystem state" + type: + allow_custom_values: false + members: + - id: used + value: 'used' + - id: free + value: 'free' + - id: reserved + value: 'reserved' + examples: ["used"] + - id: type + type: + allow_custom_values: true + members: + - id: fat32 + value: 'fat32' + - id: exfat + value: 'exfat' + - id: ntfs + value: 'ntfs' + - id: refs + value: 'refs' + - id: hfsplus + value: 'hfsplus' + - id: ext4 + value: 'ext4' + brief: "The filesystem type" + examples: ["ext4"] + - id: mode + type: string + brief: "The filesystem mode" + examples: ["rw, ro"] + - id: mountpoint + type: string + brief: "The filesystem mount path" + examples: ["/mnt/data"] + + - id: metric.system.filesystem.usage + type: metric + metric_name: system.filesystem.usage + brief: "" + instrument: updowncounter + unit: "By" + attributes: + - ref: system.device + - ref: system.filesystem.state + - ref: system.filesystem.type + - ref: system.filesystem.mode + - ref: system.filesystem.mountpoint + + - id: metric.system.filesystem.utilization + type: metric + metric_name: system.filesystem.utilization + brief: "" + instrument: gauge + unit: "1" + attributes: + - ref: system.device + - ref: system.filesystem.state + - ref: system.filesystem.type + - ref: system.filesystem.mode + - ref: system.filesystem.mountpoint + + # system.network.* metrics and attribute group + - id: attributes.system.network + prefix: system.network + type: attribute_group + brief: "Describes Network metric attributes" + attributes: + - id: direction + type: + allow_custom_values: false + members: + - id: transmit + value: 'transmit' + - id: receive + value: 'receive' + brief: "" + examples: ["transmit"] + - id: state + type: + allow_custom_values: false + members: + - id: close + value: 'close' + - id: close_wait + value: 'close_wait' + - id: closing + value: 'closing' + - id: delete + value: 'delete' + - id: established + value: 'established' + - id: fin_wait_1 + value: 'fin_wait_1' + - id: fin_wait_2 + value: 'fin_wait_2' + - id: last_ack + value: 'last_ack' + - id: listen + value: 'listen' + - id: syn_recv + value: 'syn_recv' + - id: syn_sent + value: 'syn_sent' + - id: time_wait + value: 'time_wait' + brief: "A stateless protocol MUST NOT set this attribute" + examples: ["close_wait"] + + - id: metric.system.network.dropped + type: metric + metric_name: system.network.dropped + brief: "Count of packets that are dropped or discarded even though there was no error" + instrument: counter + unit: "{packet}" + note: | + Measured as: + + - Linux: the `drop` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) + - Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2) + attributes: + - ref: system.device + - ref: system.network.direction + + - id: metric.system.network.packets + type: metric + metric_name: system.network.packets + brief: "" + instrument: counter + unit: "{packet}" + attributes: + - ref: system.device + - ref: system.network.direction + + - id: metric.system.network.errors + type: metric + metric_name: system.network.errors + brief: "Count of network errors detected" + instrument: counter + unit: "{error}" + note: | + Measured as: + + - Linux: the `errs` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). + - Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). + attributes: + - ref: system.device + - ref: system.network.direction + + - id: metric.system.network.io + type: metric + metric_name: system.network.io + brief: "" + instrument: counter + unit: "By" + attributes: + - ref: system.device + - ref: system.network.direction + + - id: metric.system.network.connections + type: metric + metric_name: system.network.connections + brief: "" + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: system.device + - ref: system.network.state + - ref: network.transport + + # system.processes.* metrics and attribute group + - id: attributes.system.processes + prefix: system.processes + type: attribute_group + brief: "Describes System Process metric attributes" + attributes: + - id: status + type: + allow_custom_values: true + members: + - id: running + value: 'running' + - id: sleeping + value: 'sleeping' + - id: stopped + value: 'stopped' + - id: defunct + value: 'defunct' + brief: > + The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) + examples: ["running"] + + + - id: metric.system.processes.count + type: metric + metric_name: system.processes.count + brief: "Total number of processes in each state" + instrument: updowncounter + unit: "{process}" + attributes: + - ref: system.processes.status + + - id: metric.system.processes.created + type: metric + metric_name: system.processes.created + brief: "Total number of processes created over uptime of the host" + instrument: counter + unit: "{process}" diff --git a/schema-next.yaml b/schema-next.yaml index acc97ca7b8..609605b787 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -63,6 +63,70 @@ versions: - jvm.buffer.usage - jvm.buffer.limit - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count 1.21.0: spans: changes: From 48dc44c31ba8132b8d02e4452cf7bca972d637fb Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 12 Sep 2023 18:55:20 +0300 Subject: [PATCH 042/482] Bump semantic conventions tooling to v0.21.0 (#310) Co-authored-by: Armin Ruech --- .vscode/settings.json | 2 +- Makefile | 2 +- internal/tools/schema_check.sh | 2 +- model/README.md | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 89d895f2f4..6b792056bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "MD040": false, }, "yaml.schemas": { - "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.20.0/semantic-conventions/semconv.schema.json": [ + "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.21.0/semantic-conventions/semconv.schema.json": [ "semantic_conventions/**/*.yaml" ] }, diff --git a/Makefile b/Makefile index 0a7bed5ae5..a87243775e 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! -SEMCONVGEN_VERSION=0.20.0 +SEMCONVGEN_VERSION=0.21.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index 179ca4087b..f89a391e2b 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -6,7 +6,7 @@ set -e -BUILD_TOOL_SCHEMAS_VERSION=0.20.0 +BUILD_TOOL_SCHEMAS_VERSION=0.21.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") diff --git a/model/README.md b/model/README.md index b8afe3e506..b80573074f 100644 --- a/model/README.md +++ b/model/README.md @@ -14,12 +14,12 @@ Semantic conventions for the spec MUST adhere to the [attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-requirement-level.md), and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md) conventions. -Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions/syntax.md) +Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. A schema file for VS code is configured in the `/.vscode/settings.json` of this repository, enabling auto-completion and additional checks. Refer to -[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions/README.md) for what extension you need. +[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions/README.md) for what extension you need. ## Generating markdown @@ -30,7 +30,7 @@ formatted Markdown tables for all semantic conventions in the specification. Run make table-generation ``` -For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.20.0/semantic-conventions) +For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions) in the OpenTelemetry build tools repository. Using this build tool, it is also possible to generate code for use in OpenTelemetry language projects. From 58c52c59bae610f637cff57541aeb55d29788573 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 12 Sep 2023 09:01:35 -0700 Subject: [PATCH 043/482] Update client address to be consistent with server address (#302) Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 ++ docs/general/attributes.md | 2 +- docs/http/http-spans.md | 2 +- docs/rpc/rpc-spans.md | 2 +- model/client.yaml | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4612cb77e9..96acda87f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,8 @@ release. ([#270](https://github.com/open-telemetry/semantic-conventions/pull/270)) - Moved RPC streaming notes from metric brief section to notes section. ([#275](https://github.com/open-telemetry/semantic-conventions/pull/275)) +- Updates `client.address` to allow domain names for consistency with `server.address`. + ([#302](https://github.com/open-telemetry/semantic-conventions/pull/302)) - BREAKING: Generate System metrics semconv from YAML. ([#89](https://github.com/open-telemetry/semantic-conventions/pull/89)) - Rename attributes for `system.cpu.*` metrics: diff --git a/docs/general/attributes.md b/docs/general/attributes.md index b1bc6e0ff6..f4199c7e0f 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -128,7 +128,7 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | Client address - IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| `client.address` | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | | `client.port` | int | Client port number. [2] | `65123` | Recommended | | `client.socket.address` | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | `client.socket.port` | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 2fa3121bb9..861cc74fab 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -376,7 +376,7 @@ If the route cannot be determined, the `name` attribute MUST be set as defined i | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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 | -| [`client.address`](../general/attributes.md) | string | Client address - IP address or Unix domain socket name. [2] | `83.164.160.102` | Recommended | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [2] | `83.164.160.102` | Recommended | | [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [3] | `65123` | Recommended | | [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [4] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [5] | `35555` | Recommended: If different than `client.port`. | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index e5bdaaf29d..7ef19bc619 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -161,7 +161,7 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | | [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | diff --git a/model/client.yaml b/model/client.yaml index 51fbb636f2..d1d9502183 100644 --- a/model/client.yaml +++ b/model/client.yaml @@ -12,7 +12,7 @@ groups: attributes: - id: address type: string - brief: Client address - IP address or Unix domain socket name. + brief: Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. note: > When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. From e880bddb63437119a33caddd643e069b500851a6 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Wed, 13 Sep 2023 13:11:19 +0200 Subject: [PATCH 044/482] Fix System metrics yaml warning (#322) --- model/metrics/system-metrics.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 41c508f3d2..2759d1f66f 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -452,7 +452,7 @@ groups: - ref: system.network.state - ref: network.transport - # system.processes.* metrics and attribute group + # system.processes.* metrics and attribute group - id: attributes.system.processes prefix: system.processes type: attribute_group From 875cfefe7d143aca5258c625c98d87d3c95aba46 Mon Sep 17 00:00:00 2001 From: Tyler Helmuth <12352919+TylerHelmuth@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:44:11 -0600 Subject: [PATCH 045/482] Reduce restrictions on which metrics may be named utilization (#280) --- docs/general/metrics.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 938a5e73e1..c4c6398fbf 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -166,8 +166,10 @@ over all attribute values SHOULD be equal to the **limit**. - **utilization** - an instrument that measures the *fraction* of **usage** out of its **limit** should be called `entity.utilization`. For example, -`system.memory.utilization` for the fraction of memory in use. Utilization -values are in the range `[0, 1]`. +`system.memory.utilization` for the fraction of memory in use. Utilization can +be with respect to a fixed limit or a soft limit. Utilization values are +represended as a ratio and are typically in the range `[0, 1]`, but may go above 1 +in case of exceeding a soft limit. - **time** - an instrument that measures passage of time should be called `entity.time`. For example, `system.cpu.time` with attribute `state = idle | user From a5979b01bd4549da6868bc8c97bf5a904f154be0 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 19 Sep 2023 12:37:12 +0200 Subject: [PATCH 046/482] Make messaging payload attributes consistent with other conventions (#229) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/messaging/messaging-spans.md | 44 ++++++++++++++++++------------- model/trace/messaging.yaml | 22 ++++++++++------ schema-next.yaml | 4 +++ 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96acda87f4..4d6974e789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,9 @@ release. - `state` to `system.network.state` - Rename attributes for `system.processes.*` metrics: - `status` to `system.processes.status` +- BREAKING: Rename `messaging.message.payload_size_bytes` to `messaging.message.body.size`, + remove `messaging.message.payload_compressed_size_bytes`. + ([#229](https://github.com/open-telemetry/semantic-conventions/pull/229)) ## v1.21.0 (2023-07-13) diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index c1814ad8d9..6135222dc0 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -66,7 +66,7 @@ Although messaging systems are not as standardized as, e.g., HTTP, it is assumed that the following definitions are applicable to most of them that have similar concepts at all (names borrowed mostly from JMS): -A *message* is an envelope with a potentially empty payload. +A *message* is an envelope with a potentially empty body. This envelope may offer the possibility to convey additional metadata, often in key/value form. A message is sent by a message *producer* to: @@ -225,18 +225,18 @@ The following operations related to messages are defined for these semantic conv | `messaging.destination.name` | string | The message destination name [5] | `MyQueue`; `MyTopic` | Conditionally Required: [6] | | `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [7] | `/customers/{customerId}` | Conditionally Required: [8] | | `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [9] | -| `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [10] | -| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [11] | -| `messaging.message.payload_compressed_size_bytes` | int | The compressed size of the message payload in bytes. | `2048` | Recommended: [12] | -| `messaging.message.payload_size_bytes` | int | The (uncompressed) size of the message payload in bytes. Also use this attribute if it is unknown whether the compressed or uncompressed payload size is reported. | `2738` | Recommended: [13] | +| `messaging.message.body.size` | int | The size of the message body in bytes. [10] | `1439` | Recommended: [11] | +| `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [12] | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [13] | `2738` | Recommended: [14] | +| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [15] | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [14] | `3.1.1` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [16] | `3.1.1` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [15] | `example.com` | Conditionally Required: If available. | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [16] | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [17] | `proxy.example.com` | Recommended: [18] | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [19] | `16456` | Recommended: If different than `server.port`. | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [17] | `example.com` | Conditionally Required: If available. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [18] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [19] | `proxy.example.com` | Recommended: [20] | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [21] | `16456` | Recommended: If different than `server.port`. | **[1]:** If a custom value is used, it MUST be of low cardinality. @@ -257,26 +257,32 @@ the broker does not have such notion, the destination name SHOULD uniquely ident **[9]:** If value is `true`. When missing, the value is assumed to be `false`. -**[10]:** Only if span represents operation on a single message. +**[10]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. -**[11]:** Only for spans that represent an operation on a single message. +**[11]:** Only if span represents operation on a single message. **[12]:** Only if span represents operation on a single message. -**[13]:** Only if span represents operation on a single message. +**[13]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +size should be used. -**[14]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[14]:** Only if span represents operation on a single message. -**[15]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +**[15]:** Only for spans that represent an operation on a single message. -**[16]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[16]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[17]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[18]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. -**[17]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. +**[19]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. -**[18]:** If different than `server.address` and if `server.socket.address` is set. +**[20]:** If different than `server.address` and if `server.socket.address` is set. -**[19]:** When observed from the client side, this SHOULD represent the immediate server peer port. +**[21]:** When observed from the client side, this SHOULD represent the immediate server peer port. When observed from the server side, this SHOULD represent the physical server port. `messaging.operation` 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. diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index bb7a768638..19c8f375ed 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -15,16 +15,22 @@ groups: The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". examples: 'MyConversationId' - - id: message.payload_size_bytes + - id: message.envelope.size type: int brief: > - The (uncompressed) size of the message payload in bytes. - Also use this attribute if it is unknown whether the compressed or uncompressed payload size is reported. + The size of the message body and metadata in bytes. + note: | + This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed + size should be used. examples: 2738 - - id: message.payload_compressed_size_bytes + - id: message.body.size type: int - brief: 'The compressed size of the message payload in bytes.' - examples: 2048 + brief: > + The size of the message body in bytes. + note: | + This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed + body size should be used. + examples: 1439 - id: messaging.destination prefix: messaging.destination @@ -156,10 +162,10 @@ groups: - ref: messaging.message.conversation_id requirement_level: recommended: Only if span represents operation on a single message. - - ref: messaging.message.payload_size_bytes + - ref: messaging.message.envelope.size requirement_level: recommended: Only if span represents operation on a single message. - - ref: messaging.message.payload_compressed_size_bytes + - ref: messaging.message.body.size requirement_level: recommended: Only if span represents operation on a single message. - ref: server.address diff --git a/schema-next.yaml b/schema-next.yaml index 609605b787..7e82205757 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -4,6 +4,10 @@ versions: next: metrics: changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size # https://github.com/open-telemetry/semantic-conventions/pull/224 - rename_metrics: http.client.duration: http.client.request.duration From 203691d99612452df0c951640b04521e34969628 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 20 Sep 2023 09:49:31 -0700 Subject: [PATCH 047/482] Improve `error.type` wording in HTTP semconv (#331) --- docs/http/http-metrics.md | 12 ++++++------ docs/http/http-spans.md | 2 +- model/http-common.yaml | 2 +- model/metrics/http.yaml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 07c065f2ab..c41cf7c61a 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -93,7 +93,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -263,7 +263,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -365,7 +365,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -469,7 +469,7 @@ of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -565,7 +565,7 @@ This metric is optional. `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -661,7 +661,7 @@ This metric is optional. `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 861cc74fab..914a859f0c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -134,7 +134,7 @@ sections below. `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. diff --git a/model/http-common.yaml b/model/http-common.yaml index b6643676db..7d062bd584 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -71,7 +71,7 @@ groups: `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index f6354aa7d5..c0e241b9c7 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -40,7 +40,7 @@ groups: `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -76,7 +76,7 @@ groups: `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code. + `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. From 9db3c5fdd448ad100c090191fdac0f067f9d1cf4 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 21 Sep 2023 08:41:05 -0700 Subject: [PATCH 048/482] Rename http body size metrics to match attribute names (#247) --- CHANGELOG.md | 3 +++ docs/http/http-metrics.md | 48 +++++++++++++++++++-------------------- model/metrics/http.yaml | 36 +++++++++++++++++++---------- schema-next.yaml | 4 ++++ 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d6974e789..a85b404ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,9 @@ release. - BREAKING: Rename `messaging.message.payload_size_bytes` to `messaging.message.body.size`, remove `messaging.message.payload_compressed_size_bytes`. ([#229](https://github.com/open-telemetry/semantic-conventions/pull/229)) +- BREAKING: Rename `http.server.request.size` metric to `http.server.request.body.size` + and `http.server.response.size` metric to `http.server.response.body.size` + ([#247](https://github.com/open-telemetry/semantic-conventions/pull/247)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index c41cf7c61a..8cc48b775d 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -17,12 +17,12 @@ operations. By adding HTTP attributes to metric events it allows for finely tune - [HTTP Server](#http-server) * [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) * [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) - * [Metric: `http.server.request.size`](#metric-httpserverrequestsize) - * [Metric: `http.server.response.size`](#metric-httpserverresponsesize) + * [Metric: `http.server.request.body.size`](#metric-httpserverrequestbodysize) + * [Metric: `http.server.response.body.size`](#metric-httpserverresponsebodysize) - [HTTP Client](#http-client) * [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) - * [Metric: `http.client.request.size`](#metric-httpclientrequestsize) - * [Metric: `http.client.response.size`](#metric-httpclientresponsesize) + * [Metric: `http.client.request.body.size`](#metric-httpclientrequestbodysize) + * [Metric: `http.client.response.body.size`](#metric-httpclientresponsebodysize) @@ -229,21 +229,21 @@ SHOULD NOT be set if only IP address is available and capturing name would requi | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | -### Metric: `http.server.request.size` +### Metric: `http.server.request.body.size` **Status**: [Experimental][DocumentStatus] This metric is optional. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.request.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | +| `http.server.request.body.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | -**[1]:** Size as measured over the wire (compressed size if messages are compressed). +**[1]:** 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. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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 | @@ -331,21 +331,21 @@ SHOULD NOT be set if only IP address is available and capturing name would requi | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | -### Metric: `http.server.response.size` +### Metric: `http.server.response.body.size` **Status**: [Experimental][DocumentStatus] This metric is optional. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.response.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | +| `http.server.response.body.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | -**[1]:** Size as measured over the wire (compressed size if messages are compressed). +**[1]:** 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. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `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 | @@ -535,21 +535,21 @@ When observed from the server side, this SHOULD represent the physical server ad | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | -### Metric: `http.client.request.size` +### Metric: `http.client.request.body.size` **Status**: [Experimental][DocumentStatus] This metric is optional. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.request.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | +| `http.client.request.body.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | -**[1]:** Size as measured over the wire (compressed size if messages are compressed). +**[1]:** 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. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | @@ -631,21 +631,21 @@ When observed from the server side, this SHOULD represent the physical server ad | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | -### Metric: `http.client.response.size` +### Metric: `http.client.response.body.size` **Status**: [Experimental][DocumentStatus] This metric is optional. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.response.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | +| `http.client.response.body.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | -**[1]:** Size as measured over the wire (compressed size if messages are compressed). +**[1]:** 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. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index c0e241b9c7..53ad230d28 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -134,22 +134,28 @@ groups: if it's sent in absolute-form. - Port identifier of the `Host` header - - id: metric.http.server.request.size + - id: metric.http.server.request.body.size type: metric - metric_name: http.server.request.size + metric_name: http.server.request.body.size brief: "Measures the size of HTTP request messages." instrument: histogram unit: "By" - note: Size as measured over the wire (compressed size if messages are compressed). + note: > + 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. extends: metric_attributes.http.server - - id: metric.http.server.response.size + - id: metric.http.server.response.body.size type: metric - metric_name: http.server.response.size + metric_name: http.server.response.body.size brief: "Measures the size of HTTP response messages." instrument: histogram unit: "By" - note: Size as measured over the wire (compressed size if messages are compressed). + note: > + 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. extends: metric_attributes.http.server - id: metric.http.client.request.duration @@ -160,20 +166,26 @@ groups: unit: "s" extends: metric_attributes.http.client - - id: metric.http.client.request.size + - id: metric.http.client.request.body.size type: metric - metric_name: http.client.request.size + metric_name: http.client.request.body.size brief: "Measures the size of HTTP request messages." instrument: histogram unit: "By" - note: Size as measured over the wire (compressed size if messages are compressed). + note: > + 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. extends: metric_attributes.http.client - - id: metric.http.client.response.size + - id: metric.http.client.response.body.size type: metric - metric_name: http.client.response.size + metric_name: http.client.response.body.size brief: "Measures the size of HTTP response messages." instrument: histogram unit: "By" - note: Size as measured over the wire (compressed size if messages are compressed). + note: > + 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. extends: metric_attributes.http.client diff --git a/schema-next.yaml b/schema-next.yaml index 7e82205757..4fecff3b2e 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -131,6 +131,10 @@ versions: status: system.processes.status apply_to_metrics: - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size 1.21.0: spans: changes: From 6166960d5c41e66b100bc2dca07a64fd210a407b Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Thu, 21 Sep 2023 19:22:47 +0200 Subject: [PATCH 049/482] Remove experimental Kafka metrics (#338) --- docs/messaging/kafka.md | 75 ----------------------------------------- 1 file changed, 75 deletions(-) diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 47d36bb22f..052bebacb8 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -11,10 +11,6 @@ linkTitle: Kafka - [Span attributes](#span-attributes) - [Examples](#examples) * [Apache Kafka with Quarkus or Spring Boot Example](#apache-kafka-with-quarkus-or-spring-boot-example) -- [Metrics](#metrics) - * [General Metrics](#general-metrics) - * [Producer Metrics](#producer-metrics) - * [Consumer Metrics](#consumer-metrics) @@ -88,75 +84,4 @@ Process CB: | Span Rcv2 | | `messaging.kafka.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | | `messaging.kafka.message.offset` | `"12"` | `"12"` | `"12"` | `"32"` | `"32"` | -## Metrics - -This section defines how to apply semantic conventions when collecting Kafka metrics. - -### General Metrics - -**Description:** General Kafka metrics. - -| Name | Instrument | Value type | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | Attribute Key | Attribute Values | -| ---------------------------------------------| ------------- | ---------- | ------ | -------------------------------------------- | -------------- | ------------- | ---------------- | -| messaging.kafka.messages | Counter | Int64 | messages | `{message}` | The number of messages received by the broker. | | | -| messaging.kafka.requests.failed | Counter | Int64 | requests | `{request}` | The number of requests to the broker resulting in a failure. | `type` | `produce`, `fetch` | -| messaging.kafka.requests.queue | UpDownCounter | Int64 | requests | `{request}` | The number of requests in the request queue. | | | -| messaging.kafka.network.io | Counter | Int64 | bytes | `By` | The bytes received or sent by the broker. | `state` | `in`, `out` | -| messaging.kafka.purgatory.size | UpDownCounter | Int64 | requests | `{request}` | The number of requests waiting in the purgatory. | `type` | `produce`, `fetch` | -| messaging.kafka.partitions.all | UpDownCounter | Int64 | partitions | `{partition}` | The number of partitions in the broker. | | | -| messaging.kafka.partitions.offline | UpDownCounter | Int64 | partitions | `{partition}` | The number of offline partitions. | | | -| messaging.kafka.partitions.under-replicated | UpDownCounter | Int64 | partition | `{partition}` | The number of under replicated partitions. | | | -| messaging.kafka.isr.operations | Counter | Int64 | operations | `{operation}` | The number of in-sync replica shrink and expand operations. | `operation` | `shrink`, `expand` | -| messaging.kafka.lag_max | Gauge | Int64 | lag max | `{message}` | Max lag in messages between follower and leader replicas. | | | -| messaging.kafka.controllers.active | UpDownCounter | Int64 | controllers | `{controller}` | The number of active controllers in the broker. | | | -| messaging.kafka.leader.elections | Counter | Int64 | elections | `{election}` | Leader election rate (increasing values indicates broker failures). | | | -| messaging.kafka.leader.unclean-elections | Counter | Int64 | elections | `{election}` | Unclean leader election rate (increasing values indicates broker failures). | | | -| messaging.kafka.brokers | UpDownCounter | Int64 | brokers | `{broker}` | Number of brokers in the cluster. | | | -| messaging.kafka.topic.partitions | UpDownCounter | Int64 | partitions | `{partition}` | Number of partitions in topic. | `topic` | The ID (integer) of a topic | -| messaging.kafka.partition.current_offset | Gauge | Int64 | partition offset | `{partition offset}` | Current offset of partition of topic. | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition | -| messaging.kafka.partition.oldest_offset | Gauge | Int64 | partition offset | `{partition offset}` | Oldest offset of partition of topic | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition | -| messaging.kafka.partition.replicas.all | UpDownCounter | Int64 | replicas | `{replica}` | Number of replicas for partition of topic | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition | -| messaging.kafka.partition.replicas.in_sync | UpDownCounter | Int64 | replicas | `{replica}` | Number of synchronized replicas of partition | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition| - -### Producer Metrics - -**Description:** Kafka Producer level metrics. - -| Name | Instrument | Value type | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | Attribute Key | Attribute Values | -| --------------------------------------------- | ------------- | ---------- | ------ | -------------------------------------------- | -------------- | ------------- | ---------------- | -| messaging.kafka.producer.outgoing-bytes.rate | Gauge | Double | bytes per second | `By/s` | The average number of outgoing bytes sent per second to all servers. | `client-id` | `client-id` value | -| messaging.kafka.producer.responses.rate | Gauge | Double | responses per second | `{response}/s` | The average number of responses received per second. | `client-id` | `client-id` value | -| messaging.kafka.producer.bytes.rate | Gauge | Double | bytes per second | `By/s` | The average number of bytes sent per second for a specific topic. | `client-id` | `client-id` value | -| | | | | | | `topic` | topic name | -| messaging.kafka.producer.compression-ratio | Gauge | Double | compression ratio | `{compression}` | The average compression ratio of record batches for a specific topic. | `client-id` | `client-id` value | -| | | | | | | `topic` | topic name | -| messaging.kafka.producer.record-error.rate | Gauge | Double | error rate | `{error}/s` | The average per-second number of record sends that resulted in errors for a specific topic. | `client-id` | `client-id` value | -| | | | | | | `topic` | topic name | -| messaging.kafka.producer.record-retry.rate | Gauge | Double | retry rate | `{retry}/s` | The average per-second number of retried record sends for a specific topic. | `client-id` | `client-id` value | -| | | | | | | `topic` | topic name | -| messaging.kafka.producer.record-sent.rate | Gauge | Double | records sent rate | `{record_sent}/s` | The average number of records sent per second for a specific topic. | `client-id` | `client-id` value | -| | | | | | | `topic` | topic name | - -### Consumer Metrics - -**Description:** Kafka Consumer level metrics. - -| Name | Instrument | Value type | Unit | Unit ([UCUM](/docs/general/metrics.md#instrument-units)) | Description | Attribute Key | Attribute Values | -| --------------------------------------------- | ------------- | ---------- | ------ | -------------------------------------------- | -------------- | ------------- | ---------------- | -| messaging.kafka.consumer.members | UpDownCounter | Int64 | members | `{member}` | Count of members in the consumer group | `group` | The ID (string) of a consumer group | -| messaging.kafka.consumer.offset | Gauge | Int64 | offset | `{offset}` | Current offset of the consumer group at partition of topic | `group` | The ID (string) of a consumer group | -| | | | | | | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition | -| messaging.kafka.consumer.offset_sum | Gauge | Int64 | offset sum | `{offset sum}` | Sum of consumer group offset across partitions of topic | `group` | The ID (string) of a consumer group | -| | | | | | | `topic` | The ID (integer) of a topic | -| messaging.kafka.consumer.lag | Gauge | Int64 | lag | `{lag}` | Current approximate lag of consumer group at partition of topic | `group` | The ID (string) of a consumer group | -| | | | | | | `topic` | The ID (integer) of a topic | -| | | | | | | `partition` | The number (integer) of the partition | -| messaging.kafka.consumer.lag_sum | Gauge | Int64 | lag sum | `{lag sum}` | Current approximate sum of consumer group lag across all partitions of topic | `group` | The ID (string) of a consumer group | -| | | | | | | `topic` | The ID (integer) of a topic | - [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md From a89f57357e45619e65f52e86994763c96932fb66 Mon Sep 17 00:00:00 2001 From: Bryce Buchanan <75274611+bryce-b@users.noreply.github.com> Date: Fri, 22 Sep 2023 00:04:05 -0700 Subject: [PATCH 050/482] Session.id semantic convention (#215) Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> Co-authored-by: Chengzhong Wu Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/general/session.md | 22 ++++++++++++++++++++++ model/session.yaml | 17 +++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 docs/general/session.md create mode 100644 model/session.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index a85b404ca1..39fcf53427 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ release. ## Unreleased +- Adds `session.id` and session.md to general docs and model +([#215](https://github.com/open-telemetry/semantic-conventions/pull/215)) - Add `cluster.name` and `node.name` attributes to Elasticsearch semantic conventions. ([#285](https://github.com/open-telemetry/semantic-conventions/pull/285)) - Fix the unit of metric.process.runtime.jvm.system.cpu.load_1m to be {run_queue_item} diff --git a/docs/general/session.md b/docs/general/session.md new file mode 100644 index 0000000000..2a3f533107 --- /dev/null +++ b/docs/general/session.md @@ -0,0 +1,22 @@ +# Semantic conventions for session + +**Status**: [Experimental][DocumentStatus] + +This document defines semantic conventions to apply to client-side applications when tracking sessions. + +Session is defined as the period of time encompassing all activities performed by the application and the actions +executed by the end user. + +Consequently, a Session is represented as a collection of Logs, Events, and Spans emitted by the Client Application +throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in +the Logs, Events, and Spans generated during the Session's lifecycle. + +## Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/session.yaml b/model/session.yaml new file mode 100644 index 0000000000..eacda8416d --- /dev/null +++ b/model/session.yaml @@ -0,0 +1,17 @@ +groups: + - id: session-id + prefix: session + type: attribute_group + brief: > + Session is defined as the period of time encompassing all activities performed by the application and the actions + executed by the end user. + + Consequently, a Session is represented as a collection of Logs, Events, and Spans emitted by the Client Application + throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in + the Logs, Events, and Spans generated during the Session's lifecycle. + attributes: + - id: id + type: string + brief: "A unique id to identify a session." + examples: "00112233-4455-6677-8899-aabbccddeeff" + requirement_level: opt_in From 650be8f5239bb257d51402c14e51f891f27f375e Mon Sep 17 00:00:00 2001 From: Mike Koltsov <6823298+ItsLastDay@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:48:36 +0200 Subject: [PATCH 051/482] Add system.linux.memory.available metric (#323) --- CHANGELOG.md | 2 ++ CONTRIBUTING.md | 8 ++++---- docs/system/system-metrics.md | 15 +++++++++++++++ model/metrics/system-metrics.yaml | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39fcf53427..ac4db6bbb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,8 @@ release. - BREAKING: Rename `messaging.message.payload_size_bytes` to `messaging.message.body.size`, remove `messaging.message.payload_compressed_size_bytes`. ([#229](https://github.com/open-telemetry/semantic-conventions/pull/229)) +- Add `system.linux.memory.available` metric. + ([#323](https://github.com/open-telemetry/semantic-conventions/pull/323)) - BREAKING: Rename `http.server.request.size` metric to `http.server.request.body.size` and `http.server.response.size` metric to `http.server.response.body.size` ([#247](https://github.com/open-telemetry/semantic-conventions/pull/247)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5721670ffa..3bfe45c930 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,18 +21,18 @@ key, but non-obvious, aspects: - All descriptions, normative language are defined in the `docs/` directory. - We provide tooling to generate Markdown documentation from the formal - YAML definitons. See [Yaml to Markdown](#yaml-to-markdown). + YAML definitons. See [Yaml to Markdown](#yaml-to-markdown). - We use Hugo to render [semantic conventions on our website](https://opentelemetry.io/docs/specs/semconv/). You will see ` @@ -739,3 +740,17 @@ an `{os}` prefix to split this metric across OSes. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/document-status.md [MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/metrics/metric-requirement-level.md#recommended + +### Metric: `system.linux.memory.available` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.linux.memory.available` | UpDownCounter | `By` | An estimate of how much memory is available for starting new applications, without causing swapping [1] | + +**[1]:** This is an alternative to `system.memory.usage` metric with `state=free`. +Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values. +This is supposed to be more accurate than just "free" memory. +For reference, see the calculations [here](https://superuser.com/a/980821). +See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). + diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 2759d1f66f..cfd20979f2 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -490,3 +490,17 @@ groups: brief: "Total number of processes created over uptime of the host" instrument: counter unit: "{process}" + + # system.linux.* metrics + - id: metric.system.linux.memory.available + type: metric + metric_name: system.linux.memory.available + brief: "An estimate of how much memory is available for starting new applications, without causing swapping" + note: | + This is an alternative to `system.memory.usage` metric with `state=free`. + Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values. + This is supposed to be more accurate than just "free" memory. + For reference, see the calculations [here](https://superuser.com/a/980821). + See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). + instrument: updowncounter + unit: "By" From e4b67282cc60084656296115b9025d794293e2d6 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 22 Sep 2023 09:55:56 -0700 Subject: [PATCH 052/482] Move non-`network.*` attributes out of network.yaml (#296) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ model/general.yaml | 89 ++++++++++++++++++++++++++++++++++++++++++++++ model/network.yaml | 88 --------------------------------------------- 3 files changed, 91 insertions(+), 88 deletions(-) create mode 100644 model/general.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index ac4db6bbb1..331790d89d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,6 +110,8 @@ release. - BREAKING: Rename `http.server.request.size` metric to `http.server.request.body.size` and `http.server.response.size` metric to `http.server.response.body.size` ([#247](https://github.com/open-telemetry/semantic-conventions/pull/247)) +- Move non-`network.*` attributes out of network.yaml. + ([#296](https://github.com/open-telemetry/semantic-conventions/pull/296)) ## v1.21.0 (2023-07-13) diff --git a/model/general.yaml b/model/general.yaml new file mode 100644 index 0000000000..4f387bac6f --- /dev/null +++ b/model/general.yaml @@ -0,0 +1,89 @@ +groups: + - id: peer + prefix: peer + type: span + brief: "Operations that access some remote service." + attributes: + - id: service + type: string + brief: > + The [`service.name`](/docs/resource/README.md#service) + of the remote service. SHOULD be equal to the actual `service.name` + resource attribute of the remote service if any. + examples: "AuthTokenCache" + - id: identity + prefix: enduser + type: span + brief: > + These attributes may be used for any operation with an authenticated and/or authorized enduser. + attributes: + - id: id + type: string + brief: > + Username or client_id extracted from the access token or + [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) + header in the inbound request from outside the system. + examples: 'username' + - id: role + type: string + brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' + examples: 'admin' + - id: scope + type: string + brief: > + Scopes or granted authorities the client currently possesses extracted from token + or application security context. The value would come from the scope associated + with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) + or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + examples: 'read:message, write:files' + - id: thread + prefix: thread + type: span + brief: > + These attributes may be used for any operation to store information about a thread that started a span. + attributes: + - id: id + type: int + brief: > + Current "managed" thread ID (as opposed to OS thread ID). + examples: 42 + - id: name + type: string + brief: > + Current thread name. + examples: main + - id: daemon + brief: "Whether the thread is daemon or not." + type: boolean + - id: code + prefix: code + type: span + brief: > + These attributes allow to report this unit of code and therefore to provide more context about the span. + attributes: + - id: function + type: string + brief: > + The method or function name, or equivalent (usually rightmost part of the code unit's name). + examples: serveRequest + - id: namespace + type: string + brief: > + The "namespace" within which `code.function` is defined. Usually the qualified class or module name, + such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. + examples: com.example.MyHttpService + - id: filepath + type: string + brief: > + The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). + examples: /usr/local/MyApplication/content_root/app/index.php + - id: lineno + type: int + brief: > + The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + examples: 42 + - id: column + type: int + brief: > + The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + examples: 16 diff --git a/model/network.yaml b/model/network.yaml index 478937c110..fa83e62099 100644 --- a/model/network.yaml +++ b/model/network.yaml @@ -162,91 +162,3 @@ groups: type: string brief: "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network." examples: "DE" - - id: peer - prefix: peer - type: span - brief: "Operations that access some remote service." - attributes: - - id: service - type: string - brief: > - The [`service.name`](/docs/resource/README.md#service) - of the remote service. SHOULD be equal to the actual `service.name` - resource attribute of the remote service if any. - examples: "AuthTokenCache" - - id: identity - prefix: enduser - type: span - brief: > - These attributes may be used for any operation with an authenticated and/or authorized enduser. - attributes: - - id: id - type: string - brief: > - Username or client_id extracted from the access token or - [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) - header in the inbound request from outside the system. - examples: 'username' - - id: role - type: string - brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' - examples: 'admin' - - id: scope - type: string - brief: > - Scopes or granted authorities the client currently possesses extracted from token - or application security context. The value would come from the scope associated - with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) - or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). - examples: 'read:message, write:files' - - id: thread - prefix: thread - type: span - brief: > - These attributes may be used for any operation to store information about a thread that started a span. - attributes: - - id: id - type: int - brief: > - Current "managed" thread ID (as opposed to OS thread ID). - examples: 42 - - id: name - type: string - brief: > - Current thread name. - examples: main - - id: daemon - brief: "Whether the thread is daemon or not." - type: boolean - - id: code - prefix: code - type: span - brief: > - These attributes allow to report this unit of code and therefore to provide more context about the span. - attributes: - - id: function - type: string - brief: > - The method or function name, or equivalent (usually rightmost part of the code unit's name). - examples: serveRequest - - id: namespace - type: string - brief: > - The "namespace" within which `code.function` is defined. Usually the qualified class or module name, - such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. - examples: com.example.MyHttpService - - id: filepath - type: string - brief: > - The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). - examples: /usr/local/MyApplication/content_root/app/index.php - - id: lineno - type: int - brief: > - The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - examples: 42 - - id: column - type: int - brief: > - The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - examples: 16 From 65eed24c6c03058c090f1106ff62909aa999e2dd Mon Sep 17 00:00:00 2001 From: Surbhi A <138259843+surbhiia@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:02:30 -0700 Subject: [PATCH 053/482] Add android.yaml and android.os.api.level resource attribute (#328) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/android.md | 15 +++++++++++++++ model/resource/android.yaml | 14 ++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 docs/resource/android.md create mode 100644 model/resource/android.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 331790d89d..5dd4e7098a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,6 +112,8 @@ release. ([#247](https://github.com/open-telemetry/semantic-conventions/pull/247)) - Move non-`network.*` attributes out of network.yaml. ([#296](https://github.com/open-telemetry/semantic-conventions/pull/296)) +- Introducing Android `android.os.api_level` resource attribute. + ([#328](https://github.com/open-telemetry/semantic-conventions/pull/328)) ## v1.21.0 (2023-07-13) diff --git a/docs/resource/android.md b/docs/resource/android.md new file mode 100644 index 0000000000..bbef3af2d0 --- /dev/null +++ b/docs/resource/android.md @@ -0,0 +1,15 @@ +# Android + +**Status**: [Experimental][DocumentStatus] + +**type:** `android` + +**Description**: The Android platform on which the Android application is running. + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | Recommended | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/resource/android.yaml b/model/resource/android.yaml new file mode 100644 index 0000000000..dcc236d846 --- /dev/null +++ b/model/resource/android.yaml @@ -0,0 +1,14 @@ +groups: + - id: android + prefix: android + type: resource + brief: > + The Android platform on which the Android application is running. + attributes: + - id: os.api_level + type: string + brief: > + Uniquely identifies the framework API revision offered by a version + (`os.version`) of the android operating system. More information can be found + [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). + examples: ['33', '32'] From c7b094d36428ea7c7628533bfa4ab79fa153aa37 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Mon, 25 Sep 2023 23:44:03 +0900 Subject: [PATCH 054/482] Remove service.version from list of attributes with dedicated env var (#261) Co-authored-by: Josh Suereth Co-authored-by: Joao Grassi --- docs/resource/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/resource/README.md b/docs/resource/README.md index 0426bd6249..c7637f565f 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -62,7 +62,6 @@ These are the attributes which MAY be configurable via a dedicated environment v as specified in [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/configuration/sdk-environment-variables.md): - [`service.name`](#service) -- [`service.version`](#service) ## Semantic Attributes with SDK-provided Default Value From 1d3d63b3d6ef85d658c96f463d44f33029de9cc7 Mon Sep 17 00:00:00 2001 From: Goutham Veeramachaneni Date: Mon, 25 Sep 2023 16:49:20 +0200 Subject: [PATCH 055/482] Update span name recommendation for HTTP Server (#287) Signed-off-by: Goutham Co-authored-by: Trask Stalnaker Co-authored-by: Johannes Tax Co-authored-by: Josh Suereth --- docs/http/http-spans.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 914a859f0c..0449089215 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -368,10 +368,6 @@ 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 cannot be determined, the `name` attribute MUST be set as defined in the general semantic conventions for HTTP. - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| From 984079ee2b98a5700b139989db9737b044ab40e6 Mon Sep 17 00:00:00 2001 From: Surbhi A <138259843+surbhiia@users.noreply.github.com> Date: Mon, 25 Sep 2023 07:56:22 -0700 Subject: [PATCH 056/482] Adding os.build_id resource attribute and discussion why os.sdk.version isn't required (#293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joao Grassi Co-authored-by: Christian Neumüller Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- CHANGELOG.md | 2 ++ docs/resource/os.md | 1 + model/resource/os.yaml | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd4e7098a..613d3c8278 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,6 +114,8 @@ release. ([#296](https://github.com/open-telemetry/semantic-conventions/pull/296)) - Introducing Android `android.os.api_level` resource attribute. ([#328](https://github.com/open-telemetry/semantic-conventions/pull/328)) +- Added `os.build_id` resource attribute. + ([#293](https://github.com/open-telemetry/semantic-conventions/pull/293)) ## v1.21.0 (2023-07-13) diff --git a/docs/resource/os.md b/docs/resource/os.md index 2b73acea08..585c29d10c 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -15,6 +15,7 @@ In case of virtualized environments, this is the operating system as it is obser | `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | Recommended | | `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | Recommended | | `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | Recommended | +| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | `os.type` 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. diff --git a/model/resource/os.yaml b/model/resource/os.yaml index 083b88495e..78636f8461 100644 --- a/model/resource/os.yaml +++ b/model/resource/os.yaml @@ -63,3 +63,7 @@ groups: The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). examples: ['14.2.1', '18.04.1'] + - id: build_id + type: string + brief: 'Unique identifier for a particular build or compilation of the operating system.' + examples: ['TQ3C.230805.001.B2', '20E247', '22621'] From 2ef85e6e84de3b173dd374eff66d7bbf414cefd7 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Tue, 26 Sep 2023 09:55:47 +0200 Subject: [PATCH 057/482] Moved template attributes to yaml model files (#315) Co-authored-by: Trask Stalnaker Co-authored-by: Joao Grassi --- docs/database/elasticsearch.md | 40 ++++++++++++-------------------- docs/http/http-spans.md | 42 +++++++++++++++------------------- docs/rpc/connect-rpc.md | 16 +++++-------- docs/rpc/grpc.md | 16 +++++-------- model/trace/database.yaml | 13 +++++++++++ model/trace/http.yaml | 31 +++++++++++++++++++++++++ model/trace/rpc.yaml | 36 +++++++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 69 deletions(-) diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 43003ddc8b..8dd4a5fc4d 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -21,19 +21,6 @@ name, as the path could contain dynamic values. The endpoint id is the `name` fi [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json). If the endpoint id is not available, the span name SHOULD be the `http.request.method`. -## URL path parts - -Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format -`db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD -reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) -in order to map the path part values to their names. - -| Attribute | Type | Description | Examples | Requirement Level | -|-------------------------------------|---|---------------------------------------|------------------------------------------------------------------------------------------|---| -| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: [1] | - -**[1]:** when the url has dynamic values - ## Call-level attributes @@ -41,22 +28,25 @@ in order to map the path part values to their names. |---|---|---|---|---| | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | | `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | Recommended: [2] | -| [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [3] | `search`; `ml.close_job`; `cat.aliases` | Required | -| [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [4] | -| `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [6] | `example.com` | See below | -| [`server.port`](../general/attributes.md) | int | Server port number [7] | `80`; `8080`; `443` | Recommended | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [8] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [3] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | +| [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | +| [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | +| `http.request.method` | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [7] | `example.com` | See below | +| [`server.port`](../general/attributes.md) | int | Server port number [8] | `80`; `8080`; `443` | Recommended | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [9] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. **[2]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. -**[3]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +**[3]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. + +**[4]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. -**[4]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. +**[5]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. -**[5]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[6]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -71,12 +61,12 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[8]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[8]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[9]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 0449089215..ee2128f460 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -17,7 +17,6 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Name](#name) - [Status](#status) - [Common Attributes](#common-attributes) - * [HTTP request and response headers](#http-request-and-response-headers) - [HTTP client](#http-client) * [HTTP client span duration](#http-client-span-duration) * [HTTP request retries and redirects](#http-request-retries-and-redirects) @@ -120,17 +119,27 @@ sections below. | `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [1] | | `http.request.body.size` | 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.body.size` | 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 | -| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [3] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | +| `error.type` | string | Describes a class of error the operation ended with. [4] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [5] | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [7] | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | **[1]:** If and only if it's different than `http.request.method`. -**[2]:** If the request fails with an error before response status code was sent or received, +**[2]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[3]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[4]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), @@ -146,7 +155,7 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[5]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -161,9 +170,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). +**[7]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: @@ -207,21 +216,6 @@ Following attributes MUST be provided **at span creation time** (when provided a | `ipv6` | IPv6 | -### HTTP request and response headers - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|-------------------| -| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [1] [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [1] [2] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | - -**[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. -Including all request/response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - -The `User-Agent` header is already captured in the `user_agent.original` attribute. -Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - -**[2]:** The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - ## HTTP client This span type represents an outbound HTTP request. There are two ways this can be achieved in an instrumentation: diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index f383bf7703..55ec272b40 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -20,9 +20,15 @@ Below is a table of attributes that SHOULD be included on client and server Conn | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | Conditionally Required: [1] | +| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [2] | `rpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [3] | `rpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | **[1]:** If response is not successful and if error code available. +**[2]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[3]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + `rpc.connect_rpc.error_code` MUST be one of the following: | Value | Description | @@ -49,14 +55,4 @@ Below is a table of attributes that SHOULD be included on client and server Conn If `rpc.connect_rpc.error_code` is set, [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#set-status) MUST be set to `Error` and left unset in all other cases. -## Connect RPC Request and Response Metadata - -| Attribute | Type | Description | Examples | Requirement Level | -|-------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------|-------------------| -| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Optional | -| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Optional | - -**[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. -Including all request/response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index c5f140bf6f..dd24a1ffa6 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -20,6 +20,12 @@ Below is a table of attributes that SHOULD be included on client and server gRPC | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | +| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | + +**[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[2]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. `rpc.grpc.status_code` MUST be one of the following: @@ -72,14 +78,4 @@ and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tr | DATA_LOSS | `Error` | `Error` | | UNAUTHENTICATED | unset | `Error` | -## gRPC Request and Response Metadata - -| Attribute | Type | Description | Examples | Requirement Level | -|-------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------|-------------------| -| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | - -**[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. -Including all request/response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 2348a2a0f0..aeb68fc6af 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -472,6 +472,19 @@ groups: brief: > Represents the human-readable identifier of the node/instance to which a request was routed. examples: ["instance-0000000001"] + - id: path_parts + type: template[string] + requirement_level: + conditionally_required: when the url has dynamic values + tag: call-level-tech-specific + brief: > + A dynamic value in the url path. + note: > + Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format + `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD + reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) + in order to map the path part values to their names. + examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - id: db.sql prefix: 'db.sql' diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 53898fb483..ae362604ca 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -28,6 +28,37 @@ 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 + - id: request.header + type: template[string[]] + requirement_level: opt_in + brief: > + HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + note: > + Instrumentations SHOULD require an explicit configuration of which headers are to be captured. + Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + + The `User-Agent` header is already captured in the `user_agent.original` attribute. + Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + + The attribute value MUST consist of either multiple header values as an array of strings + or a single-item array containing a possibly comma-concatenated string, depending on the way + the HTTP library provides access to headers. + examples: ['http.request.header.content_type=["application/json"]', 'http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]'] + - id: response.header + type: template[string[]] + requirement_level: opt_in + brief: > + HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + note: > + Instrumentations SHOULD require an explicit configuration of which headers are to be captured. + Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + + Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + + The attribute value MUST consist of either multiple header values as an array of strings + or a single-item array containing a possibly comma-concatenated string, depending on the way + the HTTP library provides access to headers. + examples: ['http.response.header.content_type=["application/json"]', 'http.response.header.my_custom_header=["abc", "def"]'] - ref: http.request.method sampling_relevant: true - ref: network.transport diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index d2aab9a5ed..38a25016e0 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -156,6 +156,24 @@ groups: value: 16 requirement_level: required brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." + - id: request.metadata + type: template[string[]] + requirement_level: opt_in + brief: > + gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]'] + - id: response.metadata + type: template[string[]] + requirement_level: opt_in + brief: > + gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]'] - id: rpc.jsonrpc prefix: rpc.jsonrpc @@ -261,3 +279,21 @@ groups: requirement_level: conditionally_required: If response is not successful and if error code available. brief: "The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values." + - id: request.metadata + type: template[string[]] + requirement_level: opt_in + brief: > + Connect request metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]'] + - id: response.metadata + type: template[string[]] + requirement_level: opt_in + brief: > + Connect response metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]'] From 2bcee3ca7904e66472bf9c91ebfa342d837759aa Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 26 Sep 2023 15:51:03 +0100 Subject: [PATCH 058/482] Add container labels field from ECS (#125) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/container.md | 1 + model/resource/container.yaml | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 613d3c8278..bb6b78343a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ release. - Adds `session.id` and session.md to general docs and model ([#215](https://github.com/open-telemetry/semantic-conventions/pull/215)) +- Add `container.labels.` attributes. + ([#125](https://github.com/open-telemetry/semantic-conventions/pull/125)) - Add `cluster.name` and `node.name` attributes to Elasticsearch semantic conventions. ([#285](https://github.com/open-telemetry/semantic-conventions/pull/285)) - Fix the unit of metric.process.runtime.jvm.system.cpu.load_1m to be {run_queue_item} diff --git a/docs/resource/container.md b/docs/resource/container.md index b0017c4b36..cc9ff9fd34 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -19,6 +19,7 @@ | `container.command` | string | The command used to run the container (i.e. the command name). [3] | `otelcontribcol` | Opt-In | | `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | | `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | +| `container.labels.` | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | Recommended | **[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. diff --git a/model/resource/container.yaml b/model/resource/container.yaml index 3dbac9641b..2080b7b9c6 100644 --- a/model/resource/container.yaml +++ b/model/resource/container.yaml @@ -82,3 +82,8 @@ groups: brief: > All the command arguments (including the command/executable itself) run by the container. [2] examples: [ 'otelcontribcol, --config, config.yaml' ] + - id: labels + type: template[string] + brief: > + Container labels, `` being the label name, the value being the label value. + examples: [ 'container.labels.app=nginx' ] From 9790d8f54533840dd187d3ffa5c2546d9420d357 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 26 Sep 2023 09:37:58 -0700 Subject: [PATCH 059/482] Remove the zero bucket boundary from `http.server.request.duration` and `http.client.request.duration` (#318) --- CHANGELOG.md | 3 +++ docs/http/http-metrics.md | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb6b78343a..4290e2c183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,6 +118,9 @@ release. ([#328](https://github.com/open-telemetry/semantic-conventions/pull/328)) - Added `os.build_id` resource attribute. ([#293](https://github.com/open-telemetry/semantic-conventions/pull/293)) +- BREAKING: Remove the zero bucket boundary from `http.server.request.duration` + and `http.client.request.duration`. + ([#318](https://github.com/open-telemetry/semantic-conventions/pull/318)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 8cc48b775d..6b10380650 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -65,7 +65,7 @@ When this metric is reported alongside an HTTP server span, the metric value SHO This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) -of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. | Name | Instrument Type | Unit (UCUM) | Description | @@ -445,7 +445,7 @@ When this metric is reported alongside an HTTP client span, the metric value SHO This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) -of `[ 0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. | Name | Instrument Type | Unit (UCUM) | Description | From 50c5424549a719411ae1483cccae812e77d47708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 29 Sep 2023 20:57:22 +0200 Subject: [PATCH 060/482] Port, address clarifications (#289) --- CHANGELOG.md | 2 + docs/database/database-spans.md | 2 +- docs/general/attributes.md | 91 ++++++++++++++++++------------- docs/http/http-spans.md | 2 +- docs/messaging/messaging-spans.md | 2 +- docs/rpc/rpc-metrics.md | 2 +- docs/rpc/rpc-spans.md | 4 +- docs/system/system-metrics.md | 2 +- model/network.yaml | 3 + 9 files changed, 64 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4290e2c183..51b38e35db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,8 @@ release. - BREAKING: Remove the zero bucket boundary from `http.server.request.duration` and `http.client.request.duration`. ([#318](https://github.com/open-telemetry/semantic-conventions/pull/318)) +- Encourage setting `network.transport` when reporting port numbers + ([#289](https://github.com/open-telemetry/semantic-conventions/pull/289)) ## v1.21.0 (2023-07-13) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index d208eebd7a..d942b29f16 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,7 +67,7 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the database host. [1] | `example.com` | Conditionally Required: See alternative attributes below. | | [`server.port`](../general/attributes.md) | int | Server port number [2] | `80`; `8080`; `443` | Conditionally Required: [3] | diff --git a/docs/general/attributes.md b/docs/general/attributes.md index f4199c7e0f..99fe0da717 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -15,17 +15,18 @@ Particular operations may refer to or require some of these attributes. -- [Server and client attributes](#server-and-client-attributes) +- [Server, client and shared network attributes](#server-client-and-shared-network-attributes) + * [Address and port attributes](#address-and-port-attributes) * [Server attributes](#server-attributes) + [`server.address`](#serveraddress) + [`server.socket.*` attributes](#serversocket-attributes) * [Client attributes](#client-attributes) + [Connecting through intermediary](#connecting-through-intermediary) -- [Network attributes](#network-attributes) * [Source and destination attributes](#source-and-destination-attributes) + [Source](#source) + [Destination](#destination) - * [Network connection and carrier attributes](#network-connection-and-carrier-attributes) + * [Other network attributes](#other-network-attributes) + + [Network connection and carrier attributes](#network-connection-and-carrier-attributes) - [General remote service attributes](#general-remote-service-attributes) - [General identity attributes](#general-identity-attributes) - [General thread attributes](#general-thread-attributes) @@ -33,7 +34,10 @@ Particular operations may refer to or require some of these attributes. -## Server and client attributes + + + +## Server, client and shared network attributes These attributes may be used to describe the client and server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). @@ -45,6 +49,13 @@ This also covers UDP network interactions where one side initiates the interacti In an ideal situation, not accounting for proxies, multiple IP addresses or host names, the `server.*` attributes are the same on the client and server. +### Address and port attributes + +For all IP-based protocols, the "address" should be just the IP-level address. +Protocol-specific parts of an address are split into other attributes (when applicable) such as "port" attributes for +TCP and UDP. If such transport-specific information is collected and the attribute name does not already uniquely +identify the transport, then setting [`network.transport`](#other-network-attributes) is especially encouraged. + ### Server attributes > **Warning** @@ -175,40 +186,6 @@ The `client.socket.address` and `client.socket.port` attributes then SHOULD cont If only immediate peer information is available, it should be set on `client.address` and `client.port` and `client.socket.*` attributes SHOULD NOT be set. -## Network attributes - -> **Warning** -> Attributes in this section are in use by the HTTP semantic conventions. -Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed -if they do not cause breaking changes to HTTP semantic conventions. - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `network.transport` | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | -| `network.type` | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| `network.protocol.name` | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| `network.protocol.version` | string | Version of the application layer protocol used. See note below. [1] | `3.1.1` | Recommended | - -**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - -`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | -| `unix` | Unix domain socket | - -`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | - - ### Source and destination attributes These attributes may be used to describe the sender and receiver of a network exchange/packet. These should be used @@ -244,7 +221,43 @@ Destination fields capture details about the receiver of a network exchange/pack **[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. -### Network connection and carrier attributes + + +### Other network attributes + +> **Warning** +> Attributes in this section are in use by the HTTP semantic conventions. +Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed +if they do not cause breaking changes to HTTP semantic conventions. + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `network.transport` | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | +| `network.type` | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | +| `network.protocol.name` | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | +| `network.protocol.version` | string | Version of the application layer protocol used. See note below. [1] | `3.1.1` | Recommended | + +**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. See note below. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +#### Network connection and carrier attributes | Attribute | Type | Description | Examples | Requirement Level | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index ee2128f460..68a8a0cd50 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -125,7 +125,7 @@ sections below. | `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). | | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [7] | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Conditionally Required: [7] | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 6135222dc0..90f58da2fb 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -231,7 +231,7 @@ The following operations related to messages are defined for these semantic conv | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [15] | | [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [16] | `3.1.1` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [17] | `example.com` | Conditionally Required: If available. | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [18] | `10.5.3.2` | Recommended: If different than `server.address`. | diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index d51e609be6..8ff24ac2b8 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -223,7 +223,7 @@ measurements. | [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [1] | `myservice.EchoService` | Recommended | | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [2] | `exampleMethod` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 7ef19bc619..9a9ae62cc7 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -88,7 +88,7 @@ Examples of span names: | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [1] | `myservice.EchoService` | Recommended | | `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [2] | `exampleMethod` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | @@ -165,7 +165,7 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | | [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 37b14608a1..8fa2bfa16f 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -637,7 +637,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | | `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | diff --git a/model/network.yaml b/model/network.yaml index fa83e62099..28074ba84d 100644 --- a/model/network.yaml +++ b/model/network.yaml @@ -25,6 +25,9 @@ groups: [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. + Consider always setting the transport when setting a port number, since + a port number is ambiguous without knowing the transport, for example + different processes could be listening on TCP port 12345 and UDP port 12345. examples: ['tcp', 'udp'] - id: type type: From fe1797ef860049d40a50d56ea05f8fbe59f4ee95 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 2 Oct 2023 01:18:40 -0700 Subject: [PATCH 061/482] Add url.scheme to http client metrics (#357) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 3 +++ model/metrics/http.yaml | 2 ++ 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51b38e35db..ce87eb3c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -123,6 +123,8 @@ release. ([#318](https://github.com/open-telemetry/semantic-conventions/pull/318)) - Encourage setting `network.transport` when reporting port numbers ([#289](https://github.com/open-telemetry/semantic-conventions/pull/289)) +- BREAKING: Add `url.scheme` to `http.client.*` metrics + ([#357](https://github.com/open-telemetry/semantic-conventions/pull/357)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 6b10380650..101ce3c5c0 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -464,6 +464,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. @@ -560,6 +561,7 @@ This metric is optional. | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. @@ -656,6 +658,7 @@ This metric is optional. | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 53ad230d28..a5ceceb288 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -87,6 +87,8 @@ groups: additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + - ref: url.scheme + requirement_level: required - id: metric.http.server.request.duration type: metric From 56286849c94324fbe87adc69fba92ea4245d1e3d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 2 Oct 2023 08:45:46 -0700 Subject: [PATCH 062/482] BREAKING: Remove `server.socket.address` attribute from http and rpc metrics (#350) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 12 ---------- docs/rpc/rpc-metrics.md | 42 ++++++++++++++++++---------------- model/metrics/http.yaml | 1 - model/metrics/rpc-metrics.yaml | 2 -- 5 files changed, 24 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce87eb3c0c..18b2cb8f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,8 @@ release. ([#289](https://github.com/open-telemetry/semantic-conventions/pull/289)) - BREAKING: Add `url.scheme` to `http.client.*` metrics ([#357](https://github.com/open-telemetry/semantic-conventions/pull/357)) +- BREAKING: Remove `server.socket.address` from HTTP and RPC client metrics. + ([#350](https://github.com/open-telemetry/semantic-conventions/pull/350)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 101ce3c5c0..e488fd5f60 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -463,7 +463,6 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -511,9 +510,6 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - `error.type` 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 | @@ -560,7 +556,6 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -608,9 +603,6 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - `error.type` 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 | @@ -657,7 +649,6 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | Recommended: If different than `server.address`. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -705,9 +696,6 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. **[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - `error.type` 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 | diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 8ff24ac2b8..44021f7d01 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -217,39 +217,41 @@ This metric is [recommended][MetricRecommended]. Below is a table of attributes that SHOULD be included on client and server RPC measurements. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [1] | `myservice.EchoService` | Recommended | -| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [2] | `exampleMethod` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [6] | `16456` | Recommended: [7] | +| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Recommended | +| [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [2] | `myservice.EchoService` | Recommended | +| [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [3] | `example.com` | Recommended | +| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Recommended | -**[1]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[2]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[3]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +the server address behind any intermediaries (e.g. proxies) if it's available. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. +`network.transport` 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. -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. - -**[7]:** If different than `server.port` and if `server.socket.address` is set. +| Value | Description | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. See note below. | +| `unix` | Unix domain socket | -**Additional attribute requirements:** At least one of the following sets of attributes is required: +`network.type` 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. -* [`server.socket.address`](../general/attributes.md) -* [`server.address`](../general/attributes.md) +| Value | Description | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | `rpc.system` 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. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index a5ceceb288..8e6f350929 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -66,7 +66,6 @@ groups: - ref: http.response.status_code - ref: network.protocol.name - ref: network.protocol.version - - ref: server.socket.address - ref: error.type requirement_level: conditionally_required: If request has ended with an error. diff --git a/model/metrics/rpc-metrics.yaml b/model/metrics/rpc-metrics.yaml index 237107e6d8..43186b0765 100644 --- a/model/metrics/rpc-metrics.yaml +++ b/model/metrics/rpc-metrics.yaml @@ -13,8 +13,6 @@ groups: - ref: network.type - ref: server.address - ref: server.port - - ref: server.socket.address - - ref: server.socket.port # RPC Server metrics - id: metric.rpc.server.duration From 3286326b17fdd9f6aebc17f97e1ee01f9d450577 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 2 Oct 2023 08:57:37 -0700 Subject: [PATCH 063/482] Improve network briefs (#352) --- CHANGELOG.md | 2 + docs/database/database-spans.md | 32 ++++++---- docs/general/attributes.md | 20 ++++-- docs/http/http-metrics.md | 102 +++++++++++++++++------------- docs/http/http-spans.md | 22 +++++-- docs/messaging/messaging-spans.md | 38 +++++++---- docs/rpc/rpc-metrics.md | 28 +++++--- docs/rpc/rpc-spans.md | 42 ++++++++---- docs/system/system-metrics.md | 8 ++- model/network.yaml | 18 +++--- 10 files changed, 197 insertions(+), 115 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18b2cb8f85..d93c97e1bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -127,6 +127,8 @@ release. ([#357](https://github.com/open-telemetry/semantic-conventions/pull/357)) - BREAKING: Remove `server.socket.address` from HTTP and RPC client metrics. ([#350](https://github.com/open-telemetry/semantic-conventions/pull/350)) +- Improve network attribute briefs. + ([#352](https://github.com/open-telemetry/semantic-conventions/pull/352)) ## v1.21.0 (2023-07-13) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index d942b29f16..544798808e 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,24 +67,32 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the database host. [1] | `example.com` | Conditionally Required: See alternative attributes below. | -| [`server.port`](../general/attributes.md) | int | Server port number [2] | `80`; `8080`; `443` | Conditionally Required: [3] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [4] | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [5] | `16456` | Recommended: If different than `server.port`. | - -**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com` | Conditionally Required: See alternative attributes below. | +| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: [5] | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | See below | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [7] | `16456` | Recommended: If different than `server.port`. | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[3]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[5]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[4]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. -**[5]:** When observed from the client side, this SHOULD represent the immediate server peer port. +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer port. When observed from the server side, this SHOULD represent the physical server port. **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 99fe0da717..e8160cfdb1 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -233,12 +233,22 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `network.transport` | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| `network.type` | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| `network.protocol.name` | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| `network.protocol.version` | string | Version of the application layer protocol used. See note below. [1] | `3.1.1` | Recommended | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | +| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | -**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** The value SHOULD be normalized to lowercase. + +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. `network.transport` 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. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e488fd5f60..f4fa7a8fc9 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -80,10 +80,10 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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. @@ -120,9 +120,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** The value SHOULD be normalized to lowercase. -**[5]:** Determined by using the first of the following that applies +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[6]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -132,7 +134,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[6]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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) @@ -250,10 +252,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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. @@ -290,9 +292,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** The value SHOULD be normalized to lowercase. -**[5]:** Determined by using the first of the following that applies +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[6]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -302,7 +306,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[6]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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) @@ -352,10 +356,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Opt-In | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[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. @@ -392,9 +396,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** The value SHOULD be normalized to lowercase. -**[5]:** Determined by using the first of the following that applies +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[6]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -404,7 +410,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[6]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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) @@ -459,10 +465,10 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -496,9 +502,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** The value SHOULD be normalized to lowercase. -**[4]:** Determined by using the first of the following that applies +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[5]:** 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 @@ -506,9 +514,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[6]:** If not default (`80` for `http` scheme, `443` for `https`). +**[7]:** If not default (`80` for `http` scheme, `443` for `https`). `error.type` 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. @@ -552,10 +560,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -589,9 +597,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** The value SHOULD be normalized to lowercase. -**[4]:** Determined by using the first of the following that applies +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[5]:** 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 @@ -599,9 +609,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[6]:** If not default (`80` for `http` scheme, `443` for `https`). +**[7]:** If not default (`80` for `http` scheme, `443` for `https`). `error.type` 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. @@ -645,10 +655,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -682,9 +692,11 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** The value SHOULD be normalized to lowercase. -**[4]:** Determined by using the first of the following that applies +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[5]:** 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 @@ -692,9 +704,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if capturing it would require an extra DNS lookup. -**[5]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. -**[6]:** If not default (`80` for `http` scheme, `443` for `https`). +**[7]:** If not default (`80` for `http` scheme, `443` for `https`). `error.type` 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. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 68a8a0cd50..929b81c027 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -123,10 +123,10 @@ sections below. | `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [3] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | | `error.type` | string | Describes a class of error the operation ended with. [4] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Conditionally Required: [7] | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Conditionally Required: [9] | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [10] | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | **[1]:** If and only if it's different than `http.request.method`. @@ -170,9 +170,19 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[6]:** The value SHOULD be normalized to lowercase. -**[7]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). +**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[8]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[9]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). + +**[10]:** The value SHOULD be normalized to lowercase. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 90f58da2fb..b1505e49d7 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -229,14 +229,14 @@ The following operations related to messages are defined for these semantic conv | `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [12] | | `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [13] | `2738` | Recommended: [14] | | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [15] | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [16] | `3.1.1` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [17] | `example.com` | Conditionally Required: If available. | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [18] | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [19] | `proxy.example.com` | Recommended: [20] | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [21] | `16456` | Recommended: If different than `server.port`. | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [20] | `example.com` | Conditionally Required: If available. | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [21] | `10.5.3.2` | Recommended: If different than `server.address`. | +| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [22] | `proxy.example.com` | Recommended: [23] | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [24] | `16456` | Recommended: If different than `server.port`. | **[1]:** If a custom value is used, it MUST be of low cardinality. @@ -271,18 +271,28 @@ size should be used. **[15]:** Only for spans that represent an operation on a single message. -**[16]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[16]:** The value SHOULD be normalized to lowercase. -**[17]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +**[17]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[18]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[18]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[19]:** The value SHOULD be normalized to lowercase. + +**[20]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[21]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. -**[19]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. +**[22]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. -**[20]:** If different than `server.address` and if `server.socket.address` is set. +**[23]:** If different than `server.address` and if `server.socket.address` is set. -**[21]:** When observed from the client side, this SHOULD represent the immediate server peer port. +**[24]:** When observed from the client side, this SHOULD represent the immediate server peer port. When observed from the server side, this SHOULD represent the physical server port. `messaging.operation` 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. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 44021f7d01..ac07909f79 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -220,22 +220,30 @@ measurements. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Recommended | -| [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [2] | `myservice.EchoService` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | +| [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [3] | `example.com` | Recommended | -| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Recommended | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [5] | `example.com` | Recommended | +| [`server.port`](../general/attributes.md) | int | Server port number [6] | `80`; `8080`; `443` | Recommended | -**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[1]:** The value SHOULD be normalized to lowercase. -**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[4]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. `network.transport` 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. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 9a9ae62cc7..d45cf2c6ea 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -88,28 +88,36 @@ Examples of span names: | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [1] | `myservice.EchoService` | Recommended | | `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [2] | `exampleMethod` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: See below | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [6] | `16456` | Recommended: [7] | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com` | Required | +| [`server.port`](../general/attributes.md) | int | Server port number [6] | `80`; `8080`; `443` | Conditionally Required: See below | +| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | See below | +| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [8] | `16456` | Recommended: [9] | **[1]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). **[2]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[3]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. +**[3]:** The value SHOULD be normalized to lowercase. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. -**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[4]:** The value SHOULD be normalized to lowercase. + +**[5]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. + +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. + +**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer port. +**[8]:** When observed from the client side, this SHOULD represent the immediate server peer port. When observed from the server side, this SHOULD represent the physical server port. -**[7]:** If different than `server.port` and if `server.socket.address` is set. +**[9]:** If different than `server.port` and if `server.socket.address` is set. **Additional attribute requirements:** At least one of the following sets of attributes is required: @@ -165,8 +173,8 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | | [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [5] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [6] | `ipv4`; `ipv6` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. @@ -177,6 +185,14 @@ When observed from the client side, this SHOULD represent the physical client ad **[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. When observed from the client side, this SHOULD represent the physical client port. + +**[5]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[6]:** The value SHOULD be normalized to lowercase. ### Events diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 8fa2bfa16f..745c9c25a0 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -637,10 +637,16 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. | `tcp`; `udp` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | | `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + `network.transport` 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 | diff --git a/model/network.yaml b/model/network.yaml index 28074ba84d..2b969ea36e 100644 --- a/model/network.yaml +++ b/model/network.yaml @@ -22,9 +22,11 @@ groups: value: 'unix' brief: "Unix domain socket" brief: > - [OSI Transport Layer](https://osi-model.com/transport-layer/) or - [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). + [OSI transport layer](https://osi-model.com/transport-layer/) or + [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). + note: | The value SHOULD be normalized to lowercase. + Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. @@ -39,19 +41,17 @@ groups: - id: ipv6 value: 'ipv6' brief: "IPv6" - brief: > - [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. - The value SHOULD be normalized to lowercase. + brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. examples: ['ipv4', 'ipv6'] - id: protocol.name type: string - brief: > - [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. - The value SHOULD be normalized to lowercase. + brief: '[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. examples: ['amqp', 'http', 'mqtt'] - id: protocol.version type: string - brief: 'Version of the application layer protocol used. See note below.' + brief: Version of the protocol specified in `network.protocol.name`. examples: '3.1.1' note: > `network.protocol.version` refers to the version of the protocol used and might be From 590aff7ffc42d77c7c6feef76fe134976fb64c29 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 2 Oct 2023 18:00:05 +0100 Subject: [PATCH 064/482] Document the difference between host and system metrics (#324) Signed-off-by: ChrsMark Co-authored-by: Joao Grassi Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- docs/resource/host.md | 3 +++ docs/system/system-metrics.md | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/docs/resource/host.md b/docs/resource/host.md index 150755dc19..7469f8f40f 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -6,6 +6,9 @@ **Description:** A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. +The `host.*` namespace SHOULD be exclusively used to capture resource attributes. +To report host metrics, the `system.*` namespace SHOULD be used. + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 745c9c25a0..a06d5b9664 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -11,6 +11,12 @@ metrics in OpenTelemetry. Consider the [general metric semantic conventions](/docs/general/metrics.md#general-metric-semantic-conventions) when creating instruments not explicitly defined in the specification. +The `system.*` namespace SHOULD be exclusively used to report hosts' metrics. +The `system.*` namespace SHOULD only be used when the metrics are collected from within the target system. (physical servers, virtual machines etc). +Metrics collected from technology-specific, well-defined APIs (e.g. Kubelet's API or container runtimes) +should be reported under their respective namespace (e.g. k8s.*, container.*). +Resource attributes related to a host, SHOULD be reported under the `host.*` namespace. + From 2c065be5e66bbaf00898b1a740bb3b3e47b8acc6 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 3 Oct 2023 00:37:56 -0700 Subject: [PATCH 065/482] Editorial: Update build-tools to 0.22.0 and sort attributes alphabetically in all semconv (#359) Co-authored-by: Armin Ruech --- Makefile | 2 +- docs/cloudevents/cloudevents-spans.md | 2 +- docs/database/cassandra.md | 8 +-- docs/database/cosmosdb.md | 18 +++---- docs/database/database-spans.md | 10 ++-- docs/database/dynamodb.md | 18 +++---- docs/database/elasticsearch.md | 10 ++-- docs/database/graphql.md | 2 +- docs/faas/faas-spans.md | 6 +-- docs/general/attributes.md | 68 ++++++++++++------------ docs/general/events.md | 2 +- docs/general/logs.md | 2 +- docs/http/http-metrics.md | 48 ++++++++--------- docs/http/http-spans.md | 60 ++++++++++----------- docs/jvm/jvm-metrics.md | 18 +++---- docs/messaging/kafka.md | 2 +- docs/messaging/messaging-spans.md | 56 +++++++++---------- docs/messaging/rocketmq.md | 30 +++++------ docs/object-stores/s3.md | 44 +++++++-------- docs/resource/README.md | 10 ++-- docs/resource/browser.md | 10 ++-- docs/resource/cloud-provider/aws/ecs.md | 2 +- docs/resource/cloud-provider/aws/logs.md | 10 ++-- docs/resource/cloud-provider/gcp/gce.md | 2 +- docs/resource/cloud-provider/heroku.md | 4 +- docs/resource/cloud.md | 46 ++++++++-------- docs/resource/container.md | 22 ++++---- docs/resource/device.md | 12 ++--- docs/resource/faas.md | 58 ++++++++++---------- docs/resource/host.md | 12 ++--- docs/resource/k8s.md | 14 ++--- docs/resource/os.md | 4 +- docs/resource/process.md | 12 ++--- docs/resource/webengine.md | 2 +- docs/rpc/grpc.md | 2 +- docs/rpc/json-rpc.md | 4 +- docs/rpc/rpc-spans.md | 24 ++++----- docs/url/url.md | 4 +- internal/tools/schema_check.sh | 10 ++-- model/README.md | 6 +-- 40 files changed, 339 insertions(+), 337 deletions(-) diff --git a/Makefile b/Makefile index a87243775e..c6d956424b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! -SEMCONVGEN_VERSION=0.21.0 +SEMCONVGEN_VERSION=0.22.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index d13a8d5300..a985cae034 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -205,8 +205,8 @@ The following attributes are applicable to creation and processing Spans. | `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | Required | | `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | Required | | `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | Recommended | -| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | Recommended | | `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | Recommended | +| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | Recommended | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index fc420a9f5d..41380ebedc 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -17,13 +17,13 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | Recommended | | `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | Recommended | -| `db.cassandra.table` | string | The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | +| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | Recommended | +| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | Recommended | | `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | Recommended | +| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | Recommended | | `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | Recommended | -| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | Recommended | -| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | Recommended | +| `db.cassandra.table` | string | The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | | [`db.name`](database-spans.md) | string | The keyspace name in Cassandra. [2] | `mykeyspace` | Conditionally Required: If applicable. | **[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 83425d15bb..c5b2a1a836 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -21,13 +21,13 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | Recommended | -| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | Conditionally Required: [1] | | `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | Conditionally Required: if not `direct` (or pick gw as default) | | `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | Conditionally Required: if available | +| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | Conditionally Required: [1] | +| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | Conditionally Required: when available | | `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | Recommended | | `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | Conditionally Required: if response was received | | `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | Conditionally Required: [2] | -| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | Conditionally Required: when available | | `user_agent.original` | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | Recommended | **[1]:** when performing one of the operations in this list @@ -38,6 +38,13 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). Default value is "NS". +`db.cosmosdb.connection_mode` MUST be one of the following: + +| Value | Description | +|---|---| +| `gateway` | Gateway (HTTP) connections mode | +| `direct` | Direct connection. | + `db.cosmosdb.operation_type` 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 | @@ -57,13 +64,6 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | `Batch` | batch | | `QueryPlan` | query_plan | | `ExecuteJavaScript` | execute_javascript | - -`db.cosmosdb.connection_mode` MUST be one of the following: - -| Value | Description | -|---|---| -| `gateway` | Gateway (HTTP) connections mode | -| `direct` | Direct connection. | In addition to Cosmos DB attributes, all spans include diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 544798808e..05314a27fd 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -64,8 +64,8 @@ Some database systems may allow a connection to switch to a different `db.user`, | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | @@ -185,14 +185,14 @@ Usually only one `db.name` will be used per connection though. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | -| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [2] | -| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [3] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | +| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | +| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). -**[2]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. -**[3]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +**[3]:** Should be collected by default only if there is sanitization that excludes sensitive information. ## Semantic Conventions for specific database technologies diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index f37e918366..13a6ec9ce1 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -46,10 +46,10 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | -| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | Recommended | | `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | +| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | | `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | +| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | Recommended | | `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | @@ -98,8 +98,8 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | Recommended | -| `aws.dynamodb.table_count` | int | The the number of items in the `TableNames` response parameter. | `20` | Recommended | | `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | +| `aws.dynamodb.table_count` | int | The the number of items in the `TableNames` response parameter. | `20` | Recommended | ## DynamoDB.PutItem @@ -117,13 +117,13 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | Recommended | | `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | Recommended | | `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | Recommended | | `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | | `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | Recommended | | `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | | `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | Recommended | +| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | Recommended | | `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | Recommended | | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | @@ -133,18 +133,18 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | Recommended | -| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | Recommended | -| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | Recommended | -| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | Recommended | | `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | Recommended | | `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | Recommended | | `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | +| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | Recommended | | `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | Recommended | | `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | | `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | Recommended | +| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | Recommended | +| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | Recommended | | `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | Recommended | | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | Recommended | ## DynamoDB.UpdateItem @@ -163,8 +163,8 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | Recommended | -| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | | `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | +| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | | `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 8dd4a5fc4d..cd0c069fd7 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -32,9 +32,9 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | `http.request.method` | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [7] | `example.com` | See below | -| [`server.port`](../general/attributes.md) | int | Server port number [8] | `80`; `8080`; `443` | Recommended | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [9] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com` | Conditionally Required: See alternative attributes below. | +| [`server.port`](../general/attributes.md) | int | Server port number [8] | `80`; `8080`; `443` | Conditionally Required: [9] | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. @@ -66,7 +66,9 @@ the server address behind any intermediaries (e.g. proxies) if it's available. **[8]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[9]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. diff --git a/docs/database/graphql.md b/docs/database/graphql.md index 8cc6409866..7e3d6a8a06 100644 --- a/docs/database/graphql.md +++ b/docs/database/graphql.md @@ -17,9 +17,9 @@ MAY be used as span name. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | Recommended | | `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | Recommended | | `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | Recommended | -| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | Recommended | **[1]:** The value may be sanitized to exclude sensitive information. diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 8a90312273..e1e7066b32 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -41,8 +41,8 @@ If Spans following this convention are produced, a Resource of type `faas` MUST | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | | [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | | `faas.trigger` | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | **[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, @@ -200,9 +200,9 @@ FaaS instrumentations that produce `faas` spans with trigger `datasource`, SHOUL | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | Required | +| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | Recommended | | `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | Required | | `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | -| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | Recommended | `faas.document.operation` 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. @@ -232,8 +232,8 @@ A function is scheduled to be executed regularly. The following additional attri | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | | `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | Recommended | +| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | ### Other diff --git a/docs/general/attributes.md b/docs/general/attributes.md index e8160cfdb1..6111990606 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -68,8 +68,8 @@ if they do not cause breaking changes to HTTP semantic conventions. |---|---|---|---|---| | `server.address` | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `example.com` | Recommended | | `server.port` | int | Server port number [2] | `80`; `8080`; `443` | Recommended | -| `server.socket.domain` | string | Immediate server peer's domain name if available without reverse DNS lookup [3] | `proxy.example.com` | Recommended: If different than `server.address`. | -| `server.socket.address` | string | Server address of the socket connection - IP address or Unix domain socket name. [4] | `10.5.3.2` | Recommended: If different than `server.address`. | +| `server.socket.address` | string | Server address of the socket connection - IP address or Unix domain socket name. [3] | `10.5.3.2` | Recommended: If different than `server.address`. | +| `server.socket.domain` | string | Immediate server peer's domain name if available without reverse DNS lookup [4] | `proxy.example.com` | Recommended: If different than `server.address`. | | `server.socket.port` | int | Server port number of the socket connection. [5] | `16456` | Recommended: If different than `server.port`. | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent @@ -77,11 +77,11 @@ the server address behind any intermediaries (e.g. proxies) if it's available. **[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[3]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. - -**[4]:** When observed from the client side, this SHOULD represent the immediate server peer address. +**[3]:** When observed from the client side, this SHOULD represent the immediate server peer address. When observed from the server side, this SHOULD represent the physical server address. +**[4]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. + **[5]:** When observed from the client side, this SHOULD represent the immediate server peer port. When observed from the server side, this SHOULD represent the physical server port. @@ -200,8 +200,8 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `source.domain` | string | The domain name of the source system. [1] | `foo.example.com` | Recommended | | `source.address` | string | Source address, for example IP address or Unix socket name. | `10.5.3.2` | Recommended | +| `source.domain` | string | The domain name of the source system. [1] | `foo.example.com` | Recommended | | `source.port` | int | Source port number | `3389`; `2888` | Recommended | **[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. @@ -214,8 +214,8 @@ Destination fields capture details about the receiver of a network exchange/pack | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `destination.domain` | string | The domain name of the destination system. [1] | `foo.example.com` | Recommended | | `destination.address` | string | Destination address, for example IP address or UNIX socket name. | `10.5.3.2` | Recommended | +| `destination.domain` | string | The domain name of the destination system. [1] | `foo.example.com` | Recommended | | `destination.port` | int | Destination port number | `3389`; `2888` | Recommended | **[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. @@ -233,22 +233,22 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | -| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | +| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. +**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[3]:** The value SHOULD be normalized to lowercase. + Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. -**[2]:** The value SHOULD be normalized to lowercase. - -**[3]:** The value SHOULD be normalized to lowercase. - -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** The value SHOULD be normalized to lowercase. `network.transport` 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. @@ -272,22 +272,12 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `network.connection.type` | string | The internet connection type. | `wifi` | Recommended | -| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | Recommended | -| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | Recommended | +| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | Recommended | | `network.carrier.mcc` | string | The mobile carrier country code. | `310` | Recommended | | `network.carrier.mnc` | string | The mobile carrier network code. | `001` | Recommended | -| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | Recommended | - -`network.connection.type` 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 | -|---|---| -| `wifi` | wifi | -| `wired` | wired | -| `cell` | cell | -| `unavailable` | unavailable | -| `unknown` | unknown | +| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | Recommended | +| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | Recommended | +| `network.connection.type` | string | The internet connection type. | `wifi` | Recommended | `network.connection.subtype` 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. @@ -314,6 +304,16 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `nr` | 5G NR (New Radio) | | `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | | `lte_ca` | LTE CA | + +`network.connection.type` 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 | +|---|---| +| `wifi` | wifi | +| `wired` | wired | +| `cell` | cell | +| `unavailable` | unavailable | +| `unknown` | unknown | For `Unix` and `pipe`, since the connection goes over the file system instead of being directly to a known peer, `server.address` is the only attribute that usually makes sense (see description of `server.address` below). @@ -389,9 +389,9 @@ a thread that started a span. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | | `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | | `thread.name` | string | Current thread name. | `main` | Recommended | -| `thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | Examples of where `thread.id` and `thread.name` can be extracted from: @@ -416,11 +416,11 @@ about the span. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | -| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | +| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | Recommended | | `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | Recommended | +| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | | `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | Recommended | -| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | Recommended | +| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/general/events.md b/docs/general/events.md index bb05d9a015..92747e77d9 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -43,8 +43,8 @@ that identify the class of Events but not the instance of the Event. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `event.name` | string | The name identifies the event. | `click`; `exception` | Required | | `event.domain` | string | The domain identifies the business context for the events. [1] | `browser` | Required | +| `event.name` | string | The name identifies the event. | `click`; `exception` | Required | **[1]:** Events across different domains may have same `event.name`, yet be unrelated events. diff --git a/docs/general/logs.md b/docs/general/logs.md index 0ccdbb7c73..555530f58a 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -60,8 +60,8 @@ As such, these should be recorded as Log Record attributes when applicable. They | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `log.file.name` | string | The basename of the file. | `audit.log` | Recommended | -| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | Opt-In | | `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | Opt-In | +| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | Opt-In | | `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | Opt-In | diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index f4fa7a8fc9..c406fa9e9e 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -76,20 +76,17 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `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 | -| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | -**[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](/docs/http/http-spans.md#http-server-definitions) if there is one. - -**[2]:** If the request fails with an error before response status code was sent or received, +**[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), @@ -105,7 +102,7 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -120,6 +117,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + **[4]:** The value SHOULD be normalized to lowercase. **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. @@ -248,20 +248,17 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `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 | -| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | -**[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](/docs/http/http-spans.md#http-server-definitions) if there is one. - -**[2]:** If the request fails with an error before response status code was sent or received, +**[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), @@ -277,7 +274,7 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -292,6 +289,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + **[4]:** The value SHOULD be normalized to lowercase. **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. @@ -352,20 +352,17 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `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 | -| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | -**[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](/docs/http/http-spans.md#http-server-definitions) if there is one. - -**[2]:** If the request fails with an error before response status code was sent or received, +**[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), @@ -381,7 +378,7 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -396,6 +393,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + **[4]:** The value SHOULD be normalized to lowercase. **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 929b81c027..0548eaf01e 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -115,31 +115,21 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.response.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.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [1] | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | `http.request.body.size` | 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.body.size` | 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.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [3] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | -| `error.type` | string | Describes a class of error the operation ended with. [4] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [5] | `GET`; `POST`; `HEAD` | Required | +| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | +| `http.response.body.size` | 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.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | +| `http.response.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. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Conditionally Required: [9] | | [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [10] | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | -**[1]:** If and only if it's different than `http.request.method`. - -**[2]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -**[3]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -**[4]:** If the request fails with an error before response status code was sent or received, +**[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), @@ -155,7 +145,11 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[5]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -170,6 +164,12 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +**[4]:** If and only if it's different than `http.request.method`. + +**[5]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + **[6]:** The value SHOULD be normalized to lowercase. **[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. @@ -375,11 +375,11 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `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 | -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [2] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [3] | `65123` | Recommended | -| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [4] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [5] | `35555` | Recommended: If different than `client.port`. | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | +| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | +| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | +| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | +| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Recommended: [8] | | [`server.socket.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. [9] | `10.5.3.2` | Opt-In | @@ -388,19 +388,19 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [12] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | -**[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](/docs/http/http-spans.md#http-server-definitions) if there is one. - -**[2]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. +**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[3]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. -**[4]:** When observed from the server side, this SHOULD represent the immediate client peer address. +**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. When observed from the client side, this SHOULD represent the physical client address. -**[5]:** When observed from the server side, this SHOULD represent the immediate client peer port. +**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. When observed from the client side, this SHOULD represent the physical client port. +**[5]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + **[6]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only diff --git a/docs/jvm/jvm-metrics.md b/docs/jvm/jvm-metrics.md index 6272e494fe..efcf94ca6e 100644 --- a/docs/jvm/jvm-metrics.md +++ b/docs/jvm/jvm-metrics.md @@ -57,8 +57,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -84,8 +84,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -111,8 +111,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -138,8 +138,8 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -174,12 +174,12 @@ of `[]` (single bucket histogram capturing count, sum, min, max). | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.gc.name` | string | Name of the garbage collector. [1] | `G1 Young Generation`; `G1 Old Generation` | Recommended | -| `jvm.gc.action` | string | Name of the garbage collector action. [2] | `end of minor GC`; `end of major GC` | Recommended | +| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | Recommended | +| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | Recommended | -**[1]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). +**[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). -**[2]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). +**[2]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). ## JVM Threads @@ -322,8 +322,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 052bebacb8..90fd518580 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -27,9 +27,9 @@ For Apache Kafka, the following additional attributes are defined: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | Recommended | | `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | Recommended | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | | `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | Recommended | | `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | Conditionally Required: [2] | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index b1505e49d7..8faceefe39 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -217,18 +217,18 @@ The following operations related to messages are defined for these semantic conv | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | -| `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [1] | `publish` | Required | -| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [2] | `0`; `1`; `2` | Conditionally Required: [3] | +| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | Conditionally Required: [2] | | `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | -| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [4] | -| `messaging.destination.name` | string | The message destination name [5] | `MyQueue`; `MyTopic` | Conditionally Required: [6] | -| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [7] | `/customers/{customerId}` | Conditionally Required: [8] | -| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [9] | -| `messaging.message.body.size` | int | The size of the message body in bytes. [10] | `1439` | Recommended: [11] | -| `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [12] | -| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [13] | `2738` | Recommended: [14] | -| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [15] | +| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [3] | +| `messaging.destination.name` | string | The message destination name [4] | `MyQueue`; `MyTopic` | Conditionally Required: [5] | +| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [6] | `/customers/{customerId}` | Conditionally Required: [7] | +| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [8] | +| `messaging.message.body.size` | int | The size of the message body in bytes. [9] | `1439` | Recommended: [10] | +| `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [11] | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | +| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | +| `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [15] | `publish` | Required | +| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | @@ -238,38 +238,38 @@ The following operations related to messages are defined for these semantic conv | [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [22] | `proxy.example.com` | Recommended: [23] | | [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [24] | `16456` | Recommended: If different than `server.port`. | -**[1]:** If a custom value is used, it MUST be of low cardinality. +**[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. -**[2]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +**[2]:** If the span describes an operation on a batch of messages. -**[3]:** If the span describes an operation on a batch of messages. +**[3]:** If value is `true`. When missing, the value is assumed to be `false`. -**[4]:** If value is `true`. When missing, the value is assumed to be `false`. - -**[5]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[4]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker does not have such notion, the destination name SHOULD uniquely identify the broker. -**[6]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[5]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[7]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[6]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[8]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[7]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[9]:** If value is `true`. When missing, the value is assumed to be `false`. +**[8]:** If value is `true`. When missing, the value is assumed to be `false`. -**[10]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[9]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[11]:** Only if span represents operation on a single message. +**[10]:** Only if span represents operation on a single message. -**[12]:** Only if span represents operation on a single message. +**[11]:** Only if span represents operation on a single message. -**[13]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[12]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[14]:** Only if span represents operation on a single message. +**[13]:** Only if span represents operation on a single message. + +**[14]:** Only for spans that represent an operation on a single message. -**[15]:** Only for spans that represent an operation on a single message. +**[15]:** If a custom value is used, it MUST be of low cardinality. **[16]:** The value SHOULD be normalized to lowercase. @@ -339,8 +339,8 @@ under the namespace `messaging.destination_publish.*` | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | | `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | Recommended | +| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | **[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker does not have such notion, the original destination name SHOULD uniquely identify the broker. diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index a0b88daa06..cf7c88c194 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -19,19 +19,26 @@ Specific attributes for Apache RocketMQ are defined below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | Required | | `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | Required | -| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | Conditionally Required: [1] | -| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | Conditionally Required: [2] | +| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | Recommended | +| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | Conditionally Required: [1] | +| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | Conditionally Required: [2] | | `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | Conditionally Required: If the message type is FIFO. | -| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | Recommended | -| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | Recommended | | `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | Recommended | -| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | Recommended | +| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | Recommended | +| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | Recommended | +| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | Required | + +**[1]:** If the message type is delay and delivery timestamp is not specified. -**[1]:** If the message type is delay and delay time level is not specified. +**[2]:** If the message type is delay and delay time level is not specified. + +`messaging.rocketmq.consumption_model` MUST be one of the following: -**[2]:** If the message type is delay and delivery timestamp is not specified. +| Value | Description | +|---|---| +| `clustering` | Clustering consumption model | +| `broadcasting` | Broadcasting consumption model | `messaging.rocketmq.message.type` MUST be one of the following: @@ -41,13 +48,6 @@ Specific attributes for Apache RocketMQ are defined below. | `fifo` | FIFO message | | `delay` | Delay message | | `transaction` | Transaction message | - -`messaging.rocketmq.consumption_model` MUST be one of the following: - -| Value | Description | -|---|---| -| `clustering` | Clustering consumption model | -| `broadcasting` | Broadcasting consumption model | `messaging.client_id` SHOULD be set to the client ID that is automatically generated by the Apache RocketMQ SDK. diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index 71d6c56360..904d9c0ad0 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -15,16 +15,27 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | Recommended | -| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [2] | `someFile.yml` | Recommended | -| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [3] | `someFile.yml` | Recommended | -| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [4] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | Recommended | -| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [5] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | Recommended | -| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [6] | `3456` | Recommended | +| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | Recommended | +| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | Recommended | +| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | Recommended | +| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | Recommended | +| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | Recommended | **[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. -**[2]:** The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. +**[2]:** The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter +of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). +This applies in particular to the following operations: + +- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + +**[3]:** The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. +The `delete` attribute corresponds to the `--delete` parameter of the +[delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). + +**[4]:** The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. This applies in particular to the following operations: - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) @@ -41,14 +52,12 @@ This applies in particular to the following operations: - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) -**[3]:** The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter -of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). -This applies in particular to the following operations: - -- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) -- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) +**[5]:** The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. +The `part_number` attribute corresponds to the `--part-number` parameter of the +[upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). -**[4]:** The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter +**[6]:** The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. This applies in particular to the following operations: @@ -57,15 +66,6 @@ This applies in particular to the following operations: - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - -**[5]:** The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. -The `delete` attribute corresponds to the `--delete` parameter of the -[delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). - -**[6]:** The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) -and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. -The `part_number` attribute corresponds to the `--part-number` parameter of the -[upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/resource/README.md b/docs/resource/README.md index c7637f565f..312200f716 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -99,12 +99,12 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `service.namespace` | string | A namespace for `service.name`. [1] | `Shop` | Recommended | -| `service.instance.id` | string | The string ID of the service instance. [2] | `my-k8s-pod-deployment-1`; `627cc493-f310-47de-96bd-71410b7dec09` | Recommended | +| `service.instance.id` | string | The string ID of the service instance. [1] | `my-k8s-pod-deployment-1`; `627cc493-f310-47de-96bd-71410b7dec09` | Recommended | +| `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | Recommended | -**[1]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. +**[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent and stay the same for the lifetime of the service instance, however it is acceptable that the ID is ephemeral and changes during important lifetime events for the service (e.g. service restarts). If the service has no inherent unique ID that can be used as the value of this attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). -**[2]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent and stay the same for the lifetime of the service instance, however it is acceptable that the ID is ephemeral and changes during important lifetime events for the service (e.g. service restarts). If the service has no inherent unique ID that can be used as the value of this attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). +**[2]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. Note: `service.namespace` and `service.name` are not intended to be concatenated for the purpose of forming a single globally unique name for the service. For example the following 2 sets of attributes actually describe 2 different services (despite the fact that the concatenation would result in the same string): @@ -132,8 +132,8 @@ service.name = Shop.shoppingcart | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | Required | | `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | Required | +| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | Required | | `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | Required | **[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. diff --git a/docs/resource/browser.md b/docs/resource/browser.md index a914a1f24e..9f5b164d88 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -12,19 +12,19 @@ All of these attributes can be provided by the user agent itself in the form of | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | Recommended | -| `browser.platform` | string | The platform on which the browser is running [2] | `Windows`; `macOS`; `Android` | Recommended | +| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | | `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | Recommended | -| `browser.language` | string | Preferred language of the user using the browser [4] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | +| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | Recommended | | `user_agent.original` | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | Recommended | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). -**[2]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. -The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. +**[2]:** This value is intended to be taken from the Navigator API `navigator.language`. **[3]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. -**[4]:** This value is intended to be taken from the Navigator API `navigator.language`. +**[4]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. +The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. **[5]:** The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used. diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index ba3ae6183b..eefbee3103 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -9,8 +9,8 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | Recommended | | `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | Recommended | +| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | Recommended | | `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | Recommended | | `aws.ecs.task.arn` | string | The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b` | Recommended | | `aws.ecs.task.family` | string | The task definition family this task definition is a member of. | `opentelemetry-family` | Recommended | diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index d2238e68d6..5001849225 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -9,14 +9,14 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [1] | `[/aws/lambda/my-function, opentelemetry-service]` | Recommended | -| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [2] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | Recommended | -| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | Recommended | +| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | Recommended | +| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | Recommended | | `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | Recommended | +| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | Recommended | -**[1]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. +**[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). -**[2]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). +**[2]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. **[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. diff --git a/docs/resource/cloud-provider/gcp/gce.md b/docs/resource/cloud-provider/gcp/gce.md index 49d9954643..986ce0fbe5 100644 --- a/docs/resource/cloud-provider/gcp/gce.md +++ b/docs/resource/cloud-provider/gcp/gce.md @@ -7,6 +7,6 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | Recommended | | `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | Recommended | +| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | Recommended | diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index fb0171cd75..2344373f0a 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | Opt-In | -| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | Opt-In | | `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | Opt-In | +| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | Opt-In | +| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | Opt-In | **Mapping:** diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index 7967c30976..871c36f5bd 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -9,16 +9,20 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | | `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | Recommended | -| `cloud.region` | string | The geographical region the resource is running. [1] | `us-central1`; `us-east-1` | Recommended | -| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [2] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | -| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [3] | `us-east-1c` | Recommended | -| `cloud.platform` | string | The cloud platform in use. [4] | `alibaba_cloud_ecs` | Recommended | +| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | Recommended | +| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | Recommended | +| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | +| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | Recommended | +| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | + +**[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. + +**[2]:** The prefix of the service SHOULD match the one specified in `cloud.provider`. -**[1]:** Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). +**[3]:** Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). -**[2]:** On some cloud providers, it may not be possible to determine the full ID at startup, +**[4]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. The exact value to use for `cloud.resource_id` depends on the cloud provider. @@ -36,22 +40,6 @@ The following well-known definitions MUST be used if you set this attribute and This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. -**[3]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. - -**[4]:** The prefix of the service SHOULD match the one specified in `cloud.provider`. - -`cloud.provider` 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 | -|---|---| -| `alibaba_cloud` | Alibaba Cloud | -| `aws` | Amazon Web Services | -| `azure` | Microsoft Azure | -| `gcp` | Google Cloud Platform | -| `heroku` | Heroku Platform as a Service | -| `ibm_cloud` | IBM Cloud | -| `tencent_cloud` | Tencent Cloud | - `cloud.platform` 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 | @@ -83,6 +71,18 @@ The following well-known definitions MUST be used if you set this attribute and | `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | | `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | | `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | + +`cloud.provider` 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 | +|---|---| +| `alibaba_cloud` | Alibaba Cloud | +| `aws` | Amazon Web Services | +| `azure` | Microsoft Azure | +| `gcp` | Google Cloud Platform | +| `heroku` | Heroku Platform as a Service | +| `ibm_cloud` | IBM Cloud | +| `tencent_cloud` | Tencent Cloud | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/resource/container.md b/docs/resource/container.md index cc9ff9fd34..7c4a014932 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -9,25 +9,25 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | +| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | Opt-In | +| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | +| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | | `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | Recommended | -| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | +| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | | `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | +| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | | `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | -| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [1] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | -| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [2] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | -| `container.command` | string | The command used to run the container (i.e. the command name). [3] | `otelcontribcol` | Opt-In | -| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | -| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | | `container.labels.` | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | Recommended | +| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | +| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | -**[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. +**[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + +**[2]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. -**[2]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. - -**[3]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. +**[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. ## Open Container Initiative (OCI) diff --git a/docs/resource/device.md b/docs/resource/device.md index 174057e861..5aa502c9a0 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -10,17 +10,17 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | Recommended | -| `device.model.identifier` | string | The model identifier for the device [2] | `iPhone3,4`; `SM-G920F` | Recommended | -| `device.model.name` | string | The marketing name for the device model [3] | `iPhone 6s Plus`; `Samsung Galaxy S6` | Recommended | -| `device.manufacturer` | string | The name of the device manufacturer [4] | `Apple`; `Samsung` | Recommended | +| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | Recommended | +| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | Recommended | +| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | Recommended | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. -**[2]:** It's recommended this value represents a machine readable version of the model identifier rather than the market or consumer-friendly name of the device. +**[2]:** The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. -**[3]:** It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. +**[3]:** It's recommended this value represents a machine readable version of the model identifier rather than the market or consumer-friendly name of the device. -**[4]:** The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. +**[4]:** It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/resource/faas.md b/docs/resource/faas.md index 4de83ef8d7..1c92319818 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -16,13 +16,35 @@ See also: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.name` | string | The name of the single function that this runtime instance executes. [1] | `my-function`; `myazurefunctionapp/some-function-name` | Required | -| `faas.version` | string | The immutable version of the function being executed. [2] | `26`; `pinkfroid-00002` | Recommended | -| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [3] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | -| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [4] | `134217728` | Recommended | -| [`cloud.resource_id`](cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [5] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | +| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | +| `faas.name` | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | +| `faas.version` | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | Recommended | -**[1]:** This is the name of the function as configured/deployed on the FaaS +**[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, +so it may be necessary to set `cloud.resource_id` as a span attribute instead. + +The exact value to use for `cloud.resource_id` depends on the cloud provider. +The following well-known definitions MUST be used if you set this attribute and they apply: + +* **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invokable with + multiple different aliases. +* **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) +* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. + +**[2]:** * **AWS Lambda:** Use the (full) log stream name. + +**[3]:** It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). + +**[4]:** This is the name of the function as configured/deployed on the FaaS platform and is usually different from the name of the callback function (which may be stored in the [`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) @@ -39,7 +61,7 @@ definition of function name MUST be used for this attribute app can host multiple functions that would usually share a TracerProvider (see also the `cloud.resource_id` attribute). -**[2]:** Depending on the cloud provider and platform, use: +**[5]:** Depending on the cloud provider and platform, use: * **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) (an integer represented as a decimal string). @@ -48,28 +70,6 @@ definition of function name MUST be used for this attribute * **Google Cloud Functions:** The value of the [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). * **Azure Functions:** Not applicable. Do not set this attribute. - -**[3]:** * **AWS Lambda:** Use the (full) log stream name. - -**[4]:** It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). - -**[5]:** On some cloud providers, it may not be possible to determine the full ID at startup, -so it may be necessary to set `cloud.resource_id` as a span attribute instead. - -The exact value to use for `cloud.resource_id` depends on the cloud provider. -The following well-known definitions MUST be used if you set this attribute and they apply: - -* **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). - Take care not to use the "invoked ARN" directly but replace any - [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) - with the resolved function version, as the same runtime instance may be invokable with - multiple different aliases. -* **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form - `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. - This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - a TracerProvider. Note: The resource attribute `faas.instance` differs from the span attribute `faas.invocation_id`. For more information see the [Semantic conventions for FaaS spans](/docs/faas/faas-spans.md#difference-between-invocation-and-instance). diff --git a/docs/resource/host.md b/docs/resource/host.md index 7469f8f40f..f216a78c92 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -12,13 +12,13 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | Recommended | -| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | -| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | | `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | Recommended | -| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | +| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | Recommended | | `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | Recommended | +| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | | `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). | `0.1` | Recommended | +| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | +| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | `host.arch` 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. @@ -39,12 +39,12 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | +| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | | `host.cpu.family` | int | Numeric value specifying the family or generation of the CPU. | `6` | Opt-In | | `host.cpu.model.id` | int | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6` | Opt-In | | `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | | `host.cpu.stepping` | int | Stepping or core revisions. | `1` | Opt-In | -| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | +| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index 6aada5e772..c0f5769094 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -91,8 +91,8 @@ containers on your cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | +| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Container @@ -127,8 +127,8 @@ any given time. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | +| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Deployment @@ -144,8 +144,8 @@ distributed among the nodes of a cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | Recommended | +| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## StatefulSet @@ -160,8 +160,8 @@ about the ordering and uniqueness of these Pods. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | Recommended | +| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## DaemonSet @@ -175,8 +175,8 @@ A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | Recommended | +| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Job @@ -191,8 +191,8 @@ successfully terminate. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.job.name` | string | The name of the Job. | `opentelemetry` | Recommended | +| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## CronJob @@ -206,8 +206,8 @@ A CronJob creates Jobs on a repeating schedule. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | Recommended | +| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/resource/os.md b/docs/resource/os.md index 585c29d10c..a868349619 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -11,11 +11,11 @@ In case of virtualized environments, this is the operating system as it is obser | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `os.type` | string | The operating system type. | `windows` | Required | +| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | | `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | Recommended | | `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | Recommended | +| `os.type` | string | The operating system type. | `windows` | Required | | `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | Recommended | -| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | `os.type` 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. diff --git a/docs/resource/process.md b/docs/resource/process.md index 388f26129c..24d1e7b8f9 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -27,14 +27,14 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `process.pid` | int | Process identifier (PID). | `1234` | Recommended | -| `process.parent_pid` | int | Parent Process identifier (PID). | `111` | Recommended | -| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | -| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | | `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | Conditionally Required: See alternative attributes below. | -| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | Conditionally Required: See alternative attributes below. | | `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | Conditionally Required: See alternative attributes below. | +| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | Conditionally Required: See alternative attributes below. | +| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | +| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | | `process.owner` | string | The username of the user that owns the process. | `root` | Recommended | +| `process.parent_pid` | int | Parent Process identifier (PID). | `111` | Recommended | +| `process.pid` | int | Process identifier (PID). | `1234` | Recommended | **Additional attribute requirements:** At least one of the following sets of attributes is required: @@ -62,9 +62,9 @@ In that case it MUST be interpreted as if it was `process.command_args`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | Recommended | | `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | Recommended | | `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | Recommended | -| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | Recommended | How to set these attributes for particular runtime kinds is described in the following subsections. diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 8b3a0985c7..72d61d2613 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | Recommended | | `webengine.name` | string | The name of the web engine. | `WildFly` | Required | | `webengine.version` | string | The version of the web engine. | `21.0.0` | Recommended | -| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | Recommended | Information describing the web engine SHOULD be captured using the values acquired from the API provided by the web engine, preferably during runtime, to avoid maintenance burden on engine version upgrades. As an example - Java engines are often but not always packaged as application servers. For Java application servers supporting Servlet API the required information MAY be captured by invoking `ServletContext.getServerInfo()` during runtime and parsing the result. diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index dd24a1ffa6..b02ab58cc9 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -19,9 +19,9 @@ Below is a table of attributes that SHOULD be included on client and server gRPC | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | | `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | | `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index 3c26a8eeb9..9ceed93d14 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -17,10 +17,10 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | -| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | | `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | Conditionally Required: If response is not successful. | | `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | Recommended | +| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | +| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Required | **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index d45cf2c6ea..98d753e20f 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -85,27 +85,27 @@ Examples of span names: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | +| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [1] | `myservice.EchoService` | Recommended | -| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [2] | `exampleMethod` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com` | Required | | [`server.port`](../general/attributes.md) | int | Server port number [6] | `80`; `8080`; `443` | Conditionally Required: See below | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | See below | | [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [8] | `16456` | Recommended: [9] | -**[1]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). - -**[2]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). - -**[3]:** The value SHOULD be normalized to lowercase. +**[1]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. -**[4]:** The value SHOULD be normalized to lowercase. +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[4]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). **[5]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. @@ -206,9 +206,9 @@ The event name MUST be `message`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `message.type` | string | Whether this is a received or sent message. | `SENT` | Recommended | -| `message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | Recommended | | `message.compressed_size` | int | Compressed size of the message in bytes. | | Recommended | +| `message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | Recommended | +| `message.type` | string | Whether this is a received or sent message. | `SENT` | Recommended | | `message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | Recommended | **[1]:** This way we guarantee that the values will be consistent between different implementations. diff --git a/docs/url/url.md b/docs/url/url.md index 0661c8dd8f..9f20f62170 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -25,11 +25,11 @@ This document defines semantic conventions that describe URL and its components. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | | `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | | `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | | `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index f89a391e2b..32c489d1a7 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -6,13 +6,13 @@ set -e -BUILD_TOOL_SCHEMAS_VERSION=0.21.0 +BUILD_TOOL_SCHEMAS_VERSION=0.22.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") # Verifies remote avilability of a schema file. -# +# # If the schema file is available for download, THEN we make sure it is exactly # what is in the repository. If the file is not available for download, # we pass this check. This is to allow releases to be checked in, where @@ -38,10 +38,10 @@ verify_remote_availability() { # 1 - version number verify_local_availability() { local ver="$1" - + file="$schemas_dir/$ver" echo -n "Ensure schema file $file exists... " - + # Check that the schema for the version exists. if [ -f "$file" ]; then echo "OK, exists." @@ -72,7 +72,7 @@ for file in $schemas_dir/*; do echo -n "Checking schema file $file for version $ver... " - # Check that the version is defined in the schema file. + # Check that the version is defined in the schema file. if ! grep -q "\s$ver:" $file; then echo "FAILED: $ver version definition is not found in $file" exit 1 diff --git a/model/README.md b/model/README.md index b80573074f..f32a08bb12 100644 --- a/model/README.md +++ b/model/README.md @@ -14,12 +14,12 @@ Semantic conventions for the spec MUST adhere to the [attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-requirement-level.md), and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md) conventions. -Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions/syntax.md) +Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. A schema file for VS code is configured in the `/.vscode/settings.json` of this repository, enabling auto-completion and additional checks. Refer to -[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions/README.md) for what extension you need. +[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions/README.md) for what extension you need. ## Generating markdown @@ -30,7 +30,7 @@ formatted Markdown tables for all semantic conventions in the specification. Run make table-generation ``` -For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.21.0/semantic-conventions) +For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions) in the OpenTelemetry build tools repository. Using this build tool, it is also possible to generate code for use in OpenTelemetry language projects. From 5181f045607637ed42013ac9e7f8a05bd3a2dd36 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 4 Oct 2023 09:31:07 -0700 Subject: [PATCH 066/482] Move Alexander Wert from approver to maintainer (#363) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1c1b8dbb9..d82c0365b7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/open-telemetry/teams/specs-semconv-approvers)): -- [Alexander Wert](https://github.com/AlexanderWert), Elastic - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian - [Johannes Tax](https://github.com/pyohannes), Grafana Labs @@ -29,6 +28,7 @@ _Find more about the approver role in [community repository](https://github.com/ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs/open-telemetry/teams/specs-semconv-maintainers)): +- [Alexander Wert](https://github.com/AlexanderWert), Elastic - [Armin Ruech](https://github.com/arminru), Dynatrace - [Joao Grassi](https://github.com/joaopgrassi), Dynatrace - [Josh Suereth](https://github.com/jsuereth), Google From b33f2fcbaff5f35d585f3117334d0b6eab2dfbc3 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 5 Oct 2023 15:12:31 +0200 Subject: [PATCH 067/482] telemetry.distro.name and telemetry.distro.version (#178) Co-authored-by: Reiley Yang --- CHANGELOG.md | 3 +++ docs/resource/README.md | 6 +++++- model/resource/telemetry_experimental.yaml | 12 ++++++++++-- schema-next.yaml | 6 ++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d93c97e1bf..5e010a3da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,6 +129,9 @@ release. ([#350](https://github.com/open-telemetry/semantic-conventions/pull/350)) - Improve network attribute briefs. ([#352](https://github.com/open-telemetry/semantic-conventions/pull/352)) +- BREAKING: Rename `telemetry.auto.version` resource attribute to `telemetry.distro.version` + and add `telemetry.distro.name` resource attribute + ([#178](https://github.com/open-telemetry/semantic-conventions/pull/178)) ## v1.21.0 (2023-07-13) diff --git a/docs/resource/README.md b/docs/resource/README.md index 312200f716..d0a4a272dc 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -172,7 +172,11 @@ All custom identifiers SHOULD be stable across different versions of an implemen | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `telemetry.auto.version` | string | The version string of the auto instrumentation agent, if used. | `1.2.3` | Recommended | +| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | Recommended | +| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | Recommended | + +**[1]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to +a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. ## Compute Unit diff --git a/model/resource/telemetry_experimental.yaml b/model/resource/telemetry_experimental.yaml index 6313705517..8f7b23554b 100644 --- a/model/resource/telemetry_experimental.yaml +++ b/model/resource/telemetry_experimental.yaml @@ -5,8 +5,16 @@ groups: brief: > The telemetry SDK used to capture data recorded by the instrumentation libraries. attributes: - - id: auto.version + - id: distro.name type: string brief: > - The version string of the auto instrumentation agent, if used. + The name of the auto instrumentation agent or distribution, if used. + note: | + Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to + a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. + examples: ["parts-unlimited-java"] + - id: distro.version + type: string + brief: > + The version string of the auto instrumentation agent or distribution, if used. examples: ["1.2.3"] diff --git a/schema-next.yaml b/schema-next.yaml index 4fecff3b2e..066a9ce9ef 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -135,6 +135,12 @@ versions: - rename_metrics: http.server.request.size: http.server.request.body.size http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version 1.21.0: spans: changes: From 2c30cf69fe005c1c6cc2fdbbda755b317cc7db74 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 5 Oct 2023 08:04:22 -0700 Subject: [PATCH 068/482] Add semconv-mobile-approvers (#368) Co-authored-by: Armin Ruech --- .github/CODEOWNERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0c016ce011..f541bc6faa 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -41,4 +41,8 @@ /docs/resource/host.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers /model/resource/host.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers +# Mobile semantic conventions approvers +/docs/mobile/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-mobile-approvers +/model/logs/mobile* @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-mobile-approvers + # TODO - Add semconv area experts From 5436da468d5b5f1889ef90ccba800ef65d6a429e Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 6 Oct 2023 05:29:07 -0700 Subject: [PATCH 069/482] Improve HTTP metric briefs (#366) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 14 +++++++------- model/metrics/http.yaml | 14 +++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e010a3da2..7f766e2eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -132,6 +132,8 @@ release. - BREAKING: Rename `telemetry.auto.version` resource attribute to `telemetry.distro.version` and add `telemetry.distro.name` resource attribute ([#178](https://github.com/open-telemetry/semantic-conventions/pull/178)) +- Improve HTTP metric briefs. + ([#366](https://github.com/open-telemetry/semantic-conventions/pull/366)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index c406fa9e9e..e90b3d9249 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -70,7 +70,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.request.duration` | Histogram | `s` | Measures the duration of inbound HTTP requests. | +| `http.server.request.duration` | Histogram | `s` | Duration of HTTP server requests. | @@ -172,7 +172,7 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.active_requests` | UpDownCounter | `{request}` | Measures the number of concurrent HTTP requests that are currently in-flight. | +| `http.server.active_requests` | UpDownCounter | `{request}` | Number of active HTTP server requests. | @@ -240,7 +240,7 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.request.body.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | +| `http.server.request.body.size` | Histogram | `By` | Size of HTTP server request bodies. [1] | **[1]:** 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. @@ -344,7 +344,7 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.server.response.body.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | +| `http.server.response.body.size` | Histogram | `By` | Size of HTTP server response bodies. [1] | **[1]:** 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. @@ -456,7 +456,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.request.duration` | Histogram | `s` | Measures the duration of outbound HTTP requests. | +| `http.client.request.duration` | Histogram | `s` | Duration of HTTP client requests. | @@ -549,7 +549,7 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.request.body.size` | Histogram | `By` | Measures the size of HTTP request messages. [1] | +| `http.client.request.body.size` | Histogram | `By` | Size of HTTP client request bodies. [1] | **[1]:** 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. @@ -644,7 +644,7 @@ This metric is optional. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `http.client.response.body.size` | Histogram | `By` | Measures the size of HTTP response messages. [1] | +| `http.client.response.body.size` | Histogram | `By` | Size of HTTP client response bodies. [1] | **[1]:** 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. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 8e6f350929..89c54cb2c6 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -92,7 +92,7 @@ groups: - id: metric.http.server.request.duration type: metric metric_name: http.server.request.duration - brief: "Measures the duration of inbound HTTP requests." + brief: "Duration of HTTP server requests." instrument: histogram unit: "s" extends: metric_attributes.http.server @@ -100,7 +100,7 @@ groups: - 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." + brief: "Number of active HTTP server requests." instrument: updowncounter unit: "{request}" attributes: @@ -138,7 +138,7 @@ groups: - id: metric.http.server.request.body.size type: metric metric_name: http.server.request.body.size - brief: "Measures the size of HTTP request messages." + brief: "Size of HTTP server request bodies." instrument: histogram unit: "By" note: > @@ -150,7 +150,7 @@ groups: - id: metric.http.server.response.body.size type: metric metric_name: http.server.response.body.size - brief: "Measures the size of HTTP response messages." + brief: "Size of HTTP server response bodies." instrument: histogram unit: "By" note: > @@ -162,7 +162,7 @@ groups: - id: metric.http.client.request.duration type: metric metric_name: http.client.request.duration - brief: "Measures the duration of outbound HTTP requests." + brief: "Duration of HTTP client requests." instrument: histogram unit: "s" extends: metric_attributes.http.client @@ -170,7 +170,7 @@ groups: - id: metric.http.client.request.body.size type: metric metric_name: http.client.request.body.size - brief: "Measures the size of HTTP request messages." + brief: "Size of HTTP client request bodies." instrument: histogram unit: "By" note: > @@ -182,7 +182,7 @@ groups: - id: metric.http.client.response.body.size type: metric metric_name: http.client.response.body.size - brief: "Measures the size of HTTP response messages." + brief: "Size of HTTP client response bodies." instrument: histogram unit: "By" note: > From 0af7e0efee513e0d0d075646301752bb9571cece Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Mon, 9 Oct 2023 07:28:44 +0200 Subject: [PATCH 070/482] [resource/host] Add semantic convention for IP addresses of a host (#203) Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/resource/host.md | 3 +++ model/resource/host.yaml | 10 ++++++++++ 3 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f766e2eb8..d823481daa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,8 @@ release. ([#178](https://github.com/open-telemetry/semantic-conventions/pull/178)) - Improve HTTP metric briefs. ([#366](https://github.com/open-telemetry/semantic-conventions/pull/366)) +- Add `host.ip` resource attribute convention. + ([#203](https://github.com/open-telemetry/semantic-conventions/pull/203)) ## v1.21.0 (2023-07-13) diff --git a/docs/resource/host.md b/docs/resource/host.md index f216a78c92..77c7a707af 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -17,9 +17,12 @@ To report host metrics, the `system.*` namespace SHOULD be used. | `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | Recommended | | `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | | `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). | `0.1` | Recommended | +| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | Opt-In | | `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | | `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | +**[1]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. + `host.arch` 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 | diff --git a/model/resource/host.yaml b/model/resource/host.yaml index 2839d8f660..141ccd76bf 100644 --- a/model/resource/host.yaml +++ b/model/resource/host.yaml @@ -70,6 +70,16 @@ groups: The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). examples: ['0.1'] + - id: ip + type: string[] + requirement_level: opt_in + brief: > + Available IP addresses of the host, excluding loopback interfaces. + note: > + IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses + MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. + examples: ["192.168.1.140", "fe80::abc2:4a28:737a:609e"] + - id: host.cpu prefix: host.cpu type: resource From 4efa49f4e87254eea9c666541897883911f1eac1 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Sun, 8 Oct 2023 22:35:41 -0700 Subject: [PATCH 071/482] Require two approvals from different companies before merging the PR (#364) Co-authored-by: Alexander Wert --- CONTRIBUTING.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3bfe45c930..782fb79ca9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -157,6 +157,23 @@ To quickly fix typos, use make misspell-correction ``` +### How to get your PR merged + +A PR (pull request) is considered to be **ready to merge** when: + +* It has received at least two approvals from the [code + owners](./.github/CODEOWNERS) (if approvals are from only one company, they + won't count). +* There is no `request changes` from the [code owners](./.github/CODEOWNERS). +* It has been at least two working days since the last modification (except for + the trivial updates, such like typo, cosmetic, rebase, etc.). This gives + people reasonable time to review. +* Trivial changes (typos, cosmetic changes, CI improvements, etc.) don't have to + wait for two days. + +Any [maintainer](./README.md#contributing) can merge the PR once it is **ready +to merge**. + ## Updating the referenced specification version 1. Open the `./internal/tools/update_specification_version.sh` script. From 559bf8bd66158dd402ae236141f139ef261b7b20 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 9 Oct 2023 15:31:35 +0200 Subject: [PATCH 072/482] Move runtime semconv to its own folder (#371) --- docs/general/metrics.md | 2 +- .../README.md} | 46 +++++++++---------- docs/{jvm => runtime}/jvm-metrics.md | 0 docs/system/README.md | 2 +- docs/system/process-metrics.md | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) rename docs/{system/runtime-environment-metrics.md => runtime/README.md} (50%) rename docs/{jvm => runtime}/jvm-metrics.md (100%) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index c4c6398fbf..564d929a6a 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -35,7 +35,7 @@ The following semantic conventions surrounding metrics are defined: * [System](/docs/system/system-metrics.md): For standard system metrics. * [Hardware](/docs/system/hardware-metrics.md): For hardware-related metrics. * [Process](/docs/system/process-metrics.md): For standard process metrics. - * [Runtime Environment](/docs/system/runtime-environment-metrics.md): For runtime environment metrics. + * [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. Apart from semantic conventions for metrics, [traces](trace.md), [logs](logs.md), and [events](events.md), OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md) with diff --git a/docs/system/runtime-environment-metrics.md b/docs/runtime/README.md similarity index 50% rename from docs/system/runtime-environment-metrics.md rename to docs/runtime/README.md index c77222063a..a60539ebaa 100644 --- a/docs/system/runtime-environment-metrics.md +++ b/docs/runtime/README.md @@ -1,28 +1,24 @@ -# Semantic Conventions for Runtime Environment Metrics +# Semantic Conventions for Runtime Environment **Status**: [Experimental][DocumentStatus] -This document includes semantic conventions for runtime environment level -metrics in OpenTelemetry. Also consider the [general -metric](/docs/general/metrics.md#general-metric-semantic-conventions), [system -metrics](system-metrics.md) and [OS Process metrics](process-metrics.md) -semantic conventions when instrumenting runtime environments. +This document defines semantic conventions for +runtime environment spans, metrics and logs. -- [Metric Instruments](#metric-instruments) - * [Runtime Environment Specific Metrics - `process.runtime.{environment}.`](#runtime-environment-specific-metrics---processruntimeenvironment) -- [Attributes](#attributes) +- [Metrics](#metrics) + * [Attributes](#attributes) -## Metric Instruments +## Metrics Runtime environments vary widely in their terminology, implementation, and relative values for a given metric. For example, Go and Python are both @@ -32,26 +28,30 @@ does not propose any standard top-level runtime metric instruments. See [OTEP 108](https://github.com/open-telemetry/oteps/pull/108/files) for additional discussion. -### Runtime Environment Specific Metrics - `process.runtime.{environment}.` - Metrics specific to a certain runtime environment should be prefixed with -`process.runtime.{environment}.` and follow the semantic conventions outlined in -[general metric semantic -conventions](/docs/general/metrics.md#general-metric-semantic-conventions). Authors of -runtime instrumentations are responsible for the choice of `{environment}` to -avoid ambiguity when interpreting a metric's name or values. +the runtime's top-level namespace `{environment}.*`, e.g., `jvm.*` and follow the +[general metric semantic convention guidelines](/docs/general/metrics.md#general-metric-semantic-conventions). + +Authors of runtime instrumentations are responsible for the choice of +`{environment}` to avoid ambiguity when interpreting a metric's name or values. For example, some programming languages have multiple runtime environments that vary significantly in their implementation, like [Python which has many implementations](https://wiki.python.org/moin/PythonImplementations). For such languages, consider using specific `{environment}` prefixes to avoid -ambiguity, like `process.runtime.cpython.` and `process.runtime.pypy.`. +ambiguity, like `cpython.*` and `pypy.*`. + +Also consider the +[general metrics](/docs/general/metrics.md#general-metric-semantic-conventions), +[system metrics](/docs/system/system-metrics.md) and +[OS process metrics](/docs/system/process-metrics.md) +semantic conventions when instrumenting runtime environments. -There are other dimensions even within a given runtime environment to -consider, for example pthreads vs green thread implementations. +- [JVM](jvm-metrics.md) -## Attributes +### Attributes -[`process.runtime`](/docs/resource/process.md#process-runtimes) resource attributes SHOULD be included on runtime metric events as appropriate. +[`process.runtime`](/docs/resource/process.md#process-runtimes) +resource attributes SHOULD be included on runtime metric events as appropriate. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/jvm/jvm-metrics.md b/docs/runtime/jvm-metrics.md similarity index 100% rename from docs/jvm/jvm-metrics.md rename to docs/runtime/jvm-metrics.md diff --git a/docs/system/README.md b/docs/system/README.md index 7e6be0f0e4..8d47ef9fcc 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -16,6 +16,6 @@ System semantic conventions are defined for the following metrics: * [System](system-metrics.md): For standard system metrics. * [Hardware](hardware-metrics.md): For hardware-related metrics. * [Process](process-metrics.md): For standard process metrics. -* [Runtime Environment](runtime-environment-metrics.md): For runtime environment metrics. +* [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index d287b94a7d..25a6eb8bc4 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -13,7 +13,7 @@ instruments not explicitly defined in this document. OS process metrics are not related to the runtime environment of the program, and should take measurements from the operating system. For runtime environment metrics see [semantic conventions for runtime environment -metrics](runtime-environment-metrics.md). +metrics](/docs/runtime/README.md#metrics). From 4040095eda0159e38edfe7084ed32d3077a6ffb0 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Mon, 9 Oct 2023 17:06:34 +0200 Subject: [PATCH 073/482] Separation of attribute definitions from attribute usages: HTTP (#208) Signed-off-by: Alexander Wert Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech --- docs/attributes-registry/README.md | 32 ++++++ docs/attributes-registry/http.md | 77 +++++++++++++ docs/database/elasticsearch.md | 2 +- docs/http/http-metrics.md | 32 +++--- docs/http/http-spans.md | 20 ++-- model/http-common.yaml | 70 +----------- model/metrics/http.yaml | 7 ++ model/{ => registry}/deprecated/http.yaml | 0 model/registry/http.yaml | 126 ++++++++++++++++++++++ model/trace/http.yaml | 66 ++---------- 10 files changed, 279 insertions(+), 153 deletions(-) create mode 100644 docs/attributes-registry/README.md create mode 100644 docs/attributes-registry/http.md rename model/{ => registry}/deprecated/http.yaml (100%) create mode 100644 model/registry/http.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md new file mode 100644 index 0000000000..a1714383f8 --- /dev/null +++ b/docs/attributes-registry/README.md @@ -0,0 +1,32 @@ + + +# Attributes Registry + +The attributes registry is the place where attributes are defined. An attribute definition covers the following properties of an attribute: + +- the `id` (the fully qualified name) of the attribute +- the `type` of the attribute +- a `brief` description of the attribute and optionally a longer `note` +- example values + +Attributes defined in the registry can be used in different semantic conventions. Attributes should be included in this registry before they are used in semantic conventions. Semantic conventions may override all the properties of an attribute except for the `id` and `type` in case it's required for a particular context. In addition, semantic conventions specify the requirement level of an attribute in the corresponding context. + +A definition of an attribute in the registry does not necessarily imply that the attribute is used in any of the semantic conventions. + +If applicable, application developers are encouraged to use existing attributes from this registry. See also [these recommendations][developers recommendations] regarding attribute selection and attribute naming for custom use cases. + +All registered attributes are listed by namespace in this registry. + +> **Warning** +> The following registry overview is a work in progress. +> +> Further attribute namespaces are currently being migrated and will appear in this registry soon. + +Currently, the following namespaces exist: + +* [HTTP](http.md) + +[developers recommendations]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/common/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md new file mode 100644 index 0000000000..7a62cc8498 --- /dev/null +++ b/docs/attributes-registry/http.md @@ -0,0 +1,77 @@ + + +# HTTP + +## HTTP Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `http.request.body.size` | 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` | +| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [1] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | +| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | +| `http.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | +| `http.response.body.size` | 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` | +| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [4] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | +| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | +| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | + +**[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[3]:** 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). + +**[4]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[5]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + +`http.request.method` 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 | +|---|---| +| `CONNECT` | CONNECT method. | +| `DELETE` | DELETE method. | +| `GET` | GET method. | +| `HEAD` | HEAD method. | +| `OPTIONS` | OPTIONS method. | +| `PATCH` | PATCH method. | +| `POST` | POST method. | +| `PUT` | PUT method. | +| `TRACE` | TRACE method. | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | + + +## Deprecated HTTP Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | +| `http.request_content_length` | int | Deprecated, use `http.request.body.size` instead. | `3495` | +| `http.response_content_length` | int | Deprecated, use `http.response.body.size` instead. | `3495` | +| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | +| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | +| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | +| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | + diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index cd0c069fd7..d62e6cd7ee 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -31,7 +31,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [3] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | | [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | -| `http.request.method` | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | | [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com` | Conditionally Required: See alternative attributes below. | | [`server.port`](../general/attributes.md) | int | Server port number [8] | `80`; `8080`; `443` | Conditionally Required: [9] | | [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e90b3d9249..78c40f8e6c 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -77,9 +77,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | @@ -178,7 +178,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.request.method` | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [2] | `example.com` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -249,9 +249,9 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | @@ -353,9 +353,9 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.route` | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | @@ -463,8 +463,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | @@ -558,8 +558,8 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | @@ -653,8 +653,8 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| `http.response.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.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 0548eaf01e..6a24aaaa93 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -116,13 +116,13 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | -| `http.request.body.size` | 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.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | -| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | -| `http.response.body.size` | 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.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | -| `http.response.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.request.body.size`](../attributes-registry/http.md) | 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.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | +| [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Conditionally Required: [9] | @@ -186,7 +186,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: -* `http.request.method` +* [`http.request.method`](../attributes-registry/http.md) `error.type` 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. @@ -243,7 +243,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `http.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | +| [`http.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | | [`server.address`](../general/attributes.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 | | [`server.port`](../general/attributes.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] | | [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | Recommended: If different than `server.address`. | @@ -379,7 +379,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | | [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | | [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | -| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Recommended: [8] | | [`server.socket.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. [9] | `10.5.3.2` | Opt-In | diff --git a/model/http-common.yaml b/model/http-common.yaml index 7d062bd584..7cf4614ac8 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -2,66 +2,12 @@ groups: - id: attributes.http.common type: attribute_group brief: "Describes HTTP attributes." - prefix: http attributes: - - id: request.method - type: - allow_custom_values: true - members: - - id: connect - value: "CONNECT" - brief: 'CONNECT method.' - - id: delete - value: "DELETE" - brief: 'DELETE method.' - - id: get - value: "GET" - brief: 'GET method.' - - id: head - value: "HEAD" - brief: 'HEAD method.' - - id: options - value: "OPTIONS" - brief: 'OPTIONS method.' - - id: patch - value: "PATCH" - brief: 'PATCH method.' - - id: post - value: "POST" - brief: 'POST method.' - - id: put - value: "PUT" - brief: 'PUT method.' - - id: trace - value: "TRACE" - brief: 'TRACE method.' - - id: other - value: "_OTHER" - brief: 'Any HTTP method that the instrumentation has no prior knowledge of.' + - ref: http.request.method requirement_level: required - brief: 'HTTP request method.' - examples: ["GET", "POST", "HEAD"] - note: | - HTTP request method value SHOULD be "known" to the instrumentation. - By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) - and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - - If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - - If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override - the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named - OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods - (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - - HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. - Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. - Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - - id: response.status_code - type: int + - ref: http.response.status_code 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] - ref: error.type requirement_level: conditionally_required: If request has ended with an error. @@ -90,7 +36,6 @@ groups: examples: ['1.0', '1.1', '2', '3'] - id: attributes.http.client - prefix: http type: attribute_group brief: 'HTTP Client attributes' attributes: @@ -116,21 +61,12 @@ groups: URI port identifier, otherwise it MUST match `Host` header port identifier. - id: attributes.http.server - prefix: http type: attribute_group brief: 'HTTP Server attributes' attributes: - - id: route - type: string + - ref: http.route 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](/docs/http/http-spans.md#http-server-definitions) if there is one. - ref: server.address brief: > Name of the local HTTP server that received the request. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 89c54cb2c6..4b77963310 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -52,7 +52,10 @@ groups: If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: http.request.method + requirement_level: required - ref: http.response.status_code + requirement_level: + conditionally_required: If and only if one was received/sent. - ref: network.protocol.name - ref: network.protocol.version @@ -63,7 +66,10 @@ groups: attributes: # todo (lmolkova) build tools don't populate grandparent attributes - ref: http.request.method + requirement_level: required - ref: http.response.status_code + requirement_level: + conditionally_required: If and only if one was received/sent. - ref: network.protocol.name - ref: network.protocol.version - ref: error.type @@ -105,6 +111,7 @@ groups: unit: "{request}" attributes: - ref: http.request.method + requirement_level: required - ref: url.scheme requirement_level: required examples: ["http", "https"] diff --git a/model/deprecated/http.yaml b/model/registry/deprecated/http.yaml similarity index 100% rename from model/deprecated/http.yaml rename to model/registry/deprecated/http.yaml diff --git a/model/registry/http.yaml b/model/registry/http.yaml new file mode 100644 index 0000000000..1d6f0192fa --- /dev/null +++ b/model/registry/http.yaml @@ -0,0 +1,126 @@ +groups: + - id: registry.http + prefix: http + type: attribute_group + brief: 'This document defines semantic convention attributes in the HTTP namespace.' + attributes: + - id: request.body.size + type: int + brief: > + 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. + examples: 3495 + - id: request.header + type: template[string[]] + brief: > + HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + note: > + Instrumentations SHOULD require an explicit configuration of which headers are to be captured. + Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + + The `User-Agent` header is already captured in the `user_agent.original` attribute. + Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + + The attribute value MUST consist of either multiple header values as an array of strings + or a single-item array containing a possibly comma-concatenated string, depending on the way + the HTTP library provides access to headers. + examples: ['http.request.header.content_type=["application/json"]', 'http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]'] + - id: request.method + type: + allow_custom_values: true + members: + - id: connect + value: "CONNECT" + brief: 'CONNECT method.' + - id: delete + value: "DELETE" + brief: 'DELETE method.' + - id: get + value: "GET" + brief: 'GET method.' + - id: head + value: "HEAD" + brief: 'HEAD method.' + - id: options + value: "OPTIONS" + brief: 'OPTIONS method.' + - id: patch + value: "PATCH" + brief: 'PATCH method.' + - id: post + value: "POST" + brief: 'POST method.' + - id: put + value: "PUT" + brief: 'PUT method.' + - id: trace + value: "TRACE" + brief: 'TRACE method.' + - id: other + value: "_OTHER" + brief: 'Any HTTP method that the instrumentation has no prior knowledge of.' + brief: 'HTTP request method.' + examples: ["GET", "POST", "HEAD"] + note: | + HTTP request method value SHOULD be "known" to the instrumentation. + By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + + If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + + If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override + the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named + OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods + (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + + HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. + Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. + Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + - id: request.method_original + type: string + brief: Original HTTP method sent by the client in the request line. + examples: ["GeT", "ACL", "foo"] + - 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). + examples: 3 + - id: response.body.size + type: int + brief: > + 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. + examples: 3495 + - id: response.header + type: template[string[]] + brief: > + HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + note: > + Instrumentations SHOULD require an explicit configuration of which headers are to be captured. + Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + + Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + + The attribute value MUST consist of either multiple header values as an array of strings + or a single-item array containing a possibly comma-concatenated string, depending on the way + the HTTP library provides access to headers. + examples: ['http.response.header.content_type=["application/json"]', 'http.response.header.my_custom_header=["abc", "def"]'] + - id: response.status_code + type: int + brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' + examples: [200] + - id: route + type: string + 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](/docs/http/http-spans.md#http-server-definitions) if there is one. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index ae362604ca..935827cdf9 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -1,6 +1,5 @@ groups: - id: trace.http.common - prefix: http extends: attributes.http.common type: attribute_group brief: 'This document defines semantic conventions for HTTP client and server Spans.' @@ -8,59 +7,18 @@ groups: These conventions can be used for http and https schemes and various HTTP versions like 1.1, 2 and SPDY. attributes: - - id: request.method_original - type: string + - ref: http.request.method_original requirement_level: conditionally_required: If and only if it's different than `http.request.method`. - brief: Original HTTP method sent by the client in the request line. - examples: ["GeT", "ACL", "foo"] - - id: request.body.size - type: int - brief: > - 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. - examples: 3495 - - id: response.body.size - type: int - brief: > - 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. - examples: 3495 - - id: request.header - type: template[string[]] + - ref: http.request.body.size + - ref: http.request.header requirement_level: opt_in - brief: > - HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. - note: > - Instrumentations SHOULD require an explicit configuration of which headers are to be captured. - Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - - The `User-Agent` header is already captured in the `user_agent.original` attribute. - Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - - The attribute value MUST consist of either multiple header values as an array of strings - or a single-item array containing a possibly comma-concatenated string, depending on the way - the HTTP library provides access to headers. - examples: ['http.request.header.content_type=["application/json"]', 'http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]'] - - id: response.header - type: template[string[]] + - ref: http.response.body.size + - ref: http.response.header requirement_level: opt_in - brief: > - HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. - note: > - Instrumentations SHOULD require an explicit configuration of which headers are to be captured. - Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - - Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - - The attribute value MUST consist of either multiple header values as an array of strings - or a single-item array containing a possibly comma-concatenated string, depending on the way - the HTTP library provides access to headers. - examples: ['http.response.header.content_type=["application/json"]', 'http.response.header.my_custom_header=["abc", "def"]'] - ref: http.request.method sampling_relevant: true + requirement_level: required - ref: network.transport requirement_level: conditionally_required: If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). @@ -68,23 +26,14 @@ groups: - ref: user_agent.original - id: trace.http.client - prefix: http type: span extends: attributes.http.client span_kind: client brief: 'Semantic Convention for HTTP Client' attributes: - - 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). + - ref: http.resend_count requirement_level: recommended: if and only if request was retried. - examples: 3 - ref: server.address sampling_relevant: true requirement_level: required @@ -117,7 +66,6 @@ groups: - id: trace.http.server - prefix: http type: span extends: attributes.http.server span_kind: server From 0b5a2f3354a17ac0a625716d9ad27844513f4221 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 10 Oct 2023 08:13:16 -0700 Subject: [PATCH 074/482] Rename/replace `(client|server).socket.(address|port)` attributes with `network.(peer|local).(address|port)`. (#342) Co-authored-by: Liudmila Molkova --- CHANGELOG.md | 3 + docs/database/database-spans.md | 19 +--- docs/database/elasticsearch.md | 4 +- docs/general/attributes.md | 140 ++++++++++++------------------ docs/general/forward-proxy.png | Bin 0 -> 253872 bytes docs/general/reverse-proxy.png | Bin 0 -> 270548 bytes docs/general/simple.png | Bin 0 -> 208169 bytes docs/http/http-metrics.md | 14 +-- docs/http/http-spans.md | 61 +++++-------- docs/messaging/messaging-spans.md | 17 +--- docs/rpc/rpc-metrics.md | 4 +- docs/rpc/rpc-spans.md | 46 +++------- model/client.yaml | 22 +---- model/deprecated/network.yaml | 11 ++- model/destination.yaml | 12 ++- model/network.yaml | 16 ++++ model/server.yaml | 31 +------ model/source.yaml | 12 ++- model/trace/database.yaml | 17 ++-- model/trace/http.yaml | 17 ++-- model/trace/messaging.yaml | 12 +-- model/trace/rpc.yaml | 23 +++-- 22 files changed, 174 insertions(+), 307 deletions(-) create mode 100644 docs/general/forward-proxy.png create mode 100644 docs/general/reverse-proxy.png create mode 100644 docs/general/simple.png diff --git a/CHANGELOG.md b/CHANGELOG.md index d823481daa..3563762c3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -136,6 +136,9 @@ release. ([#366](https://github.com/open-telemetry/semantic-conventions/pull/366)) - Add `host.ip` resource attribute convention. ([#203](https://github.com/open-telemetry/semantic-conventions/pull/203)) +- BREAKING: Rename/replace `(client|server).socket.(address|port)` attributes + with `network.(peer|local).(address|port)`. + ([#342](https://github.com/open-telemetry/semantic-conventions/pull/342)) ## v1.21.0 (2023-07-13) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 05314a27fd..a767dce76a 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,12 +67,12 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com` | Conditionally Required: See alternative attributes below. | -| [`server.port`](../general/attributes.md) | int | Server port number [4] | `80`; `8080`; `443` | Conditionally Required: [5] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [6] | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [7] | `16456` | Recommended: If different than `server.port`. | +| [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../general/attributes.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | **[1]:** The value SHOULD be normalized to lowercase. @@ -89,17 +89,6 @@ the server address behind any intermediaries (e.g. proxies) if it's available. **[5]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[6]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. - -**Additional attribute requirements:** At least one of the following sets of attributes is required: - -* [`server.address`](../general/attributes.md) -* [`server.socket.address`](../general/attributes.md) - `db.system` 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 | diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index d62e6cd7ee..9bbddc5663 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -32,8 +32,8 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com` | Conditionally Required: See alternative attributes below. | -| [`server.port`](../general/attributes.md) | int | Server port number [8] | `80`; `8080`; `443` | Conditionally Required: [9] | +| [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../general/attributes.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | | [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 6111990606..542a74878d 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -19,13 +19,16 @@ Particular operations may refer to or require some of these attributes. * [Address and port attributes](#address-and-port-attributes) * [Server attributes](#server-attributes) + [`server.address`](#serveraddress) - + [`server.socket.*` attributes](#serversocket-attributes) * [Client attributes](#client-attributes) - + [Connecting through intermediary](#connecting-through-intermediary) * [Source and destination attributes](#source-and-destination-attributes) + [Source](#source) + [Destination](#destination) * [Other network attributes](#other-network-attributes) + + [`network.peer.*` and `network.local.*` attributes](#networkpeer-and-networklocal-attributes) + - [Client/server examples using `network.peer.*`](#clientserver-examples-using--networkpeer) + * [Simple client/server example](#simple-clientserver-example) + * [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) + * [Client/server example with forward proxy](#clientserver-example-with-forward-proxy) + [Network connection and carrier attributes](#network-connection-and-carrier-attributes) - [General remote service attributes](#general-remote-service-attributes) - [General identity attributes](#general-identity-attributes) @@ -66,31 +69,18 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `server.address` | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `example.com` | Recommended | -| `server.port` | int | Server port number [2] | `80`; `8080`; `443` | Recommended | -| `server.socket.address` | string | Server address of the socket connection - IP address or Unix domain socket name. [3] | `10.5.3.2` | Recommended: If different than `server.address`. | -| `server.socket.domain` | string | Immediate server peer's domain name if available without reverse DNS lookup [4] | `proxy.example.com` | Recommended: If different than `server.address`. | -| `server.socket.port` | int | Server port number of the socket connection. [5] | `16456` | Recommended: If different than `server.port`. | +| `server.address` | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | Recommended | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. **[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. - -**[3]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[4]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. - -**[5]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. `server.address` and `server.port` represent logical server name and port. Semantic conventions that refer to these attributes SHOULD specify what these attributes mean in their context. -Semantic conventions and instrumentations that populate both logical (`server.address` and `server.port`) and socket-level (`server.socket.*`) attributes SHOULD set socket-level attributes only when they don't match logical ones. For example, when direct connection to the remote destination is established and `server.address` is populated, `server.socket.domain` SHOULD NOT be set. Check out [Connecting through intermediary](#connecting-through-intermediary) for more information. - #### `server.address` For IP-based communication, the name should be a DNS host name of the service. On client side it matches remote service name, on server side, it represents local service name as seen externally on clients. @@ -107,28 +97,6 @@ the name should explicitly be set to the empty string to distinguish it from the For Unix domain socket, `server.address` attribute represents remote endpoint address on the client side and local endpoint address on the server side. -#### `server.socket.*` attributes - -_Note: this section applies to socket connections visible to instrumentations. Instrumentations have limited knowledge about intermediaries communications goes through such as [transparent proxies](https://www.rfc-editor.org/rfc/rfc3040.html#section-2.5) or VPN servers. Higher-level instrumentations such as HTTP don't always have access to the socket-level information and may not be able to populate socket-level attributes._ - -Socket-level attributes identify peer and host that are directly connected to each other. Since instrumentations may have limited knowledge on network information, instrumentations SHOULD populate such attributes to the best of their knowledge when populate them at all. - -_Note: Specific structures and methods to obtain socket-level attributes are mentioned here only as examples. Instrumentations would usually use Socket API provided by their environment or sockets implementations._ - -For IP-based communication, `server.socket.domain` represents either fully qualified domain name of immediate peer and `server.socket.address` to the IP address (or one specific to network family). - -`server.socket.domain`, `server.socket.address`, and `server.socket.port` describe server side of socket communication. For example, when connecting using `connect(2)` -on [Linux](https://man7.org/linux/man-pages/man2/connect.2.html) or [Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-connect) -with `AF_INET` address family, they represent `sin_addr` and `sin_port` fields of [`sockaddr_in`](https://man7.org/linux/man-pages/man7/ip.7.html) structure. - -On client side, address and port can be obtained by calling `getpeername` method on [Linux](https://man7.org/linux/man-pages/man2/getpeername.2.html) or -[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-getpeername). - -On server side address and port can be obtained by calling `getsockname` method on [Linux](https://man7.org/linux/man-pages/man2/getsockname.2.html) or -[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-getsockname). - -`server.socket.port` SHOULD only be populated for families that have notion of port. - ### Client attributes > **Warning** @@ -139,53 +107,14 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| `client.address` | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `client.port` | int | Client port number. [2] | `65123` | Recommended | -| `client.socket.address` | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| `client.socket.port` | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. **[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. - -**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. -When observed from the client side, this SHOULD represent the physical client address. - -**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. -When observed from the client side, this SHOULD represent the physical client port. -`client.socket.address` and `client.socket.port` represent physical client name and port. - -For IP-based communication, the `client.socket.address` should be a IP address, Unix domain name, or another address specific to network type. - -On server side, `client.socket.address` identifies the direct peer endpoint socket address. For example, when using `bind(2)` -on [Linux](https://man7.org/linux/man-pages/man2/bind.2.html) or [Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-bind) -with `AF_INET` address family, represent `sin_addr` and `sin_port` fields of `sockaddr_in` structure. - -On client side it represents local socket address and port can be obtained by calling `getsockname` method on [Linux](https://man7.org/linux/man-pages/man2/getsockname.2.html), -[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-getsockname). - -#### Connecting through intermediary - -When connecting to the remote destination through an intermediary (e.g. proxy), client instrumentations SHOULD set `server.address` and `server.port` to logical remote destination address and `server.socket.name`, `server.socket.address` and `server.socket.port` to the socket peer connection is established with - the intermediary. - -`server.socket.domain` SHOULD be set to the DNS name used to resolve `server.socket.address` if it's readily available. Instrumentations -SHOULD NOT do DNS lookups to obtain `server.socket.address`. If peer information available to instrumentation -can represent DNS name or IP address, instrumentation SHOULD NOT attempt to parse it and SHOULD only set `server.socket.domain`. - -_Note: Telemetry consumers can obtain IP address from telemetry item by first checking `server.socket.address` and if not present, falling back to `server.socket.domain`._ - -For example, [URL Host component](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2) can contain IP address or DNS name and -instrumentations that don't have access to socket-level communication can only populate `server.socket.domain`. -Instrumentations that have access to socket connection, may be able to populate valid `server.socket.address` instead of or -in addition to DNS name. - -Server instrumentations that leverage `client.address` and `client.port` attributes SHOULD set them to originating client address and port behind all proxies if this information is available. -The `client.socket.address` and `client.socket.port` attributes then SHOULD contain immediate client peer address and port. - -If only immediate peer information is available, it should be set on `client.address` and `client.port` and `client.socket.*` attributes SHOULD NOT be set. - ### Source and destination attributes These attributes may be used to describe the sender and receiver of a network exchange/packet. These should be used @@ -200,11 +129,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `source.address` | string | Source address, for example IP address or Unix socket name. | `10.5.3.2` | Recommended | -| `source.domain` | string | The domain name of the source system. [1] | `foo.example.com` | Recommended | +| `source.address` | string | Source address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `source.port` | int | Source port number | `3389`; `2888` | Recommended | -**[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. +**[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries (e.g. proxies) if it's available. #### Destination @@ -214,11 +142,10 @@ Destination fields capture details about the receiver of a network exchange/pack | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `destination.address` | string | Destination address, for example IP address or UNIX socket name. | `10.5.3.2` | Recommended | -| `destination.domain` | string | The domain name of the destination system. [1] | `foo.example.com` | Recommended | +| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `destination.port` | int | Destination port number | `3389`; `2888` | Recommended | -**[1]:** This value may be a host name, a fully qualified domain name, or another host naming format. +**[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries (e.g. proxies) if it's available. @@ -233,6 +160,10 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `network.local.port` | int | Local port number of the network connection. | `65123` | Recommended | +| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `network.peer.port` | int | Peer port number of the network connection. | `65123` | Recommended | | `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | | `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | | `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | @@ -267,6 +198,45 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `ipv6` | IPv6 | +#### `network.peer.*` and `network.local.*` attributes + +These attributes identify network peers that are directly connected to each other. + +`network.peer.address` and `network.local.address` should be IP addresses, Unix domain socket names, or other addresses specific to network type. + +_Note: Specific structures and methods to obtain socket-level attributes are mentioned here only as examples. Instrumentations would usually use Socket API provided by their environment or sockets implementations._ + +When connecting using `connect(2)` ([Linux or other POSIX systems](https://man7.org/linux/man-pages/man2/connect.2.html) / +[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-connect)) +or `bind(2)`([Linux or other POSIX systems](https://man7.org/linux/man-pages/man2/bind.2.html) / +[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-bind)) +with `AF_INET` address family, `network.peer.address` and `network.peer.port` represent `sin_addr` and `sin_port` fields +of `sockaddr_in` structure. + +`network.peer.address` and `network.peer.port` can be obtained by calling `getpeername` method +([Linux or other POSIX systems](https://man7.org/linux/man-pages/man2/getpeername.2.html) / +[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-getpeername)). + +`network.local.address` and `network.local.port` can be obtained by calling `getsockname` method +([Linux or other POSIX systems](https://man7.org/linux/man-pages/man2/getsockname.2.html) / +[Windows](https://docs.microsoft.com/windows/win32/api/winsock2/nf-winsock2-getsockname)). + +##### Client/server examples using `network.peer.*` + +Note that `network.local.*` attributes are not included in these examples since they are typically Opt-In. + +###### Simple client/server example + +![simple.png](simple.png) + +###### Client/server example with reverse proxy + +![reverse-proxy.png](reverse-proxy.png) + +###### Client/server example with forward proxy + +![forward-proxy.png](forward-proxy.png) + #### Network connection and carrier attributes diff --git a/docs/general/forward-proxy.png b/docs/general/forward-proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..0badc4624c97c1b91fcb31ef63a895886126d279 GIT binary patch literal 253872 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%0AH@_(2zJJa0YAF%7d2}|saXxV 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ℑ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

54_H=JzEQ}0X+o7|W8)-|*B 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 T5!l;%kblaG*A?>RjPL&!j|0IJ literal 0 HcmV?d00001 diff --git a/docs/general/simple.png b/docs/general/simple.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c48b0748f1c0a687e8f7e42d692955f6d93096 GIT binary patch literal 208169 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%0A!$a&S{E;TY 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 78c40f8e6c..0227a4d713 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -82,7 +82,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -179,7 +179,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [2] | `example.com` | Opt-In | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -254,7 +254,7 @@ This metric is optional. | [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -358,7 +358,7 @@ This metric is optional. | [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Opt-In | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -467,7 +467,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -562,7 +562,7 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -657,7 +657,7 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com` | Required | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 6a24aaaa93..9ed59f4f33 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -244,12 +244,11 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | -| [`server.address`](../general/attributes.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 | +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.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] | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [5] | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [6] | `proxy.example.com` | Recommended: If different than `server.address`. | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [7] | `16456` | Recommended: If different than `server.port`. | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [8] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | **[1]:** 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). @@ -266,15 +265,7 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. **[4]:** If not default (`80` for `http` scheme, `443` for `https`). -**[5]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[6]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. - -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. - -**[8]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. @@ -377,31 +368,25 @@ For an HTTP server span, `SpanKind` MUST be `Server`. |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | | [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | -| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | -| [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Recommended: [8] | -| [`server.socket.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. [9] | `10.5.3.2` | Opt-In | -| [`server.socket.port`](../general/attributes.md) | int | Local socket port. Useful in case of a multi-port host. [10] | `16456` | Opt-In | -| [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [11] | `/search` | Required | -| [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [12] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`network.local.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`network.local.port`](../general/attributes.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Recommended: [6] | +| [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | +| [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. **[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. -**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. -When observed from the client side, this SHOULD represent the physical client address. - -**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. -When observed from the client side, this SHOULD represent the physical client port. - -**[5]:** 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. +**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[6]:** Determined by using the first of the following that applies +**[4]:** Determined by using the first of the following that applies - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only include host identifier. @@ -411,24 +396,18 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. -**[7]:** Determined by using the first of the following that applies +**[5]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 -**[8]:** If not default (`80` for `http` scheme, `443` for `https`). - -**[9]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[10]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. +**[6]:** If not default (`80` for `http` scheme, `443` for `https`). -**[11]:** When missing, the value is assumed to be `/` +**[7]:** When missing, the value is assumed to be `/` -**[12]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[8]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 8faceefe39..15fef2213e 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -229,14 +229,13 @@ The following operations related to messages are defined for these semantic conv | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | | `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [15] | `publish` | Required | | `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | | [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [20] | `example.com` | Conditionally Required: If available. | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [21] | `10.5.3.2` | Recommended: If different than `server.address`. | -| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [22] | `proxy.example.com` | Recommended: [23] | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [24] | `16456` | Recommended: If different than `server.port`. | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -285,16 +284,6 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[20]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. -**[21]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[22]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. - -**[23]:** If different than `server.address` and if `server.socket.address` is set. - -**[24]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. - `messaging.operation` 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 | diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index ac07909f79..b7b51580ee 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -225,8 +225,8 @@ measurements. | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [5] | `example.com` | Recommended | -| [`server.port`](../general/attributes.md) | int | Server port number [6] | `80`; `8080`; `443` | Recommended | +| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 98d753e20f..e5d8fbb1fb 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -90,10 +90,8 @@ Examples of span names: | `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com` | Required | -| [`server.port`](../general/attributes.md) | int | Server port number [6] | `80`; `8080`; `443` | Conditionally Required: See below | -| [`server.socket.address`](../general/attributes.md) | string | Server address of the socket connection - IP address or Unix domain socket name. [7] | `10.5.3.2` | See below | -| [`server.socket.port`](../general/attributes.md) | int | Server port number of the socket connection. [8] | `16456` | Recommended: [9] | +| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: See below | **[1]:** The value SHOULD be normalized to lowercase. @@ -111,19 +109,6 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. -**[7]:** When observed from the client side, this SHOULD represent the immediate server peer address. -When observed from the server side, this SHOULD represent the physical server address. - -**[8]:** When observed from the client side, this SHOULD represent the immediate server peer port. -When observed from the server side, this SHOULD represent the physical server port. - -**[9]:** If different than `server.port` and if `server.socket.address` is set. - -**Additional attribute requirements:** At least one of the following sets of attributes is required: - -* [`server.socket.address`](../general/attributes.md) -* [`server.address`](../general/attributes.md) - `rpc.system` 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 | @@ -157,11 +142,8 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`server.socket.domain`](../general/attributes.md) | string | Immediate server peer's domain name if available without reverse DNS lookup [1] | `proxy.example.com` | Recommended: [2] | - -**[1]:** Typically observed from the client side, and represents a proxy or other intermediary domain name. - -**[2]:** If different than `server.address` and if `server.socket.address` is set. +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | ### Server attributes @@ -169,30 +151,24 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `/tmp/my.sock`; `10.1.2.80` | Recommended | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | -| [`client.socket.address`](../general/attributes.md) | string | Client address of the socket connection - IP address or Unix domain socket name. [3] | `/tmp/my.sock`; `127.0.0.1` | Recommended: If different than `client.address`. | -| [`client.socket.port`](../general/attributes.md) | int | Client port number of the socket connection. [4] | `35555` | Recommended: If different than `client.port`. | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [5] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [6] | `ipv4`; `ipv6` | Recommended | +| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `client.address`. | +| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. **[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. -**[3]:** When observed from the server side, this SHOULD represent the immediate client peer address. -When observed from the client side, this SHOULD represent the physical client address. - -**[4]:** When observed from the server side, this SHOULD represent the immediate client peer port. -When observed from the client side, this SHOULD represent the physical client port. - -**[5]:** The value SHOULD be normalized to lowercase. +**[3]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport, for example different processes could be listening on TCP port 12345 and UDP port 12345. -**[6]:** The value SHOULD be normalized to lowercase. +**[4]:** The value SHOULD be normalized to lowercase. ### Events diff --git a/model/client.yaml b/model/client.yaml index d1d9502183..71d285f7dc 100644 --- a/model/client.yaml +++ b/model/client.yaml @@ -16,7 +16,7 @@ groups: note: > When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. - examples: ['/tmp/my.sock', '10.1.2.80'] + examples: ['client.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int brief: Client port number. @@ -24,23 +24,3 @@ groups: note: > When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. - - id: socket.address - type: string - brief: Client address of the socket connection - IP address or Unix domain socket name. - note: > - When observed from the server side, this SHOULD represent the immediate client peer address. - - When observed from the client side, this SHOULD represent the physical client address. - examples: ['/tmp/my.sock', '127.0.0.1'] - requirement_level: - recommended: If different than `client.address`. - - id: socket.port - type: int - brief: Client port number of the socket connection. - note: > - When observed from the server side, this SHOULD represent the immediate client peer port. - - When observed from the client side, this SHOULD represent the physical client port. - examples: [35555] - requirement_level: - recommended: If different than `client.port`. diff --git a/model/deprecated/network.yaml b/model/deprecated/network.yaml index 17b75b90e3..19e9c22667 100644 --- a/model/deprecated/network.yaml +++ b/model/deprecated/network.yaml @@ -8,19 +8,18 @@ groups: - id: sock.peer.name type: string stability: deprecated - brief: Deprecated, use `server.socket.domain` on client spans. + brief: Deprecated, no replacement at this time. examples: ['/var/my.sock'] - id: sock.peer.addr type: string stability: deprecated - brief: > - Deprecated, use `server.socket.address` on client spans and `client.socket.address` on server spans. + brief: Deprecated, use `network.peer.address`. examples: ['192.168.0.1'] - id: sock.peer.port type: int stability: deprecated examples: [65531] - brief: Deprecated, use `server.socket.port` on client spans and `client.socket.port` on server spans. + brief: Deprecated, use `network.peer.port`. - id: peer.name type: string stability: deprecated @@ -44,12 +43,12 @@ groups: - id: sock.host.addr type: string stability: deprecated - brief: Deprecated, use `server.socket.address`. + brief: Deprecated, use `network.local.address`. examples: ['/var/my.sock'] - id: sock.host.port type: int stability: deprecated - brief: Deprecated, use `server.socket.port`. + brief: Deprecated, use `network.local.port`. examples: [8080] - id: transport type: diff --git a/model/destination.yaml b/model/destination.yaml index a2fd8fd65f..bad57d5a22 100644 --- a/model/destination.yaml +++ b/model/destination.yaml @@ -9,15 +9,13 @@ groups: This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API does not expose a clear notion of client and server. attributes: - - id: domain - type: string - brief: The domain name of the destination system. - examples: ['foo.example.com'] - note: This value may be a host name, a fully qualified domain name, or another host naming format. - id: address type: string - brief: 'Destination address, for example IP address or UNIX socket name.' - examples: ['10.5.3.2'] + brief: Destination address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + note: > + When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent + the destination address behind any intermediaries (e.g. proxies) if it's available. + examples: ['destination.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int brief: 'Destination port number' diff --git a/model/network.yaml b/model/network.yaml index 2b969ea36e..2652a2fd1b 100644 --- a/model/network.yaml +++ b/model/network.yaml @@ -57,6 +57,22 @@ groups: `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + - id: peer.address + type: string + brief: Peer address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: peer.port + type: int + brief: Peer port number of the network connection. + examples: [65123] + - id: local.address + type: string + brief: Local address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: local.port + type: int + brief: Local port number of the network connection. + examples: [65123] - id: network-connection-and-carrier prefix: network diff --git a/model/server.yaml b/model/server.yaml index aed9184905..8f10470221 100644 --- a/model/server.yaml +++ b/model/server.yaml @@ -16,38 +16,11 @@ groups: note: | When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries (e.g. proxies) if it's available. - examples: ['example.com'] + examples: ['example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int - brief: Server port number + brief: Server port number. note: > When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. examples: [80, 8080, 443] - - id: socket.domain - type: string - brief: Immediate server peer's domain name if available without reverse DNS lookup - examples: ['proxy.example.com'] - note: Typically observed from the client side, and represents a proxy or other intermediary domain name. - requirement_level: - recommended: If different than `server.address`. - - id: socket.address - type: string - brief: Server address of the socket connection - IP address or Unix domain socket name. - note: > - When observed from the client side, this SHOULD represent the immediate server peer address. - - When observed from the server side, this SHOULD represent the physical server address. - examples: ['10.5.3.2'] - requirement_level: - recommended: If different than `server.address`. - - id: socket.port - type: int - brief: Server port number of the socket connection. - note: > - When observed from the client side, this SHOULD represent the immediate server peer port. - - When observed from the server side, this SHOULD represent the physical server port. - examples: [16456] - requirement_level: - recommended: If different than `server.port`. diff --git a/model/source.yaml b/model/source.yaml index 63fc1bd4b6..9c0aa30a28 100644 --- a/model/source.yaml +++ b/model/source.yaml @@ -9,15 +9,13 @@ groups: This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API does not expose a clear notion of client and server. attributes: - - id: domain - type: string - brief: The domain name of the source system. - examples: ['foo.example.com'] - note: This value may be a host name, a fully qualified domain name, or another host naming format. - id: address type: string - brief: 'Source address, for example IP address or Unix socket name.' - examples: ['10.5.3.2'] + brief: Source address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + note: > + When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent + the source address behind any intermediaries (e.g. proxies) if it's available. + examples: ['source.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int brief: 'Source port number' diff --git a/model/trace/database.yaml b/model/trace/database.yaml index aeb68fc6af..e7e1659505 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -230,29 +230,24 @@ groups: examples: ['findAndModify', 'HMSET', 'SELECT'] - ref: server.address tag: connection-level - requirement_level: - conditionally_required: See alternative attributes below. brief: > Name of the database host. - ref: server.port tag: connection-level requirement_level: conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - - ref: server.socket.address + - ref: network.peer.address + requirement_level: + recommended: If different than `server.address`. tag: connection-level - - ref: server.socket.port + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. tag: connection-level - ref: network.transport tag: connection-level - ref: network.type tag: connection-level - - ref: server.socket.domain - requirement_level: - recommended: If different than `server.address` and if `server.socket.address` is set. - constraints: - - any_of: - - 'server.address' - - 'server.socket.address' - id: db.mssql prefix: db.mssql diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 935827cdf9..dd224b7bb5 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -57,9 +57,12 @@ groups: note: > When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. - - ref: server.socket.domain - - ref: server.socket.address - - ref: server.socket.port + - ref: network.peer.address + requirement_level: + recommended: If different than `server.address`. + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. - ref: url.full sampling_relevant: true requirement_level: required @@ -99,10 +102,10 @@ groups: - 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: server.socket.address + - ref: network.local.address requirement_level: opt_in brief: Local socket address. Useful in case of a multi-IP host. - - ref: server.socket.port + - ref: network.local.port requirement_level: opt_in brief: Local socket port. Useful in case of a multi-port host. - ref: client.address @@ -117,8 +120,8 @@ groups: The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. - - ref: client.socket.address - - ref: client.socket.port + - ref: network.peer.address + - ref: network.peer.port - ref: url.path requirement_level: required sampling_relevant: true diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 19c8f375ed..3313d95f55 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -173,18 +173,18 @@ groups: This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. requirement_level: conditionally_required: If available. - - ref: server.socket.address + - ref: network.peer.address + requirement_level: + recommended: If different than `server.address`. tag: connection-level - - ref: server.socket.port + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. tag: connection-level - ref: network.transport tag: connection-level - ref: network.type tag: connection-level - - ref: server.socket.domain - tag: connection-level - requirement_level: - recommended: If different than `server.address` and if `server.socket.address` is set. - ref: network.protocol.name examples: ['amqp', 'mqtt'] - ref: network.protocol.version diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 38a25016e0..8cee3efc39 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -49,10 +49,6 @@ groups: (e.g., method actually executing the call on the server side, RPC client stub method on the client side). examples: "exampleMethod" - - ref: server.socket.address - - ref: server.socket.port - requirement_level: - recommended: If different than `server.port` and if `server.socket.address` is set. - ref: network.transport - ref: network.type - ref: server.address @@ -66,19 +62,18 @@ groups: - ref: server.port requirement_level: conditionally_required: See below - constraints: - - any_of: - - server.socket.address - - server.address - id: rpc.client type: span brief: 'This document defines semantic conventions for remote procedure call client spans.' extends: rpc attributes: - - ref: server.socket.domain + - ref: network.peer.address + requirement_level: + recommended: If different than `server.address`. + - ref: network.peer.port requirement_level: - recommended: If different than `server.address` and if `server.socket.address` is set. + recommended: If `network.peer.address` is set. - id: rpc.server prefix: rpc @@ -89,8 +84,12 @@ groups: attributes: - ref: client.address - ref: client.port - - ref: client.socket.address - - ref: client.socket.port + - ref: network.peer.address + requirement_level: + recommended: If different than `client.address`. + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. - ref: network.transport - ref: network.type From 7311eb1d5848addd5ebf7f0eb1a32c6b14f6a4f1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 11 Oct 2023 04:17:31 -0700 Subject: [PATCH 075/482] Fix schema transformation added in #229 (#375) --- schema-next.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schema-next.yaml b/schema-next.yaml index 066a9ce9ef..4e276d419a 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,12 +2,14 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/1.21.0 versions: next: - metrics: + spans: changes: # https://github.com/open-telemetry/semantic-conventions/pull/229 - rename_attributes: attribute_map: messaging.message.payload_size_bytes: messaging.message.body.size + metrics: + changes: # https://github.com/open-telemetry/semantic-conventions/pull/224 - rename_metrics: http.client.duration: http.client.request.duration From b127e121b9b458e83a0fee8a32f7eb6721912951 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 11 Oct 2023 09:29:44 -0400 Subject: [PATCH 076/482] Bump to latest specification version. (#379) --- CONTRIBUTING.md | 3 ++- README.md | 2 +- docs/attributes-registry/README.md | 2 +- docs/cloud-providers/README.md | 2 +- docs/cloud-providers/aws-sdk.md | 2 +- docs/cloudevents/README.md | 2 +- docs/cloudevents/cloudevents-spans.md | 2 +- docs/database/README.md | 2 +- docs/database/cassandra.md | 2 +- docs/database/cosmosdb.md | 2 +- docs/database/couchdb.md | 2 +- docs/database/database-metrics.md | 6 +++--- docs/database/database-spans.md | 2 +- docs/database/dynamodb.md | 2 +- docs/database/elasticsearch.md | 2 +- docs/database/graphql.md | 2 +- docs/database/hbase.md | 2 +- docs/database/mongodb.md | 2 +- docs/database/mssql.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- docs/exceptions/README.md | 2 +- docs/exceptions/exceptions-logs.md | 10 +++++----- docs/exceptions/exceptions-spans.md | 4 ++-- docs/faas/README.md | 2 +- docs/faas/aws-lambda.md | 12 ++++++------ docs/faas/faas-metrics.md | 4 ++-- docs/faas/faas-spans.md | 2 +- docs/feature-flags/README.md | 2 +- docs/feature-flags/feature-flags-logs.md | 10 +++++----- docs/feature-flags/feature-flags-spans.md | 2 +- docs/general/attributes.md | 2 +- docs/general/events.md | 2 +- docs/general/logs.md | 6 +++--- docs/general/metrics.md | 6 +++--- docs/general/session.md | 2 +- docs/general/trace-compatibility.md | 2 +- docs/general/trace.md | 4 ++-- docs/http/README.md | 2 +- docs/http/http-metrics.md | 6 +++--- docs/http/http-spans.md | 6 +++--- docs/messaging/README.md | 2 +- docs/messaging/kafka.md | 2 +- docs/messaging/messaging-spans.md | 6 +++--- docs/messaging/rabbitmq.md | 2 +- docs/messaging/rocketmq.md | 2 +- docs/object-stores/README.md | 2 +- docs/object-stores/s3.md | 2 +- docs/resource/README.md | 10 +++++----- docs/resource/android.md | 2 +- docs/resource/browser.md | 2 +- docs/resource/cloud-provider/README.md | 2 +- docs/resource/cloud-provider/aws/README.md | 2 +- docs/resource/cloud-provider/aws/ecs.md | 2 +- docs/resource/cloud-provider/aws/eks.md | 2 +- docs/resource/cloud-provider/aws/logs.md | 2 +- docs/resource/cloud-provider/gcp/README.md | 2 +- docs/resource/cloud-provider/gcp/cloud-run.md | 2 +- docs/resource/cloud-provider/heroku.md | 2 +- docs/resource/cloud.md | 2 +- docs/resource/container.md | 2 +- docs/resource/deployment-environment.md | 2 +- docs/resource/device.md | 2 +- docs/resource/faas.md | 2 +- docs/resource/host.md | 2 +- docs/resource/k8s.md | 2 +- docs/resource/os.md | 2 +- docs/resource/process.md | 2 +- docs/resource/webengine.md | 2 +- docs/rpc/README.md | 2 +- docs/rpc/connect-rpc.md | 4 ++-- docs/rpc/grpc.md | 6 +++--- docs/rpc/json-rpc.md | 2 +- docs/rpc/rpc-metrics.md | 4 ++-- docs/rpc/rpc-spans.md | 2 +- docs/runtime/README.md | 2 +- docs/runtime/jvm-metrics.md | 8 ++++---- docs/system/README.md | 2 +- docs/system/hardware-metrics.md | 2 +- docs/system/process-metrics.md | 2 +- docs/system/system-metrics.md | 4 ++-- docs/url/README.md | 2 +- docs/url/url.md | 2 +- internal/tools/update_specification_version.sh | 4 ++-- model/README.md | 6 +++--- 85 files changed, 129 insertions(+), 128 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 782fb79ca9..3e4d9addaa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ key, but non-obvious, aspects: You will see ` -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/README.md b/docs/database/README.md index 69b0ccf1f9..50d42dd7cb 100644 --- a/docs/database/README.md +++ b/docs/database/README.md @@ -31,4 +31,4 @@ Technology specific semantic conventions are defined for the following databases * [Redis](redis.md): Semantic Conventions for *Redis*. * [SQL](sql.md): Semantic Conventions for *SQL* databases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 41380ebedc..b6f160457c 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -47,4 +47,4 @@ described on this page. | `local_serial` | local_serial | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index c5b2a1a836..5c092cf560 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -90,4 +90,4 @@ In addition to Cosmos DB attributes, all spans include | `db.cosmosdb.sub_status_code` | `0` | | `db.cosmosdb.request_charge` | `7.43` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 3624e69e9c..3ee335d759 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -22,4 +22,4 @@ described on this page. **[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 047ec6651d..058f672dd8 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -183,6 +183,6 @@ This metric is [recommended][MetricRecommended]. | `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md -[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#required -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#required +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index a767dce76a..cc995d3d37 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -200,4 +200,4 @@ More specific Semantic Conventions are defined for the following database techno * [Redis](redis.md): Semantic Conventions for *Redis*. * [SQL](sql.md): Semantic Conventions for *SQL* databases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 13a6ec9ce1..61299804a6 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -170,4 +170,4 @@ These attributes are filled in for all DynamoDB request types. | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 9bbddc5663..74e956557f 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -89,4 +89,4 @@ the server address behind any intermediaries (e.g. proxies) if it's available. | `db.elasticsearch.cluster.name` | `"e9106fc68e3044f0b1475b04bf4ffd5f"` | | `db.elasticsearch.node.name` | `"instance-0000000001"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/graphql.md b/docs/database/graphql.md index 7e3d6a8a06..fb94a7b25e 100644 --- a/docs/database/graphql.md +++ b/docs/database/graphql.md @@ -32,4 +32,4 @@ MAY be used as span name. | `subscription` | GraphQL subscription | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 2c51ce763e..8cbc9d41a1 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -22,4 +22,4 @@ described on this page. **[1]:** For HBase the `db.name` should be set to the HBase namespace. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index d3d3608272..debad64014 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -37,4 +37,4 @@ described on this page. | `db.operation` | `"findAndModify"` | | `db.mongodb.collection` | `"products"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/mssql.md b/docs/database/mssql.md index ee1bc5e099..b64cf49678 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -23,4 +23,4 @@ described on this page. **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index f7e8d41079..9be10a987b 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -43,4 +43,4 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.operation` | not set | | `db.redis.database_index` | `15` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index 7fe9370f79..70beb8eead 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -39,4 +39,4 @@ This is an example of attributes for a MySQL database span: | `db.operation` | `"SELECT"` | | `db.sql.table` | `"orders"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/exceptions/README.md b/docs/exceptions/README.md index e4bd767b8c..4e074df495 100644 --- a/docs/exceptions/README.md +++ b/docs/exceptions/README.md @@ -16,4 +16,4 @@ Semantic conventions for Exceptions are defined for the following signals: * [Exceptions on spans](exceptions-spans.md): Semantic Conventions for Exceptions associated with *spans*. * [Exceptions in logs](exceptions-logs.md): Semantic Conventions for Exceptions recorded in *logs*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 32d20e68cf..db8f45c767 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -7,8 +7,8 @@ linkTitle: Logs **Status**: [Experimental][DocumentStatus] This document defines semantic conventions for recording exceptions on -[logs](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/bridge-api.md#emit-a-logrecord) and [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/event-api.md#emit-event) -emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/bridge-api.md#logger). +[logs](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#emit-a-logrecord) and [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/event-api.md#emit-event) +emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger). @@ -21,7 +21,7 @@ emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry ## Recording an Exception Exceptions SHOULD be recorded as attributes on the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/bridge-api.md#logger) emit +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger) emit operations. Exceptions MAY be recorded on "logs" or "events" depending on the context. @@ -33,7 +33,7 @@ the language runtime. ## Attributes The table below indicates which attributes should be added to the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. | Attribute | Type | Description | Examples | Requirement Level | @@ -53,4 +53,4 @@ The table below indicates which attributes should be added to the Same as [Trace Semantic Conventions for Exceptions - Stacktrace Representation](exceptions-spans.md#stacktrace-representation). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index eef07f2cdb..ec64eb86bc 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -23,7 +23,7 @@ An exception SHOULD be recorded as an `Event` on the span during which it occurr The name of the event MUST be `"exception"`. A typical template for an auto-instrumentation implementing this semantic convention -using an [API-provided `recordException` method](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#record-exception) +using an [API-provided `recordException` method](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#record-exception) could look like this (pseudo-Java): ```java @@ -109,4 +109,4 @@ grained information from a stacktrace, if necessary. [telemetry-sdk-resource]: ../resource/README.md#telemetry-sdk [erlang-stacktrace]: https://www.erlang.org/doc/man/erl_error.html#format_exception-3 [elixir-stacktrace]: https://hexdocs.pm/elixir/1.14.3/Exception.html#format/3 -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/faas/README.md b/docs/faas/README.md index 62ecf24d24..bdf3b05222 100644 --- a/docs/faas/README.md +++ b/docs/faas/README.md @@ -20,4 +20,4 @@ Technology specific semantic conventions are defined for the following FaaS serv * [AWS Lambda](aws-lambda.md): Semantic Conventions for *AWS Lambda*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 41ccb4cce5..50dba92033 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -57,9 +57,9 @@ and the [cloud resource conventions][cloud]. The following AWS Lambda-specific a ### AWS X-Ray Environment Span Link 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](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/context/api-propagators.md). If the -resulting `Context` is [valid](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#isvalid) then a [Span Link][] SHOULD be added to the new Span's -[start options](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#specifying-links) with an associated attribute of `source=x-ray-env` to +OpenTelemetry `Context` out of it using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md). If the +resulting `Context` is [valid](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#isvalid) then a [Span Link][] SHOULD be added to the new Span's +[start options](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/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 @@ -109,7 +109,7 @@ be ` process`. If there are multiple sources in the batch, the nam For every message in the event, the [message system attributes][] (not message attributes, which are provided by the user) SHOULD be checked for the key `AWSTraceHeader`. If it is present, an OpenTelemetry `Context` SHOULD be -parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/context/api-propagators.md) and +parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) and added as a link to the span. This means the span may have as many links as messages in the batch. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. @@ -122,7 +122,7 @@ See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context- For the SQS message span, the name MUST be ` process`. The parent MUST be the `CONSUMER` span corresponding to the SQS event. The [message system attributes][] (not message attributes, which are provided by the user) SHOULD be checked for the key `AWSTraceHeader`. If it is present, an OpenTelemetry `Context` SHOULD be -parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/context/api-propagators.md) and +parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) and added as a link to the span. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. @@ -246,4 +246,4 @@ because it is not available until function invocation. [environment variables]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index ab1f395c13..b64d90dd01 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -288,5 +288,5 @@ FaaS providers. This list is not exhaustive. * [Google CloudFunctions Metrics](https://cloud.google.com/monitoring/api/metrics_gcp#gcp-cloudfunctions) * [OpenFaas Metrics](https://docs.openfaas.com/architecture/metrics/) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index e1e7066b32..3a9f50c2ad 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -261,4 +261,4 @@ This example shows the FaaS attributes for a (non-FaaS) process hosted on Google | Resource | `faas.instance` | n/a | `"my-lambda-function:instance-0001"` | | Resource | `cloud.resource_id` | n/a | `"arn:aws:lambda:us-west-2:123456789012:function:my-lambda-function"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/feature-flags/README.md b/docs/feature-flags/README.md index 30a308837a..1eb70a28e3 100644 --- a/docs/feature-flags/README.md +++ b/docs/feature-flags/README.md @@ -17,4 +17,4 @@ Semantic conventions for feature flags are defined for the following signals: * [Feature Flags in Spans](feature-flags-spans.md): Semantic Conventions for recording feature flags in *spans*. * [Feature Flags in Logs](feature-flags-logs.md): Semantic Conventions for recording feature flags in *logs*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/feature-flags/feature-flags-logs.md b/docs/feature-flags/feature-flags-logs.md index 8f19707e75..200229fab7 100644 --- a/docs/feature-flags/feature-flags-logs.md +++ b/docs/feature-flags/feature-flags-logs.md @@ -7,8 +7,8 @@ linkTitle: Logs **Status**: [Experimental][DocumentStatus] This document defines semantic conventions for recording feature flag evaluations as -a [log record](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/data-model.md#log-and-event-record-definition) emitted through the -[Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/bridge-api.md#emit-a-logrecord). +a [log record](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) emitted through the +[Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#emit-a-logrecord). This is useful when a flag is evaluated outside of a transaction context such as when the application loads or on a timer. To record a flag evaluation as a part of a transaction context, @@ -28,14 +28,14 @@ section of the trace semantic convention for feature flag evaluations. ## Recording an Evaluation Feature flag evaluations SHOULD be recorded as attributes on the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/bridge-api.md#logger) emit +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger) emit operations. Evaluations MAY be recorded on "logs" or "events" depending on the context. ## Attributes The table below indicates which attributes should be added to the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. The event name MUST be `feature_flag`. @@ -56,4 +56,4 @@ semantic identifier is unavailable. String representation of the value should be determined by the implementer. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/feature-flags/feature-flags-spans.md b/docs/feature-flags/feature-flags-spans.md index 0bf5de6174..bdd94a0106 100644 --- a/docs/feature-flags/feature-flags-spans.md +++ b/docs/feature-flags/feature-flags-spans.md @@ -60,4 +60,4 @@ semantic identifier is unavailable. String representation of the value should be determined by the implementer. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 542a74878d..6a8793df65 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -393,4 +393,4 @@ about the span. | `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/events.md b/docs/general/events.md index 92747e77d9..8c9a0c05a7 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -58,4 +58,4 @@ unrelated events. | `k8s` | Events from Kubernetes | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/logs.md b/docs/general/logs.md index 555530f58a..c66136624d 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -28,7 +28,7 @@ The following semantic conventions for logs are defined: * [Feature Flags](/docs/feature-flags/feature-flags-logs.md): Semantic attributes that may be used in describing feature flag evaluations in logs. Apart from semantic conventions for logs, [events](events.md), [traces](trace.md), and [metrics](metrics.md), -OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md) with their own +OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). ## General log identification attributes @@ -48,7 +48,7 @@ The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID This section describes attributes for log media in OpenTelemetry. Log media are mechanisms by which logs are transmitted. Types of media include files, streams, network protocols, and os-specific logging services such as journald and Windows Event Log. -**Note:** The OpenTelemetry specification defines a [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md#resource-sdk) as `an immutable representation of the entity producing telemetry`. +**Note:** The OpenTelemetry specification defines a [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md#resource-sdk) as `an immutable representation of the entity producing telemetry`. The following attributes do not describe entities that produce telemetry. Rather, they describe mechanisms of log transmission. As such, these should be recorded as Log Record attributes when applicable. They should not be recorded as Resource attributes. @@ -82,4 +82,4 @@ As such, these should be recorded as Log Record attributes when applicable. They | `stderr` | Events from stderr stream | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 564d929a6a..6defc732af 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -38,7 +38,7 @@ The following semantic conventions surrounding metrics are defined: * [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. Apart from semantic conventions for metrics, [traces](trace.md), [logs](logs.md), and [events](events.md), OpenTelemetry also -defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md) with +defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). ## General Guidelines @@ -99,7 +99,7 @@ usable. When building components that interoperate between OpenTelemetry and a system using the OpenMetrics exposition format, use the -[OpenMetrics Guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/compatibility/prometheus_and_openmetrics.md). +[OpenMetrics Guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/compatibility/prometheus_and_openmetrics.md). ### Naming rules for Counters and UpDownCounters @@ -238,4 +238,4 @@ For example, if you are tracking `active_requests` with an `UpDownCounter`, and request starts and decrementing it each time a request ends, then any attributes which are not yet available when incrementing the counter at request start should not be used when decrementing the counter at request end. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/session.md b/docs/general/session.md index 2a3f533107..c6d5c55920 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -19,4 +19,4 @@ the Logs, Events, and Spans generated during the Session's lifecycle. | `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index 77ed44a13b..54e02fcf92 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -39,4 +39,4 @@ between a child Span and a parent Span, as defined by | `follows_from` | The parent Span does not depend in any way on the result of the child Span | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/trace.md b/docs/general/trace.md index af8e1c164e..01a99b61c4 100644 --- a/docs/general/trace.md +++ b/docs/general/trace.md @@ -34,7 +34,7 @@ The following semantic conventions for spans are defined: * [RPC/RMI](/docs/rpc/rpc-spans.md): For remote procedure call (e.g., gRPC) spans. Apart from semantic conventions for traces, [metrics](metrics.md), [logs](logs.md), and [events](events.md), -OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md) with their own +OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/http/README.md b/docs/http/README.md index a5249266f1..1c27a324f4 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -45,4 +45,4 @@ Semantic conventions for HTTP are defined for the following signals: * [HTTP Spans](http-spans.md): Semantic Conventions for HTTP client and server *spans*. * [HTTP Metrics](http-metrics.md): Semantic Conventions for HTTP client and server *metrics*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 0227a4d713..2979aca7ce 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -64,7 +64,7 @@ This metric is required. When this metric is reported alongside an HTTP server span, the metric value SHOULD be the same as the HTTP server span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -450,7 +450,7 @@ This metric is required. When this metric is reported alongside an HTTP client span, the metric value SHOULD be the same as the HTTP client span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -730,4 +730,4 @@ SHOULD NOT be set if capturing it would require an extra DNS lookup. | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 9ed59f4f33..5ad6181be5 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -63,7 +63,7 @@ and various HTTP versions like 1.1, 2 and SPDY. ## Name -HTTP spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#span). +HTTP spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#span). @@ -87,7 +87,7 @@ default span name. ## Status -[Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#set-status) MUST be left unset if HTTP status code was in the +[Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, unless there was another error (e.g., network error receiving the response body; or 3xx codes with max redirects exceeded), in which case status MUST be set to `Error`. @@ -591,4 +591,4 @@ Span name: `POST /uploads/:document_id`. | `http.response.status_code` | `201` | | `error.type` | `WebSocketDisconnect` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/README.md b/docs/messaging/README.md index e117836a2e..3d0a28ea6e 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -21,4 +21,4 @@ Technology specific semantic conventions are defined for the following messaging * [RabbitMQ](rabbitmq.md): Semantic Conventions for *RabbitMQ*. * [RocketMQ](rocketmq.md): Semantic Conventions for *Apache RocketMQ*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 90fd518580..9bfb1c2332 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -84,4 +84,4 @@ Process CB: | Span Rcv2 | | `messaging.kafka.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | | `messaging.kafka.message.offset` | `"12"` | `"12"` | `"12"` | `"32"` | `"32"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 15fef2213e..388ec90b03 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -177,7 +177,7 @@ The span name SHOULD be set to the message destination name and the operation be ``` -The destination name SHOULD only be used for the span name if it is known to be of low cardinality (cf. [general span name guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#span)). +The destination name SHOULD only be used for the span name if it is known to be of low cardinality (cf. [general span name guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#span)). This can be assumed if it is statically derived from application code or configuration. Wherever possible, the real destination names after resolving logical or aliased names SHOULD be used. If the destination name is dynamic, such as a [conversation ID](#conversations) or a value obtained from a `Reply-To` header, it SHOULD NOT be used for the span name. @@ -422,7 +422,7 @@ Process C: | Span Recv1 | Given is a process P, that publishes two messages to a queue Q on messaging system MS, and a process C, which receives them separately in two different operations (Span Recv1 and Recv2) and processes both messages in one batch (Span Proc1). -Since each span can only have one parent, C3 should not choose a random parent out of C1 and C2, but rather rely on the implicitly selected parent as defined by the [tracing API spec](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md). +Since each span can only have one parent, C3 should not choose a random parent out of C1 and C2, but rather rely on the implicitly selected parent as defined by the [tracing API spec](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md). Depending on the implementation, the producing spans might still be available in the meta data of the messages and should be added to C3 as links. The client library or application could also add the receiver span's SpanContext to the data structure it returns for each message. In this case, C3 could also add links to the receiver spans C1 and C2. @@ -460,4 +460,4 @@ More specific Semantic Conventions are defined for the following messaging techn * [RabbitMQ](rabbitmq.md): Semantic Conventions for *RabbitMQ*. * [RocketMQ](rocketmq.md): Semantic Conventions for *Apache RocketMQ*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 3c5bff049c..fcc120f338 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -23,4 +23,4 @@ In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. | `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index cf7c88c194..fe6a7d3401 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -52,4 +52,4 @@ Specific attributes for Apache RocketMQ are defined below. `messaging.client_id` SHOULD be set to the client ID that is automatically generated by the Apache RocketMQ SDK. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/object-stores/README.md b/docs/object-stores/README.md index 3dd2eb6715..da6a0d8612 100644 --- a/docs/object-stores/README.md +++ b/docs/object-stores/README.md @@ -15,4 +15,4 @@ The following technology specific semantic conventions are defined for object st * [AWS S3](s3.md): Semantic Conventions for *AWS S3*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index 904d9c0ad0..4b5a0f4dfd 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -68,4 +68,4 @@ This applies in particular to the following operations: - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/README.md b/docs/resource/README.md index d0a4a272dc..4d3e747dd6 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -9,7 +9,7 @@ path_base_for_github_subdir: **Status**: [Mixed][DocumentStatus] -This document defines standard attributes for resources. These attributes are typically used in the [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md) and are also recommended to be used anywhere else where there is a need to describe a resource in a consistent manner. The majority of these attributes are inherited from +This document defines standard attributes for resources. These attributes are typically used in the [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) and are also recommended to be used anywhere else where there is a need to describe a resource in a consistent manner. The majority of these attributes are inherited from [OpenCensus Resource standard](https://github.com/census-instrumentation/opencensus-specs/blob/master/resource/StandardResources.md). @@ -47,7 +47,7 @@ This document defines standard attributes for resources. These attributes are ty Attributes are grouped logically by the type of the concept that they described. Attributes in the same group have a common prefix that ends with a dot. For example all attributes that describe Kubernetes properties start with "k8s." -See [Attribute Requirement Levels](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-requirement-level.md) for details on when attributes +See [Attribute Requirement Levels](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-requirement-level.md) for details on when attributes should be included. ## Attributes with Special Handling @@ -59,14 +59,14 @@ Given their significance some resource attributes are treated specifically as de ### Semantic Attributes with Dedicated Environment Variable These are the attributes which MAY be configurable via a dedicated environment variable -as specified in [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/configuration/sdk-environment-variables.md): +as specified in [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/configuration/sdk-environment-variables.md): - [`service.name`](#service) ## Semantic Attributes with SDK-provided Default Value These are the attributes which MUST be provided by the SDK -as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/resource/sdk.md#sdk-provided-resource-attributes): +as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md#sdk-provided-resource-attributes): - [`service.name`](#service) - [`telemetry.sdk` group](#telemetry-sdk) @@ -236,4 +236,4 @@ Valid cloud providers are: - [Tencent Cloud](https://www.tencentcloud.com/) (`tencent_cloud`) - [Heroku dyno](./cloud-provider/heroku.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/android.md b/docs/resource/android.md index bbef3af2d0..39daee5a8f 100644 --- a/docs/resource/android.md +++ b/docs/resource/android.md @@ -12,4 +12,4 @@ | `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/browser.md b/docs/resource/browser.md index 9f5b164d88..c352b70c70 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -29,4 +29,4 @@ The list of possible values is defined in the [W3C User-Agent Client Hints speci **[5]:** The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/README.md b/docs/resource/cloud-provider/README.md index 40e4d4822a..9d4757a6c0 100644 --- a/docs/resource/cloud-provider/README.md +++ b/docs/resource/cloud-provider/README.md @@ -15,4 +15,4 @@ This document defines semantic conventions for resource cloud providers. * [GCP](gcp/README.md): Semantic Conventions for Google Cloud Platform. * [Heroku](heroku.md): Semantic Conventions for Heroku. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/README.md b/docs/resource/cloud-provider/aws/README.md index 3e20b6848e..2ac32239e5 100644 --- a/docs/resource/cloud-provider/aws/README.md +++ b/docs/resource/cloud-provider/aws/README.md @@ -28,4 +28,4 @@ Attributes that relate to an individual AWS service: - [Elastic Container Service (ECS)](./ecs.md) - [Elastic Kubernetes Service (EKS)](./eks.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index eefbee3103..362b66dde9 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -24,4 +24,4 @@ | `fargate` | fargate | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/eks.md b/docs/resource/cloud-provider/aws/eks.md index 765108afce..9bc4e42500 100644 --- a/docs/resource/cloud-provider/aws/eks.md +++ b/docs/resource/cloud-provider/aws/eks.md @@ -12,4 +12,4 @@ | `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index 5001849225..6d7606664d 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -21,4 +21,4 @@ **[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/README.md b/docs/resource/cloud-provider/gcp/README.md index 6888ead5a1..1e975ff9db 100644 --- a/docs/resource/cloud-provider/gcp/README.md +++ b/docs/resource/cloud-provider/gcp/README.md @@ -19,4 +19,4 @@ provider (like account ID, operating system, etc), it belongs in the parent - [Cloud Run](./cloud-run.md) - [Compute Engine](./gce.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index ce884d3e1e..d929928a9a 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -15,4 +15,4 @@ These conventions are recommended for resources running on Cloud Run. | `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index 2344373f0a..7e20ce9e47 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -29,4 +29,4 @@ Additionally, [the `cloud.provider` resource attribute MUST be set to `heroku`]( [Heroku dyno metadata]: https://devcenter.heroku.com/articles/dyno-metadata -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index 871c36f5bd..6644e63325 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -85,4 +85,4 @@ The following well-known definitions MUST be used if you set this attribute and | `tencent_cloud` | Tencent Cloud | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/container.md b/docs/resource/container.md index 7c4a014932..827e20b779 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -54,4 +54,4 @@ that defines an OCI Image manifest. An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index 847283447d..9766919543 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -12,4 +12,4 @@ | `deployment.environment` | string | Name of the [deployment environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka deployment tier). | `staging`; `production` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/device.md b/docs/resource/device.md index 5aa502c9a0..cfbaf9d82d 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -23,4 +23,4 @@ **[4]:** It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/faas.md b/docs/resource/faas.md index 1c92319818..f8560c1471 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -80,4 +80,4 @@ There are cases where a FaaS resource attribute is better applied as a span attribute instead. See the [FaaS trace conventions](/docs/faas/faas-spans.md) for more. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/host.md b/docs/resource/host.md index 77c7a707af..d074a30f6c 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -78,4 +78,4 @@ detector implementations MUST not collect `host.id` from privileged sources. If privileged lookup of `host.id` is required, the value should be injected via the `OTEL_RESOURCE_ATTRIBUTES` environment variable. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index c0f5769094..ef50c8a818 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -210,4 +210,4 @@ A CronJob creates Jobs on a repeating schedule. | `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/os.md b/docs/resource/os.md index a868349619..542b61ad2a 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -34,4 +34,4 @@ In case of virtualized environments, this is the operating system as it is obser | `z_os` | IBM z/OS | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/process.md b/docs/resource/process.md index 24d1e7b8f9..737c4aca68 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -220,4 +220,4 @@ Examples for some Ruby runtimes | MRI | ruby | 2.7.1 | ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19] | | TruffleRuby | truffleruby | 2.6.2 | truffleruby (Shopify) 20.0.0-dev-92ed3059, like ruby 2.6.2, GraalVM CE Native [x86_64-darwin] | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 72d61d2613..0d23bbdd1b 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -23,4 +23,4 @@ The situations where there are multiple candidates, it is up to instrumentation * Either Apache HTTP Server or `mod_wsgi` MAY be chosen as `webengine`, depending on the decision made by the instrumentation authors. * Django SHOULD NOT be set as an `webengine` as the required information is already available in instrumentation library and setting this into `webengine` would duplicate the information. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/README.md b/docs/rpc/README.md index 81105afb30..c7810685b4 100644 --- a/docs/rpc/README.md +++ b/docs/rpc/README.md @@ -23,4 +23,4 @@ Technology specific semantic conventions are defined for the following RPC syste * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index 55ec272b40..75798f2fb8 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -53,6 +53,6 @@ Below is a table of attributes that SHOULD be included on client and server Conn ## Connect RPC Status -If `rpc.connect_rpc.error_code` is set, [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#set-status) MUST be set to `Error` and left unset in all other cases. +If `rpc.connect_rpc.error_code` is set, [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be set to `Error` and left unset in all other cases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index b02ab58cc9..8ff11b8cf8 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -53,10 +53,10 @@ Below is a table of attributes that SHOULD be included on client and server gRPC ## gRPC Status The table below describes when -the [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#set-status) MUST be set +the [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be set to `Error` or remain unset depending on the [gRPC status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) -and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/trace/api.md#spankind). +and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind). | gRPC Status Code | `SpanKind.SERVER` Span Status | `SpanKind.CLIENT` Span Status | |---|---|---| @@ -78,4 +78,4 @@ and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tr | DATA_LOSS | `Error` | `Error` | | UNAUTHENTICATED | unset | `Error` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index 9ceed93d14..e0842a6c0b 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -26,4 +26,4 @@ described on this page. **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index b7b51580ee..f9994db859 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -294,5 +294,5 @@ More specific Semantic Conventions are defined for the following RPC technologie * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/metrics/metric-requirement-level.md#recommended +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index e5d8fbb1fb..eb1a9a9298 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -211,4 +211,4 @@ More specific Semantic Conventions are defined for the following RPC technologie * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/runtime/README.md b/docs/runtime/README.md index a60539ebaa..bc6f2c9b75 100644 --- a/docs/runtime/README.md +++ b/docs/runtime/README.md @@ -54,4 +54,4 @@ semantic conventions when instrumenting runtime environments. [`process.runtime`](/docs/resource/process.md#process-runtimes) resource attributes SHOULD be included on runtime metric events as appropriate. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index efcf94ca6e..a5d656ba5c 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -162,7 +162,7 @@ This metric is obtained by subscribing to [`GarbageCollectionNotificationInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html) events provided by [`GarbageCollectorMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/GarbageCollectorMXBean.html). The duration value is obtained from [`GcInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GcInfo.html#getDuration--) This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) of `[]` (single bucket histogram capturing count, sum, min, max). @@ -425,6 +425,6 @@ This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#opt-in -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md#recommended +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/docs/system/README.md b/docs/system/README.md index 8d47ef9fcc..a05a0bf9e8 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -18,4 +18,4 @@ System semantic conventions are defined for the following metrics: * [Process](process-metrics.md): For standard process metrics. * [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index 516674d5e6..b5b6cee212 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -388,4 +388,4 @@ Additional **Recommended** attributes: | ----------------- | ---------------------- | ---------- | | `sensor_location` | Location of the sensor | `PS0 V3_3` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 25a6eb8bc4..4312631963 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -48,4 +48,4 @@ Below is a table of Process metric instruments. Process metrics SHOULD be associated with a [`process`](/docs/resource/process.md#process) resource whose attributes provide additional context about the process. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index a06d5b9664..c92dff04e5 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -750,8 +750,8 @@ An instrument for load average over 1 minute on Linux could be named `system.linux.cpu.load_1m`, reusing the `cpu` name proposed above and having an `{os}` prefix to split this metric across OSes. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/metrics/metric-requirement-level.md#recommended +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended ### Metric: `system.linux.memory.available` diff --git a/docs/url/README.md b/docs/url/README.md index af111395de..6c863191ae 100644 --- a/docs/url/README.md +++ b/docs/url/README.md @@ -15,4 +15,4 @@ URL semantic conventions are defined for the following: * [URL](url.md): For describing URL and its components. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/url/url.md b/docs/url/url.md index 9f20f62170..0b8cc15980 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -48,4 +48,4 @@ Instrumentations that are aware of specific sensitive query string parameters MU _Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/internal/tools/update_specification_version.sh b/internal/tools/update_specification_version.sh index 761b9cee65..86cd140b88 100755 --- a/internal/tools/update_specification_version.sh +++ b/internal/tools/update_specification_version.sh @@ -6,9 +6,9 @@ # Set this to the version number you want to CHANGE in URLs in the repository. -PREVIOUS_SPECIFICATION_VERSION="v1.21.0" +PREVIOUS_SPECIFICATION_VERSION="v1.22.0" # Set this to the version number you want to KEEP in URLs in the repository. -LATEST_SPECIFICATION_VERSION="v1.22.0" +LATEST_SPECIFICATION_VERSION="v1.26.0" # The specific pattern we look for when replacing URLs SPECIFICATION_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/tree/" SPECIFICATION_BLOB_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/blob/" diff --git a/model/README.md b/model/README.md index f32a08bb12..33f3cd3379 100644 --- a/model/README.md +++ b/model/README.md @@ -10,9 +10,9 @@ the generated markdown output in the [docs](../docs/README.md) folder. ## Writing semantic conventions Semantic conventions for the spec MUST adhere to the -[attribute naming](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-naming.md), -[attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/common/attribute-requirement-level.md), -and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/metrics/metric-requirement-level.md) conventions. +[attribute naming](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md), +[attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-requirement-level.md), +and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md) conventions. Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. From f07ad8157990a35a6dca519678b0f8fec5845f91 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Thu, 12 Oct 2023 14:10:37 +0200 Subject: [PATCH 077/482] Increase markdown-link-check timeout (#393) --- .markdown_link_check_config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index 368aba40aa..48c1f6c392 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -15,5 +15,6 @@ } ], "retryOn429": true, + "timeout": "30s", "aliveStatusCodes": [200, 403] } From 4c7e85d45cdb2c304232f0605e1c480a0c13ba26 Mon Sep 17 00:00:00 2001 From: Armin Ruech Date: Thu, 12 Oct 2023 14:53:00 +0200 Subject: [PATCH 078/482] Add missing maintainers to auto_assign_issue.yml and auto_assign_pr.yml (#392) --- .github/auto_assign_issue.yml | 2 ++ .github/auto_assign_pr.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/auto_assign_issue.yml b/.github/auto_assign_issue.yml index 7a37146df5..82ebdb891d 100644 --- a/.github/auto_assign_issue.yml +++ b/.github/auto_assign_issue.yml @@ -6,7 +6,9 @@ addAssignees: true # A list of assignees, overrides reviewers if set assignees: + - AlexanderWert - arminru + - joaopgrassi - jsuereth - reyang diff --git a/.github/auto_assign_pr.yml b/.github/auto_assign_pr.yml index 6b9200b670..58d2db55b0 100644 --- a/.github/auto_assign_pr.yml +++ b/.github/auto_assign_pr.yml @@ -10,7 +10,9 @@ useAssigneeGroups: true # A list of assignees, split into different groups, to be added to pull requests (GitHub user name) assigneeGroups: maintainers: + - AlexanderWert - arminru + - joaopgrassi - jsuereth - reyang From ec3a4cf0afacc82250e7ecc0225a8d7ea624ebb4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 12 Oct 2023 06:04:18 -0700 Subject: [PATCH 079/482] Remove repetitive notes, briefs, etc on ref attributes (#367) Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 ++ docs/http/http-metrics.md | 33 +++++++++-------- docs/http/http-spans.md | 4 +- model/http-common.yaml | 7 +++- model/metrics/http.yaml | 78 --------------------------------------- model/trace/http.yaml | 47 +---------------------- 6 files changed, 30 insertions(+), 142 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3563762c3a..7e2684f73b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -139,6 +139,9 @@ release. - BREAKING: Rename/replace `(client|server).socket.(address|port)` attributes with `network.(peer|local).(address|port)`. ([#342](https://github.com/open-telemetry/semantic-conventions/pull/342)) +- Make `network.protocol.name|version` description consistent between HTTP + spans and metrics. + ([#367](https://github.com/open-telemetry/semantic-conventions/pull/367)) ## v1.21.0 (2023-07-13) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 2979aca7ce..58c7d7c18b 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -80,8 +80,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -252,8 +252,8 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -356,8 +356,8 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | @@ -465,8 +465,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -512,7 +512,8 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original 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. +If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then +`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. **[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. @@ -560,8 +561,8 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -607,7 +608,8 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original 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. +If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then +`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. **[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. @@ -655,8 +657,8 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `3.1.1` | Recommended | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -702,7 +704,8 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original 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. +If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then +`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. **[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 5ad6181be5..a127fde446 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -240,7 +240,7 @@ This span type represents an outbound HTTP request. There are two ways this can For an HTTP client span, `SpanKind` MUST be `Client`. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | @@ -363,7 +363,7 @@ This span type represents an inbound HTTP request. For an HTTP server span, `SpanKind` MUST be `Server`. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | diff --git a/model/http-common.yaml b/model/http-common.yaml index 7cf4614ac8..54e53fc72a 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -38,6 +38,7 @@ groups: - id: attributes.http.client type: attribute_group brief: 'HTTP Client attributes' + extends: attributes.http.common attributes: - ref: server.address requirement_level: required @@ -50,7 +51,8 @@ groups: 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. + If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then + `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - ref: server.port requirement_level: conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). @@ -63,6 +65,7 @@ groups: - id: attributes.http.server type: attribute_group brief: 'HTTP Server attributes' + extends: attributes.http.common attributes: - ref: http.route requirement_level: @@ -91,6 +94,8 @@ groups: - 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 + requirement_level: + recommended: If not default (`80` for `http` scheme, `443` for `https`). - ref: url.scheme requirement_level: required examples: ["http", "https"] diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 4b77963310..e9015a92d9 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -5,93 +5,15 @@ groups: extends: attributes.http.server attributes: - ref: server.address - brief: > - Name of the local HTTP server that received the request. requirement_level: opt_in - note: | - Determined by using the first of the following that applies - - - The [primary server name](/docs/http/http-spans.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: server.port - brief: > - Port of the local HTTP server that received the request. requirement_level: opt_in - note: | - Determined by using the first of the following that applies - - - Port identifier of the [primary server host](/docs/http/http-spans.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 - # todo (lmolkova) build tools don't populate grandparent attributes - - ref: error.type - requirement_level: - conditionally_required: If request has ended with an error. - examples: ['timeout', 'name_resolution_error', '500'] - note: | - If the request fails with an error before response status code was sent or received, - `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. - - If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. - - The `error.type` value SHOULD be predictable and SHOULD have low cardinality. - Instrumentations SHOULD document the list of errors they report. - - The cardinality of `error.type` within one instrumentation library SHOULD be low, but - telemetry consumers that aggregate data from multiple instrumentation libraries and applications - should be prepared for `error.type` to have high cardinality at query time, when no - additional filters are applied. - - If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - - ref: http.request.method - requirement_level: required - - ref: http.response.status_code - requirement_level: - conditionally_required: If and only if one was received/sent. - - ref: network.protocol.name - - ref: network.protocol.version - id: metric_attributes.http.client type: attribute_group brief: 'HTTP client attributes' extends: attributes.http.client attributes: - # todo (lmolkova) build tools don't populate grandparent attributes - - ref: http.request.method - requirement_level: required - - ref: http.response.status_code - requirement_level: - conditionally_required: If and only if one was received/sent. - - ref: network.protocol.name - - ref: network.protocol.version - - ref: error.type - requirement_level: - conditionally_required: If request has ended with an error. - examples: ['timeout', 'name_resolution_error', '500'] - note: | - If the request fails with an error before response status code was sent or received, - `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. - - If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. - - The `error.type` value SHOULD be predictable and SHOULD have low cardinality. - Instrumentations SHOULD document the list of errors they report. - - The cardinality of `error.type` within one instrumentation library SHOULD be low, but - telemetry consumers that aggregate data from multiple instrumentation libraries and applications - should be prepared for `error.type` to have high cardinality at query time, when no - additional filters are applied. - - If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: url.scheme requirement_level: required diff --git a/model/trace/http.yaml b/model/trace/http.yaml index dd224b7bb5..adb3534875 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -36,27 +36,8 @@ groups: recommended: if and only if request was retried. - ref: server.address 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: | - 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 - - If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then - `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - ref: server.port sampling_relevant: true - 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, `server.port` MUST match - URI port identifier, otherwise it MUST match `Host` header port identifier. - ref: network.peer.address requirement_level: recommended: If different than `server.address`. @@ -67,41 +48,17 @@ groups: sampling_relevant: true requirement_level: required - - id: trace.http.server type: span extends: attributes.http.server span_kind: server brief: 'Semantic Convention for HTTP Server' attributes: + - ref: http.route - ref: server.address - requirement_level: recommended sampling_relevant: true - 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](/docs/http/http-spans.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: server.port sampling_relevant: true - requirement_level: - recommended: 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](/docs/http/http-spans.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: network.local.address requirement_level: opt_in brief: Local socket address. Useful in case of a multi-IP host. @@ -131,5 +88,3 @@ groups: sampling_relevant: true - ref: url.scheme sampling_relevant: true - requirement_level: required - examples: ["http", "https"] From cadfe53949266d33476b15ca52c92f682600a29c Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 12 Oct 2023 09:47:57 -0400 Subject: [PATCH 080/482] Stage 1.22.0 release for review. (#380) Co-authored-by: Armin Ruech --- CHANGELOG.md | 5 + schema-next.yaml | 3 +- schemas/1.22.0 | 280 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 schemas/1.22.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2684f73b..7f6fa6005d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ release. ## Unreleased +## v1.22.0 (2023-10-12) + +- Remove experimental Kafka metrics ([#338](https://github.com/open-telemetry/semantic-conventions/pull/338)) - Adds `session.id` and session.md to general docs and model ([#215](https://github.com/open-telemetry/semantic-conventions/pull/215)) - Add `container.labels.` attributes. @@ -129,6 +132,8 @@ release. ([#350](https://github.com/open-telemetry/semantic-conventions/pull/350)) - Improve network attribute briefs. ([#352](https://github.com/open-telemetry/semantic-conventions/pull/352)) +- Document the difference between host and system metrics + ([#324](https://github.com/open-telemetry/semantic-conventions/pull/324)) - BREAKING: Rename `telemetry.auto.version` resource attribute to `telemetry.distro.version` and add `telemetry.distro.name` resource attribute ([#178](https://github.com/open-telemetry/semantic-conventions/pull/178)) diff --git a/schema-next.yaml b/schema-next.yaml index 4e276d419a..b238dd19c5 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -1,7 +1,8 @@ file_format: 1.1.0 -schema_url: https://opentelemetry.io/schemas/1.21.0 +schema_url: https://opentelemetry.io/schemas/next versions: next: + 1.22.0: spans: changes: # https://github.com/open-telemetry/semantic-conventions/pull/229 diff --git a/schemas/1.22.0 b/schemas/1.22.0 new file mode 100644 index 0000000000..c5a7f93a74 --- /dev/null +++ b/schemas/1.22.0 @@ -0,0 +1,280 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.22.0 +versions: + 1.22.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit + process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.usage + - jvm.buffer.limit + - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version + 1.21.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3336 + - rename_attributes: + attribute_map: + messaging.kafka.client_id: messaging.client_id + messaging.rocketmq.client_id: messaging.client_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3402 + - rename_attributes: + attribute_map: + # net.peer.(name|port) attributes were usually populated on client side + # so they should be usually translated to server.(address|port) + # net.host.* attributes were only populated on server side + net.host.name: server.address + net.host.port: server.port + # was only populated on client side + net.sock.peer.name: server.socket.domain + # net.sock.peer.(addr|port) mapping is not possible + # since they applied to both client and server side + # were only populated on server side + net.sock.host.addr: server.socket.address + net.sock.host.port: server.socket.port + http.client_ip: client.address + # https://github.com/open-telemetry/opentelemetry-specification/pull/3426 + - rename_attributes: + attribute_map: + net.protocol.name: network.protocol.name + net.protocol.version: network.protocol.version + net.host.connection.type: network.connection.type + net.host.connection.subtype: network.connection.subtype + net.host.carrier.name: network.carrier.name + net.host.carrier.mcc: network.carrier.mcc + net.host.carrier.mnc: network.carrier.mnc + net.host.carrier.icc: network.carrier.icc + # https://github.com/open-telemetry/opentelemetry-specification/pull/3355 + - rename_attributes: + attribute_map: + http.method: http.request.method + http.status_code: http.response.status_code + http.scheme: url.scheme + http.url: url.full + http.request_content_length: http.request.body.size + http.response_content_length: http.response.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/53 + - rename_metrics: + process.runtime.jvm.cpu.utilization: process.runtime.jvm.cpu.recent_utilization + 1.20.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3272 + - rename_attributes: + attribute_map: + net.app.protocol.name: net.protocol.name + net.app.protocol.version: net.protocol.version + 1.19.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3209 + - rename_attributes: + attribute_map: + faas.execution: faas.invocation_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3188 + - rename_attributes: + attribute_map: + faas.id: cloud.resource_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + http.user_agent: user_agent.original + resources: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + browser.user_agent: user_agent.original + 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: From ea50a0d2e13f215047b897133e29fd3efad093b6 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 12 Oct 2023 15:24:35 -0400 Subject: [PATCH 081/482] Add sections to changelog for easier user consumption on release. (#397) --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f6fa6005d..e7c4e4dcec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ release. ## Unreleased +### Breaking + +### Features + +### Fixes + ## v1.22.0 (2023-10-12) - Remove experimental Kafka metrics ([#338](https://github.com/open-telemetry/semantic-conventions/pull/338)) From 612d101d104899f456ec9b6c77f2ba9acf6f1be9 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 13 Oct 2023 04:35:40 -0700 Subject: [PATCH 082/482] Clarify that `error.type` should be the fully-qualified exception class name (if applicable) when it represents an exception type (#387) --- CHANGELOG.md | 4 ++++ docs/http/http-metrics.md | 42 ++++++++++++++++++++++----------------- docs/http/http-spans.md | 7 ++++--- model/error.yaml | 2 +- model/http-common.yaml | 7 ++++--- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7c4e4dcec..91249c0b5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ release. ### Fixes +- Clarify that `error.type` should be the fully-qualified exception class name + when it represents an exception type. + ([#387](https://github.com/open-telemetry/semantic-conventions/pull/387)) + ## v1.22.0 (2023-10-12) - Remove experimental Kafka metrics ([#338](https://github.com/open-telemetry/semantic-conventions/pull/338)) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 58c7d7c18b..0aa1e339fe 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -76,7 +76,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -87,10 +87,11 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -248,7 +249,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -259,10 +260,11 @@ This metric is optional. | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -352,7 +354,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -363,10 +365,11 @@ This metric is optional. | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -462,7 +465,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | @@ -472,10 +475,11 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -558,7 +562,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | @@ -568,10 +572,11 @@ This metric is optional. | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -654,7 +659,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | @@ -664,10 +669,11 @@ This metric is optional. | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index a127fde446..257ead144c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -115,7 +115,7 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.body.size`](../attributes-registry/http.md) | 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.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | @@ -130,10 +130,11 @@ sections below. | `user_agent.original` | 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 | **[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type or a component-specific low cardinality error code. +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. diff --git a/model/error.yaml b/model/error.yaml index cdfc587800..01b7b05f5f 100644 --- a/model/error.yaml +++ b/model/error.yaml @@ -26,6 +26,6 @@ groups: If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. - If a specific domain defines its own set of error codes (such as HTTP or gRPC status codes), + If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to use a domain-specific attribute and also set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. diff --git a/model/http-common.yaml b/model/http-common.yaml index 54e53fc72a..f10e7de342 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -11,13 +11,14 @@ groups: - ref: error.type requirement_level: conditionally_required: If request has ended with an error. - examples: ['timeout', 'name_resolution_error', '500'] + examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] note: | If the request fails with an error before response status code was sent or received, - `error.type` SHOULD be set to exception type or a component-specific low cardinality error code. + `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) + or a component-specific low cardinality error identifier. If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), - `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error code. + `error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. The `error.type` value SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. From 63231257a0b62e22d699c3399043826186095832 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 13 Oct 2023 07:46:22 -0700 Subject: [PATCH 083/482] Add cardinality warning about two opt-in HTTP metric attributes (#401) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 6 ++++++ model/metrics/http.yaml | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91249c0b5d..64d9b2c8ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ release. - Clarify that `error.type` should be the fully-qualified exception class name when it represents an exception type. ([#387](https://github.com/open-telemetry/semantic-conventions/pull/387)) +- Add cardinality warning about two opt-in HTTP metric attributes + ([#401](https://github.com/open-telemetry/semantic-conventions/pull/401)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 0aa1e339fe..2da82c97d6 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -209,6 +209,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[3]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. @@ -216,6 +219,9 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + `http.request.method` 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 | diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index e9015a92d9..2596a06f08 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -52,6 +52,9 @@ groups: SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. + Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + to trigger cardinality limits, degrading the usefulness of the metric. + - ref: server.port requirement_level: opt_in brief: > @@ -64,6 +67,9 @@ groups: if it's sent in absolute-form. - Port identifier of the `Host` header + Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + to trigger cardinality limits, degrading the usefulness of the metric. + - id: metric.http.server.request.body.size type: metric metric_name: http.server.request.body.size From 5778d7d9a365e2e08d6baea672dbedf9f171d2c8 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 15 Oct 2023 15:59:20 -0400 Subject: [PATCH 084/482] RabbitMQ, not RibbitMQ (#405) --- docs/messaging/rabbitmq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index fcc120f338..61f37c15d5 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -6,7 +6,7 @@ linkTitle: RabbitMQ **Status**: [Experimental][DocumentStatus] -The Semantic Conventions for [RibbitMQ](https://www.rabbitmq.com/) extend and override the [Messaging Semantic Conventions](README.md) +The Semantic Conventions for [RabbitMQ](https://www.rabbitmq.com/) extend and override the [Messaging Semantic Conventions](README.md) that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. From d21d653031728e610bc2510d8f3e07fe3541e76f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 15 Oct 2023 22:35:57 -0700 Subject: [PATCH 085/482] Rename `http.resend_count` to `http.request.resend_count` (#374) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/attributes-registry/http.md | 2 +- docs/http/http-spans.md | 2 +- model/registry/http.yaml | 2 +- model/trace/http.yaml | 2 +- schema-next.yaml | 4 ++++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64d9b2c8ba..15bfd73710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ release. ### Breaking +- BREAKING: Rename http.resend_count to http.request.resend_count. + ([#374](https://github.com/open-telemetry/semantic-conventions/pull/374)) + ### Features ### Fixes diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 7a62cc8498..7f8602c372 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -12,7 +12,7 @@ | `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [1] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | | `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | | `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | -| `http.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | +| `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | | `http.response.body.size` | 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` | | `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [4] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | | `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 257ead144c..67351f738c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -244,7 +244,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`http.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | +| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | | [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | | [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 1d6f0192fa..05483ec79b 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -81,7 +81,7 @@ groups: type: string brief: Original HTTP method sent by the client in the request line. examples: ["GeT", "ACL", "foo"] - - id: resend_count + - id: request.resend_count type: int brief: > The ordinal number of request resending attempt (for any reason, including redirects). diff --git a/model/trace/http.yaml b/model/trace/http.yaml index adb3534875..c0cfdaf71c 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -31,7 +31,7 @@ groups: span_kind: client brief: 'Semantic Convention for HTTP Client' attributes: - - ref: http.resend_count + - ref: http.request.resend_count requirement_level: recommended: if and only if request was retried. - ref: server.address diff --git a/schema-next.yaml b/schema-next.yaml index b238dd19c5..8fe76165a9 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -9,6 +9,10 @@ versions: - rename_attributes: attribute_map: messaging.message.payload_size_bytes: messaging.message.body.size + # https://github.com/open-telemetry/opentelemetry-specification/pull/374 + - rename_attributes: + attribute_map: + http.resend_count: http.request.resend_count metrics: changes: # https://github.com/open-telemetry/semantic-conventions/pull/224 From cee22ec91448808ebcfa53df689c800c7171c9e1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 15 Oct 2023 22:42:58 -0700 Subject: [PATCH 086/482] Make `server.port` conditionally required on HTTP server semconv (#399) Co-authored-by: Joao Grassi Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 2 +- model/http-common.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15bfd73710..2efc35c494 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ release. ([#387](https://github.com/open-telemetry/semantic-conventions/pull/387)) - Add cardinality warning about two opt-in HTTP metric attributes ([#401](https://github.com/open-telemetry/semantic-conventions/pull/401)) +- Change `server.port` from recommended to conditionally required on HTTP server semconv. + ([#399](https://github.com/open-telemetry/semantic-conventions/pull/399)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 67351f738c..a5e74fdd29 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -375,7 +375,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Recommended: [6] | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | | [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | diff --git a/model/http-common.yaml b/model/http-common.yaml index f10e7de342..921f3f1e3a 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -96,7 +96,7 @@ groups: if it's sent in absolute-form. - Port identifier of the `Host` header requirement_level: - recommended: If not default (`80` for `http` scheme, `443` for `https`). + conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). - ref: url.scheme requirement_level: required examples: ["http", "https"] From adc0187098a4a3afcf200576322913803ecaf6dd Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 17 Oct 2023 03:50:23 -0700 Subject: [PATCH 087/482] BREAKING: Define `url.scheme` in terms of logical operation in HTTP server semconv (#376) Co-authored-by: Liudmila Molkova --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 12 +++++++++--- docs/http/http-spans.md | 4 +++- model/http-common.yaml | 6 ++++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2efc35c494..0d687b6268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ release. - BREAKING: Rename http.resend_count to http.request.resend_count. ([#374](https://github.com/open-telemetry/semantic-conventions/pull/374)) +- BREAKING: Define url.scheme in terms of logical operation in HTTP server semconv. + ([#376](https://github.com/open-telemetry/semantic-conventions/pull/376)) ### Features diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 2da82c97d6..d2a73412f3 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -84,7 +84,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -142,6 +142,8 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + `error.type` 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 | @@ -263,7 +265,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -321,6 +323,8 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + `error.type` 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 | @@ -368,7 +372,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -426,6 +430,8 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + `error.type` 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 | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index a5e74fdd29..e69d4d5429 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -378,7 +378,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | | [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. @@ -410,6 +410,8 @@ SHOULD NOT be set if only IP address is available and capturing name would requi **[8]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: * [`server.address`](../general/attributes.md) diff --git a/model/http-common.yaml b/model/http-common.yaml index 921f3f1e3a..a348aa4147 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -100,3 +100,9 @@ groups: - ref: url.scheme requirement_level: required examples: ["http", "https"] + note: > + The scheme of the original client request, if known + (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), + [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), + or a similar header). + Otherwise, the scheme of the immediate peer request. From 7680dc8bee42bcea1caec9cbf1934f72b5c94f87 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 17 Oct 2023 04:36:41 -0700 Subject: [PATCH 088/482] Change `network.transport` from recommended to opt-in in the HTTP semconv (#402) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 14 ++++---------- model/trace/http.yaml | 6 ++++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d687b6268..54c1a3aa1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ release. ([#374](https://github.com/open-telemetry/semantic-conventions/pull/374)) - BREAKING: Define url.scheme in terms of logical operation in HTTP server semconv. ([#376](https://github.com/open-telemetry/semantic-conventions/pull/376)) +- BREAKING: Change `network.transport` from recommended to opt-in in HTTP semconv. + ([#402](https://github.com/open-telemetry/semantic-conventions/pull/402)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index e69d4d5429..7ea0395d72 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -125,8 +125,8 @@ sections below. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Conditionally Required: [9] | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [10] | `ipv4`; `ipv6` | Recommended | +| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | +| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [9] | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | **[1]:** If the request fails with an error before response status code was sent or received, @@ -175,15 +175,9 @@ The attribute value MUST consist of either multiple header values as an array of **[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[8]:** The value SHOULD be normalized to lowercase. +**[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example -different processes could be listening on TCP port 12345 and UDP port 12345. - -**[9]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). - -**[10]:** The value SHOULD be normalized to lowercase. +**[9]:** The value SHOULD be normalized to lowercase. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/model/trace/http.yaml b/model/trace/http.yaml index c0cfdaf71c..5038f604d1 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -20,8 +20,10 @@ groups: sampling_relevant: true requirement_level: required - ref: network.transport - requirement_level: - conditionally_required: If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`). + requirement_level: opt_in + note: > + Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. + Other obscure implementations are possible. - ref: network.type - ref: user_agent.original From 242268e905bf4a8f790db9847fad2b0843594ff2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 17 Oct 2023 07:45:21 -0700 Subject: [PATCH 089/482] Add cardinality warning about two opt-in HTTP metric attributes to all HTTP metrics. (#412) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 18 ++++++++++++++++++ model/metrics/http.yaml | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54c1a3aa1e..36135059f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ release. ([#401](https://github.com/open-telemetry/semantic-conventions/pull/401)) - Change `server.port` from recommended to conditionally required on HTTP server semconv. ([#399](https://github.com/open-telemetry/semantic-conventions/pull/399)) +- Add cardinality warning about two opt-in HTTP metric attributes to all HTTP metrics. + ([#412](https://github.com/open-telemetry/semantic-conventions/pull/412)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index d2a73412f3..1aa35b7e03 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -135,6 +135,9 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. @@ -142,6 +145,9 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -316,6 +322,9 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. @@ -323,6 +332,9 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -423,6 +435,9 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin SHOULD NOT be set if only IP address is available and capturing name would require a reverse DNS lookup. +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[7]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. @@ -430,6 +445,9 @@ SHOULD NOT be set if only IP address is available and capturing name would requi if it's sent in absolute-form. - Port identifier of the `Host` header +Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +to trigger cardinality limits, degrading the usefulness of the metric. + **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 2596a06f08..474c99fa75 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -6,8 +6,32 @@ groups: attributes: - ref: server.address requirement_level: opt_in + note: | + Determined by using the first of the following that applies + + - The [primary server name](/docs/http/http-spans.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. + + Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + to trigger cardinality limits, degrading the usefulness of the metric. + - ref: server.port requirement_level: opt_in + note: | + Determined by using the first of the following that applies + + - Port identifier of the [primary server host](/docs/http/http-spans.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 + + Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + to trigger cardinality limits, degrading the usefulness of the metric. - id: metric_attributes.http.client type: attribute_group From 3408678411353146b61c83d19f6b6ee6c4f17a61 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 17 Oct 2023 09:16:53 -0700 Subject: [PATCH 090/482] Remove `network.type` from HTTP semconv (changing it from recommended to opt-in) (#410) --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 10 ---------- model/trace/http.yaml | 1 - 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36135059f5..a4e54be2f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ release. ([#376](https://github.com/open-telemetry/semantic-conventions/pull/376)) - BREAKING: Change `network.transport` from recommended to opt-in in HTTP semconv. ([#402](https://github.com/open-telemetry/semantic-conventions/pull/402)) +- BREAKING: Change `network.type` from recommended to opt-in in HTTP semconv. + ([#410](https://github.com/open-telemetry/semantic-conventions/pull/410)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 7ea0395d72..d23527e2e6 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -126,7 +126,6 @@ sections below. | [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [9] | `ipv4`; `ipv6` | Recommended | | `user_agent.original` | 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 | **[1]:** If the request fails with an error before response status code was sent or received, @@ -177,8 +176,6 @@ The attribute value MUST consist of either multiple header values as an array of **[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. -**[9]:** The value SHOULD be normalized to lowercase. - Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: * [`http.request.method`](../attributes-registry/http.md) @@ -212,13 +209,6 @@ Following attributes MUST be provided **at span creation time** (when provided a | `udp` | UDP | | `pipe` | Named or anonymous pipe. See note below. | | `unix` | Unix domain socket | - -`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | ## HTTP client diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 5038f604d1..599b1075f7 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -24,7 +24,6 @@ groups: note: > Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. - - ref: network.type - ref: user_agent.original - id: trace.http.client From 67e5c98236076d6348a8ce79a3e29b15fa95e204 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 17 Oct 2023 20:19:09 -0700 Subject: [PATCH 091/482] Change `network.protocol.name` from recommended to opt-in in the HTTP semconv (#398) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 12 ++++++------ docs/http/http-spans.md | 2 +- model/http-common.yaml | 3 +-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e54be2f1..242003efd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ release. - BREAKING: Rename http.resend_count to http.request.resend_count. ([#374](https://github.com/open-telemetry/semantic-conventions/pull/374)) +- BREAKING: Change `network.protocol.name` from recommended to opt-in in HTTP semconv. + ([#398](https://github.com/open-telemetry/semantic-conventions/pull/398)) - BREAKING: Define url.scheme in terms of logical operation in HTTP server semconv. ([#376](https://github.com/open-telemetry/semantic-conventions/pull/376)) - BREAKING: Change `network.transport` from recommended to opt-in in HTTP semconv. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 1aa35b7e03..3faf208c12 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -80,7 +80,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | @@ -267,7 +267,7 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | @@ -380,7 +380,7 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | @@ -498,7 +498,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | @@ -595,7 +595,7 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | @@ -692,7 +692,7 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index d23527e2e6..4ef9bee100 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -123,7 +123,7 @@ sections below. | [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Recommended: if not default (`http`). | +| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | | `user_agent.original` | 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 | diff --git a/model/http-common.yaml b/model/http-common.yaml index a348aa4147..94ca81263c 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -31,8 +31,7 @@ groups: If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: network.protocol.name examples: ['http', 'spdy'] - requirement_level: - recommended: if not default (`http`). + requirement_level: opt_in - ref: network.protocol.version examples: ['1.0', '1.1', '2', '3'] From d75bb844c6a0cd40b669afbcb8a130db167a87aa Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 18 Oct 2023 02:56:27 -0700 Subject: [PATCH 092/482] Remove outdated note about not recording HTTP `server.address` when only IP address available (#413) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 8 -------- docs/http/http-spans.md | 2 -- model/http-common.yaml | 2 -- model/metrics/http.yaml | 4 ---- 5 files changed, 2 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 242003efd7..b4e3309a23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ release. ([#399](https://github.com/open-telemetry/semantic-conventions/pull/399)) - Add cardinality warning about two opt-in HTTP metric attributes to all HTTP metrics. ([#412](https://github.com/open-telemetry/semantic-conventions/pull/412)) +- Remove outdated note about not recording HTTP `server.address` when only IP address available. + ([#413](https://github.com/open-telemetry/semantic-conventions/pull/413)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 3faf208c12..e48fe99cb3 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -133,8 +133,6 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -215,8 +213,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -320,8 +316,6 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -433,8 +427,6 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 4ef9bee100..fbb25146fc 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -379,8 +379,6 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin 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. - **[5]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. diff --git a/model/http-common.yaml b/model/http-common.yaml index 94ca81263c..e87556fb96 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -82,8 +82,6 @@ groups: 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: server.port brief: > Port of the local HTTP server that received the request. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 474c99fa75..2cf9271775 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -15,8 +15,6 @@ groups: 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -74,8 +72,6 @@ groups: 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. - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. From a09cbef18bd413070c7a25636231328d34a93956 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 18 Oct 2023 12:59:44 +0200 Subject: [PATCH 093/482] Move url to the registry (#400) Co-authored-by: Joao Grassi --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/url.md | 24 +++++++++++++++++++ docs/database/elasticsearch.md | 2 +- docs/http/http-metrics.md | 14 +++++------ docs/http/http-spans.md | 16 ++++++------- docs/url/url.md | 10 ++++---- model/registry/url.yaml | 37 ++++++++++++++++++++++++++++++ model/url.yaml | 36 ++++------------------------- 8 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 docs/attributes-registry/url.md create mode 100644 model/registry/url.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 3cc895fc7a..f1efd2ca7c 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -28,5 +28,6 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: * [HTTP](http.md) +* [URL](url.md) [developers recommendations]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md new file mode 100644 index 0000000000..60f99ea205 --- /dev/null +++ b/docs/attributes-registry/url.md @@ -0,0 +1,24 @@ + +# URL + +## URL Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | +| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | + +**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +**[2]:** When missing, the value is assumed to be `/` + +**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + \ No newline at end of file diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 74e956557f..2cbbd713d5 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -34,7 +34,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | | [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e48fe99cb3..b78f54ae40 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -84,7 +84,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -188,7 +188,7 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -267,7 +267,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -378,7 +378,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -494,7 +494,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -591,7 +591,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -688,7 +688,7 @@ This metric is optional. | [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index fbb25146fc..b5b3a4c454 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -233,7 +233,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.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] | -| [`url.full`](../url/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | **[1]:** 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). @@ -258,7 +258,7 @@ Following attributes MUST be provided **at span creation time** (when provided a * [`server.address`](../general/attributes.md) * [`server.port`](../general/attributes.md) -* [`url.full`](../url/url.md) +* [`url.full`](../attributes-registry/url.md) Note that in some cases host and port identifiers in the `Host` header might be different from the `server.address` and `server.port`, in this case instrumentation MAY populate `Host` header on `http.request.header.host` attribute even if it's not enabled by user. @@ -360,9 +360,9 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | -| [`url.path`](../url/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | -| [`url.query`](../url/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../url/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. @@ -398,9 +398,9 @@ Following attributes MUST be provided **at span creation time** (when provided a * [`server.address`](../general/attributes.md) * [`server.port`](../general/attributes.md) -* [`url.path`](../url/url.md) -* [`url.query`](../url/url.md) -* [`url.scheme`](../url/url.md) +* [`url.path`](../attributes-registry/url.md) +* [`url.query`](../attributes-registry/url.md) +* [`url.scheme`](../attributes-registry/url.md) `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. diff --git a/docs/url/url.md b/docs/url/url.md index 0b8cc15980..e337f68a37 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -25,11 +25,11 @@ This document defines semantic conventions that describe URL and its components. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | -| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | +| [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. diff --git a/model/registry/url.yaml b/model/registry/url.yaml new file mode 100644 index 0000000000..7443e87919 --- /dev/null +++ b/model/registry/url.yaml @@ -0,0 +1,37 @@ +groups: + - id: registry.url + brief: Attributes describing URL. + type: attribute_group + prefix: url + attributes: + - id: scheme + type: string + brief: 'The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.' + examples: ["https", "ftp", "telnet"] + - id: full + type: string + brief: Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + note: > + For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment + is not transmitted over HTTP, but if it is known, it should be included nevertheless. + + `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. + In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. + + `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) + and SHOULD NOT be validated or modified except for sanitizing purposes. + examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] + - id: path + type: string + brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' + examples: ['/search'] + note: When missing, the value is assumed to be `/` + - id: query + type: string + brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' + examples: ["q=OpenTelemetry"] + note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + - id: fragment + type: string + brief: 'The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component' + examples: ["SemConv"] diff --git a/model/url.yaml b/model/url.yaml index 6e839fc394..bb27dc4e6d 100644 --- a/model/url.yaml +++ b/model/url.yaml @@ -4,36 +4,10 @@ groups: type: attribute_group prefix: url attributes: - - id: scheme - type: string - brief: 'The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.' - examples: ["https", "ftp", "telnet"] - - id: full - type: string - brief: Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) - note: > - For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment - is not transmitted over HTTP, but if it is known, it should be included nevertheless. - - `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. - In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. - - `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) - and SHOULD NOT be validated or modified except for sanitizing purposes. - examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] + - ref: url.scheme + - ref: url.full tag: sensitive-information - - id: path - type: string - brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' - examples: ['/search'] - note: When missing, the value is assumed to be `/` - - id: query - type: string - brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' - examples: ["q=OpenTelemetry"] - note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + - ref: url.path + - ref: url.query tag: sensitive-information - - id: fragment - type: string - brief: 'The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component' - examples: ["SemConv"] + - ref: url.fragment From 7700f5d1c8eea1f603d86c7646d38bb304f2597a Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 18 Oct 2023 07:47:29 -0700 Subject: [PATCH 094/482] Metric namespaces should not be pluralized (#267) Co-authored-by: Josh Suereth Co-authored-by: Armin Ruech --- CHANGELOG.md | 3 +++ docs/general/metrics.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e3309a23..c4a3b141e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,9 @@ release. ### Features +- Metric namespaces SHOULD NOT be pluralized. + ([#267](https://github.com/open-telemetry/opentelemetry-specification/pull/267)) + ### Fixes - Clarify that `error.type` should be the fully-qualified exception class name diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 6defc732af..c5446df657 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -105,6 +105,8 @@ using the OpenMetrics exposition format, use the #### Pluralization +Metric namespaces SHOULD NOT be pluralized. + Metric names SHOULD NOT be pluralized, unless the value being recorded represents discrete instances of a [countable quantity](https://en.wikipedia.org/wiki/Count_noun). From aebcb07995da21df5702a3089ec6076f6865d6dc Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 18 Oct 2023 11:45:51 -0400 Subject: [PATCH 095/482] [editorial] Advisory parameter anchor name fix (#420) Co-authored-by: Joao Grassi --- docs/http/http-metrics.md | 4 ++-- docs/runtime/jvm-metrics.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index b78f54ae40..d48017ec81 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -64,7 +64,7 @@ This metric is required. When this metric is reported alongside an HTTP server span, the metric value SHOULD be the same as the HTTP server span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -475,7 +475,7 @@ This metric is required. When this metric is reported alongside an HTTP client span, the metric value SHOULD be the same as the HTTP client span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index a5d656ba5c..2ec4231fc9 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -162,7 +162,7 @@ This metric is obtained by subscribing to [`GarbageCollectionNotificationInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html) events provided by [`GarbageCollectorMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/GarbageCollectorMXBean.html). The duration value is obtained from [`GcInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GcInfo.html#getDuration--) This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[]` (single bucket histogram capturing count, sum, min, max). From 965c10897de90056b66bad6cb90c4e5427c9de30 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 18 Oct 2023 23:50:11 -0700 Subject: [PATCH 096/482] Factor in `X-Forwarded-Host` / `Forwarded` when capturing `server.address` and `server.port` (#411) --- CHANGELOG.md | 2 ++ docs/http/http-metrics.md | 52 +++++++++++++++++++++++++++------------ docs/http/http-spans.md | 9 +++++-- model/http-common.yaml | 9 +++++-- model/metrics/http.yaml | 26 ++++++++++++++------ 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a3b141e2..12342a0a8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ release. ([#402](https://github.com/open-telemetry/semantic-conventions/pull/402)) - BREAKING: Change `network.type` from recommended to opt-in in HTTP semconv. ([#410](https://github.com/open-telemetry/semantic-conventions/pull/410)) +- BREAKING: Factor in `X-Forwarded-Host` / `Forwarded` when capturing `server.address` and `server.port`. + ([#411](https://github.com/open-telemetry/semantic-conventions/pull/411)) ### Features diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index d48017ec81..f08a313b63 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -127,13 +127,16 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** Determined by using the first of the following that applies -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. +- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +MUST NOT include the port identifier. + +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** Determined by using the first of the following that applies @@ -141,9 +144,11 @@ to trigger cardinality limits, degrading the usefulness of the metric. - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -207,13 +212,16 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[2]:** Determined by using the first of the following that applies -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. +- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +MUST NOT include the port identifier. + +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[3]:** Determined by using the first of the following that applies @@ -221,9 +229,11 @@ to trigger cardinality limits, degrading the usefulness of the metric. - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. `http.request.method` 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. @@ -310,13 +320,16 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** Determined by using the first of the following that applies -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. +- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +MUST NOT include the port identifier. + +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** Determined by using the first of the following that applies @@ -324,9 +337,11 @@ to trigger cardinality limits, degrading the usefulness of the metric. - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -421,13 +436,16 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** Determined by using the first of the following that applies -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. +- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +MUST NOT include the port identifier. + +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** Determined by using the first of the following that applies @@ -435,9 +453,11 @@ to trigger cardinality limits, degrading the usefulness of the metric. - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header -Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker +Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index b5b3a4c454..c062ff8351 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -373,17 +373,22 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** Determined by using the first of the following that applies -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. +- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header +MUST NOT include the port identifier. + **[5]:** Determined by using the first of the following that applies - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header **[6]:** If not default (`80` for `http` scheme, `443` for `https`). diff --git a/model/http-common.yaml b/model/http-common.yaml index e87556fb96..dfee35a62e 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -76,12 +76,15 @@ groups: note: | Determined by using the first of the following that applies - - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. + - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header + MUST NOT include the port identifier. + - ref: server.port brief: > Port of the local HTTP server that received the request. @@ -91,6 +94,8 @@ groups: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header requirement_level: conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 2cf9271775..22467fcd2a 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -9,13 +9,16 @@ groups: note: | Determined by using the first of the following that applies - - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. + - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + MUST NOT include the port identifier. + + Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port @@ -26,9 +29,11 @@ groups: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. - id: metric_attributes.http.client @@ -66,13 +71,16 @@ groups: note: | Determined by using the first of the following that applies - - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. MUST only - include host identifier. + - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Host identifier of the `Host` header - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + MUST NOT include the port identifier. + + Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port @@ -85,9 +93,11 @@ groups: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header - Warning: since this attribute may be based on the `Host` header, opting in to it may allow an attacker + Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. - id: metric.http.server.request.body.size From 315a4290fb13e18306638ebbb99464954888f5ae Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 19 Oct 2023 14:16:04 +0200 Subject: [PATCH 097/482] Moved network attributes to the registry (#390) --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/network.md | 131 +++++++++++++ docs/database/database-spans.md | 8 +- docs/general/attributes.md | 32 ++-- docs/http/http-metrics.md | 24 +-- docs/http/http-spans.md | 18 +- docs/messaging/messaging-spans.md | 12 +- docs/rpc/rpc-metrics.md | 4 +- docs/rpc/rpc-spans.md | 16 +- docs/system/system-metrics.md | 2 +- model/network.yaml | 185 ++----------------- model/{ => registry}/deprecated/network.yaml | 0 model/registry/network.yaml | 176 ++++++++++++++++++ 13 files changed, 381 insertions(+), 228 deletions(-) create mode 100644 docs/attributes-registry/network.md rename model/{ => registry}/deprecated/network.yaml (100%) create mode 100644 model/registry/network.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index f1efd2ca7c..d74037305b 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -28,6 +28,7 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: * [HTTP](http.md) +* [Network](network.md) * [URL](url.md) [developers recommendations]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md new file mode 100644 index 0000000000..5d4b9fdd0d --- /dev/null +++ b/docs/attributes-registry/network.md @@ -0,0 +1,131 @@ + + +# Network + +These attributes may be used for any network related operation. + +## Network Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | +| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | +| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | +| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | +| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | +| `network.connection.type` | string | The internet connection type. | `wifi` | +| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | +| `network.local.port` | int | Local port number of the network connection. | `65123` | +| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | +| `network.peer.port` | int | Peer port number of the network connection. | `65123` | +| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | +| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | +| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | + +**[1]:** The value SHOULD be normalized to lowercase. + +**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[3]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport, for example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[4]:** The value SHOULD be normalized to lowercase. + +`network.connection.subtype` 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 | +|---|---| +| `gprs` | GPRS | +| `edge` | EDGE | +| `umts` | UMTS | +| `cdma` | CDMA | +| `evdo_0` | EVDO Rel. 0 | +| `evdo_a` | EVDO Rev. A | +| `cdma2000_1xrtt` | CDMA2000 1XRTT | +| `hsdpa` | HSDPA | +| `hsupa` | HSUPA | +| `hspa` | HSPA | +| `iden` | IDEN | +| `evdo_b` | EVDO Rev. B | +| `lte` | LTE | +| `ehrpd` | EHRPD | +| `hspap` | HSPAP | +| `gsm` | GSM | +| `td_scdma` | TD-SCDMA | +| `iwlan` | IWLAN | +| `nr` | 5G NR (New Radio) | +| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | +| `lte_ca` | LTE CA | + +`network.connection.type` 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 | +|---|---| +| `wifi` | wifi | +| `wired` | wired | +| `cell` | cell | +| `unavailable` | unavailable | +| `unknown` | unknown | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. See note below. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Deprecated Network Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | +| `net.host.port` | int | Deprecated, use `server.port`. | `8080` | +| `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | +| `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | +| `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | +| `net.protocol.version` | string | Deprecated, use `network.protocol.version`. | `3.1.1` | +| `net.sock.family` | string | Deprecated, use `network.transport` and `network.type`. | `inet` | +| `net.sock.host.addr` | string | Deprecated, use `network.local.address`. | `/var/my.sock` | +| `net.sock.host.port` | int | Deprecated, use `network.local.port`. | `8080` | +| `net.sock.peer.addr` | string | Deprecated, use `network.peer.address`. | `192.168.0.1` | +| `net.sock.peer.name` | string | Deprecated, no replacement at this time. | `/var/my.sock` | +| `net.sock.peer.port` | int | Deprecated, use `network.peer.port`. | `65531` | +| `net.transport` | string | Deprecated, use `network.transport`. | `ip_tcp` | + +`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 | + +`net.transport` 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 | +|---|---| +| `ip_tcp` | ip_tcp | +| `ip_udp` | ip_udp | +| `pipe` | Named or anonymous pipe. | +| `inproc` | In-process communication. [1] | +| `other` | Something else (non IP-based). | + +**[1]:** Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. + diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index cc995d3d37..a4873f17e6 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,10 +67,10 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 6a8793df65..c70eb3c13d 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -157,17 +157,17 @@ Destination fields capture details about the receiver of a network exchange/pack Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed if they do not cause breaking changes to HTTP semantic conventions. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `network.local.port` | int | Local port number of the network connection. | `65123` | Recommended | -| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `network.peer.port` | int | Peer port number of the network connection. | `65123` | Recommended | -| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | -| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | -| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | -| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | +| [`network.local.address`](../attributes-registry/network.md) | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.local.port`](../attributes-registry/network.md) | int | Local port number of the network connection. | `65123` | Recommended | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. @@ -239,15 +239,15 @@ Note that `network.local.*` attributes are not included in these examples since #### Network connection and carrier attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | Recommended | -| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | Recommended | -| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | Recommended | -| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | Recommended | -| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | Recommended | -| `network.connection.type` | string | The internet connection type. | `wifi` | Recommended | +| [`network.carrier.icc`](../attributes-registry/network.md) | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | Recommended | +| [`network.carrier.mcc`](../attributes-registry/network.md) | string | The mobile carrier country code. | `310` | Recommended | +| [`network.carrier.mnc`](../attributes-registry/network.md) | string | The mobile carrier network code. | `001` | Recommended | +| [`network.carrier.name`](../attributes-registry/network.md) | string | The name of the mobile carrier. | `sprint` | Recommended | +| [`network.connection.subtype`](../attributes-registry/network.md) | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | Recommended | +| [`network.connection.type`](../attributes-registry/network.md) | string | The internet connection type. | `wifi` | Recommended | `network.connection.subtype` 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. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index f08a313b63..750ab3a1ae 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -80,8 +80,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | @@ -273,8 +273,8 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | @@ -389,8 +389,8 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | @@ -510,8 +510,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -607,8 +607,8 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | @@ -704,8 +704,8 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index c062ff8351..46caf107a2 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -123,9 +123,9 @@ sections below. | [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | | `user_agent.original` | 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 | **[1]:** If the request fails with an error before response status code was sent or received, @@ -229,8 +229,8 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.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] | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | @@ -354,10 +354,10 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | | [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | | [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.local.address`](../general/attributes.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`network.local.port`](../general/attributes.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended | +| [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 388ec90b03..381910424f 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -229,12 +229,12 @@ The following operations related to messages are defined for these semantic conv | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | | `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [15] | `publish` | Required | | `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../general/attributes.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../general/attributes.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index f9994db859..23ed667528 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -220,8 +220,8 @@ measurements. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index eb1a9a9298..995e5918d9 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -85,8 +85,8 @@ Examples of span names: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | @@ -142,8 +142,8 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | ### Server attributes @@ -153,10 +153,10 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | -| [`network.peer.address`](../general/attributes.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `client.address`. | -| [`network.peer.port`](../general/attributes.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | -| [`network.type`](../general/attributes.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `client.address`. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index c92dff04e5..bd3957fc21 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -643,7 +643,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../general/attributes.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | | `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | diff --git a/model/network.yaml b/model/network.yaml index 2652a2fd1b..7e1ee396f6 100644 --- a/model/network.yaml +++ b/model/network.yaml @@ -3,76 +3,16 @@ groups: prefix: network type: attribute_group brief: > - These attributes may be used for any network related operation. + These attributes may be used for any network related operation. attributes: - - id: transport - type: - allow_custom_values: true - members: - - id: tcp - value: 'tcp' - brief: "TCP" - - id: udp - value: 'udp' - brief: "UDP" - - id: pipe - value: "pipe" - brief: 'Named or anonymous pipe. See note below.' - - id: unix - value: 'unix' - brief: "Unix domain socket" - brief: > - [OSI transport layer](https://osi-model.com/transport-layer/) or - [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). - note: | - The value SHOULD be normalized to lowercase. - - Consider always setting the transport when setting a port number, since - a port number is ambiguous without knowing the transport, for example - different processes could be listening on TCP port 12345 and UDP port 12345. - examples: ['tcp', 'udp'] - - id: type - type: - allow_custom_values: true - members: - - id: ipv4 - value: 'ipv4' - brief: "IPv4" - - id: ipv6 - value: 'ipv6' - brief: "IPv6" - brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' - note: The value SHOULD be normalized to lowercase. - examples: ['ipv4', 'ipv6'] - - id: protocol.name - type: string - brief: '[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.' - note: The value SHOULD be normalized to lowercase. - examples: ['amqp', 'http', 'mqtt'] - - id: protocol.version - type: string - brief: Version of the protocol specified in `network.protocol.name`. - examples: '3.1.1' - note: > - `network.protocol.version` refers to the version of the protocol used and might be - different from the protocol client's version. If the HTTP client used has a version - of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - - id: peer.address - type: string - brief: Peer address of the network connection - IP address or Unix domain socket name. - examples: ['10.1.2.80', '/tmp/my.sock'] - - id: peer.port - type: int - brief: Peer port number of the network connection. - examples: [65123] - - id: local.address - type: string - brief: Local address of the network connection - IP address or Unix domain socket name. - examples: ['10.1.2.80', '/tmp/my.sock'] - - id: local.port - type: int - brief: Local port number of the network connection. - examples: [65123] + - ref: network.transport + - ref: network.type + - ref: network.protocol.name + - ref: network.protocol.version + - ref: network.peer.address + - ref: network.peer.port + - ref: network.local.address + - ref: network.local.port - id: network-connection-and-carrier prefix: network @@ -80,104 +20,9 @@ groups: brief: > These attributes may be used for any network related operation. attributes: - - id: connection.type - type: - allow_custom_values: true - members: - - id: wifi - value: "wifi" - - id: wired - value: "wired" - - id: cell - value: "cell" - - id: unavailable - value: "unavailable" - - id: unknown - value: "unknown" - brief: 'The internet connection type.' - examples: 'wifi' - - id: connection.subtype - type: - allow_custom_values: true - members: - - id: gprs - brief: GPRS - value: "gprs" - - id: edge - brief: EDGE - value: "edge" - - id: umts - brief: UMTS - value: "umts" - - id: cdma - brief: CDMA - value: "cdma" - - id: evdo_0 - brief: EVDO Rel. 0 - value: "evdo_0" - - id: evdo_a - brief: "EVDO Rev. A" - value: "evdo_a" - - id: cdma2000_1xrtt - brief: CDMA2000 1XRTT - value: "cdma2000_1xrtt" - - id: hsdpa - brief: HSDPA - value: "hsdpa" - - id: hsupa - brief: HSUPA - value: "hsupa" - - id: hspa - brief: HSPA - value: "hspa" - - id: iden - brief: IDEN - value: "iden" - - id: evdo_b - brief: "EVDO Rev. B" - value: "evdo_b" - - id: lte - brief: LTE - value: "lte" - - id: ehrpd - brief: EHRPD - value: "ehrpd" - - id: hspap - brief: HSPAP - value: "hspap" - - id: gsm - brief: GSM - value: "gsm" - - id: td_scdma - brief: TD-SCDMA - value: "td_scdma" - - id: iwlan - brief: IWLAN - value: "iwlan" - - id: nr - brief: "5G NR (New Radio)" - value: "nr" - - id: nrnsa - brief: "5G NRNSA (New Radio Non-Standalone)" - value: "nrnsa" - - id: lte_ca - brief: LTE CA - value: "lte_ca" - brief: 'This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.' - examples: 'LTE' - - id: carrier.name - type: string - brief: "The name of the mobile carrier." - examples: "sprint" - - id: carrier.mcc - type: string - brief: "The mobile carrier country code." - examples: "310" - - id: carrier.mnc - type: string - brief: "The mobile carrier network code." - examples: "001" - - id: carrier.icc - type: string - brief: "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network." - examples: "DE" + - ref: network.connection.type + - ref: network.connection.subtype + - ref: network.carrier.name + - ref: network.carrier.mcc + - ref: network.carrier.mnc + - ref: network.carrier.icc diff --git a/model/deprecated/network.yaml b/model/registry/deprecated/network.yaml similarity index 100% rename from model/deprecated/network.yaml rename to model/registry/deprecated/network.yaml diff --git a/model/registry/network.yaml b/model/registry/network.yaml new file mode 100644 index 0000000000..698b9d89f7 --- /dev/null +++ b/model/registry/network.yaml @@ -0,0 +1,176 @@ +groups: + - id: registry.network + prefix: network + type: attribute_group + brief: > + These attributes may be used for any network related operation. + attributes: + - id: carrier.icc + type: string + brief: "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network." + examples: "DE" + - id: carrier.mcc + type: string + brief: "The mobile carrier country code." + examples: "310" + - id: carrier.mnc + type: string + brief: "The mobile carrier network code." + examples: "001" + - id: carrier.name + type: string + brief: "The name of the mobile carrier." + examples: "sprint" + - id: connection.subtype + type: + allow_custom_values: true + members: + - id: gprs + brief: GPRS + value: "gprs" + - id: edge + brief: EDGE + value: "edge" + - id: umts + brief: UMTS + value: "umts" + - id: cdma + brief: CDMA + value: "cdma" + - id: evdo_0 + brief: EVDO Rel. 0 + value: "evdo_0" + - id: evdo_a + brief: "EVDO Rev. A" + value: "evdo_a" + - id: cdma2000_1xrtt + brief: CDMA2000 1XRTT + value: "cdma2000_1xrtt" + - id: hsdpa + brief: HSDPA + value: "hsdpa" + - id: hsupa + brief: HSUPA + value: "hsupa" + - id: hspa + brief: HSPA + value: "hspa" + - id: iden + brief: IDEN + value: "iden" + - id: evdo_b + brief: "EVDO Rev. B" + value: "evdo_b" + - id: lte + brief: LTE + value: "lte" + - id: ehrpd + brief: EHRPD + value: "ehrpd" + - id: hspap + brief: HSPAP + value: "hspap" + - id: gsm + brief: GSM + value: "gsm" + - id: td_scdma + brief: TD-SCDMA + value: "td_scdma" + - id: iwlan + brief: IWLAN + value: "iwlan" + - id: nr + brief: "5G NR (New Radio)" + value: "nr" + - id: nrnsa + brief: "5G NRNSA (New Radio Non-Standalone)" + value: "nrnsa" + - id: lte_ca + brief: LTE CA + value: "lte_ca" + brief: 'This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.' + examples: 'LTE' + - id: connection.type + type: + allow_custom_values: true + members: + - id: wifi + value: "wifi" + - id: wired + value: "wired" + - id: cell + value: "cell" + - id: unavailable + value: "unavailable" + - id: unknown + value: "unknown" + brief: 'The internet connection type.' + examples: 'wifi' + - id: local.address + type: string + brief: Local address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: local.port + type: int + brief: Local port number of the network connection. + examples: [65123] + - id: peer.address + type: string + brief: Peer address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: peer.port + type: int + brief: Peer port number of the network connection. + examples: [65123] + - id: protocol.name + type: string + brief: '[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. + examples: ['amqp', 'http', 'mqtt'] + - id: protocol.version + type: string + brief: Version of the protocol specified in `network.protocol.name`. + examples: '3.1.1' + note: > + `network.protocol.version` refers to the version of the protocol used and might be + different from the protocol client's version. If the HTTP client used has a version + of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + - id: transport + type: + allow_custom_values: true + members: + - id: tcp + value: 'tcp' + brief: "TCP" + - id: udp + value: 'udp' + brief: "UDP" + - id: pipe + value: "pipe" + brief: 'Named or anonymous pipe. See note below.' + - id: unix + value: 'unix' + brief: "Unix domain socket" + brief: > + [OSI transport layer](https://osi-model.com/transport-layer/) or + [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). + note: | + The value SHOULD be normalized to lowercase. + + Consider always setting the transport when setting a port number, since + a port number is ambiguous without knowing the transport, for example + different processes could be listening on TCP port 12345 and UDP port 12345. + examples: ['tcp', 'udp'] + - id: type + type: + allow_custom_values: true + members: + - id: ipv4 + value: 'ipv4' + brief: "IPv4" + - id: ipv6 + value: 'ipv6' + brief: "IPv6" + brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. + examples: ['ipv4', 'ipv6'] From e0767b2b7e851bb445bddb27a553443262e5100c Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Thu, 19 Oct 2023 16:07:32 +0200 Subject: [PATCH 098/482] Revert to old `linkTitle` on runtime readme (#428) --- docs/runtime/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/runtime/README.md b/docs/runtime/README.md index bc6f2c9b75..24d221e3b6 100644 --- a/docs/runtime/README.md +++ b/docs/runtime/README.md @@ -1,5 +1,5 @@ # Semantic Conventions for Runtime Environment From 86f1ba452bbd11af0a9cd1b431f9490e81464fad Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 19 Oct 2023 16:53:57 -0700 Subject: [PATCH 099/482] Editorial: random improvements (#415) --- .github/CODEOWNERS | 8 +- docs/attributes-registry/README.md | 2 +- docs/attributes-registry/http.md | 2 +- docs/attributes-registry/network.md | 8 +- docs/cloudevents/cloudevents-spans.md | 2 +- docs/database/database-metrics.md | 18 +-- docs/database/database-spans.md | 9 +- docs/database/elasticsearch.md | 5 +- docs/database/mssql.md | 2 +- docs/exceptions/exceptions-spans.md | 2 +- docs/faas/faas-spans.md | 6 +- docs/general/attributes.md | 31 +++-- docs/general/events.md | 3 +- docs/general/metrics.md | 4 +- docs/general/trace-compatibility.md | 2 +- docs/general/trace.md | 2 +- docs/http/http-metrics.md | 127 ++++++++++----------- docs/http/http-spans.md | 47 ++++---- docs/messaging/messaging-spans.md | 12 +- docs/resource/cloud.md | 6 +- docs/resource/deployment-environment.md | 2 +- docs/resource/faas.md | 4 +- docs/resource/k8s.md | 2 +- docs/rpc/json-rpc.md | 2 +- docs/rpc/rpc-metrics.md | 13 +-- docs/rpc/rpc-spans.md | 16 +-- docs/system/hardware-metrics.md | 2 +- docs/system/system-metrics.md | 18 +-- model/client.yaml | 8 +- model/destination.yaml | 6 +- model/error.yaml | 13 ++- model/http-common.yaml | 29 +++-- model/logs/events.yaml | 2 +- model/metrics/database-metrics.yaml | 2 +- model/metrics/http.yaml | 32 +++--- model/metrics/system-metrics.yaml | 10 +- model/registry/http.yaml | 2 +- model/registry/network.yaml | 8 +- model/resource/cloud.yaml | 6 +- model/resource/deployment_environment.yaml | 2 +- model/resource/k8s.yaml | 2 +- model/server.yaml | 10 +- model/source.yaml | 6 +- model/trace/compatibility.yaml | 4 +- model/trace/database.yaml | 2 +- model/trace/exporter/exporter.yaml | 2 +- model/trace/http.yaml | 6 +- model/trace/messaging.yaml | 4 +- model/trace/rpc.yaml | 2 +- 49 files changed, 253 insertions(+), 262 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f541bc6faa..8210e3eff6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,13 +6,13 @@ # # Learn about membership in OpenTelemetry community: # https://github.com/open-telemetry/community/blob/main/community-membership.md -# # -# Learn about CODEOWNERS file format: -# https://help.github.com/en/articles/about-code-owners +# +# Learn about CODEOWNERS file format: +# https://help.github.com/articles/about-code-owners # -# Global owners, will be the owners for everything in the repo. Membership is tracked via https://github.com/open-telemetry/community/blob/main/community-members.md +# Global owners, will be the owners for everything in the repo. Membership is tracked via https://github.com/open-telemetry/community/blob/main/community-members.md * @open-telemetry/specs-semconv-maintainers @open-telemetry/specs-semconv-approvers # Schemas and schema file tooling diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index d74037305b..ad8f844a8a 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -14,7 +14,7 @@ The attributes registry is the place where attributes are defined. An attribute Attributes defined in the registry can be used in different semantic conventions. Attributes should be included in this registry before they are used in semantic conventions. Semantic conventions may override all the properties of an attribute except for the `id` and `type` in case it's required for a particular context. In addition, semantic conventions specify the requirement level of an attribute in the corresponding context. -A definition of an attribute in the registry does not necessarily imply that the attribute is used in any of the semantic conventions. +A definition of an attribute in the registry doesn't necessarily imply that the attribute is used in any of the semantic conventions. If applicable, application developers are encouraged to use existing attributes from this registry. See also [these recommendations][developers recommendations] regarding attribute selection and attribute naming for custom use cases. diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 7f8602c372..f80783cafa 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -16,7 +16,7 @@ | `http.response.body.size` | 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` | | `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [4] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | | `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | -| `http.route` | string | The matched route (path template in the format used by the respective server framework). See note below [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | +| `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | **[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 5d4b9fdd0d..3e6cb078c7 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -22,17 +22,17 @@ These attributes may be used for any network related operation. | `network.peer.port` | int | Peer port number of the network connection. | `65123` | | `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | | `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | -| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | | `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | **[1]:** The value SHOULD be normalized to lowercase. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. **[3]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** The value SHOULD be normalized to lowercase. @@ -79,7 +79,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. |---|---| | `tcp` | TCP | | `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | +| `pipe` | Named or anonymous pipe. | | `unix` | Unix domain socket | `network.type` 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. diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 33f8f9e109..4064262d1d 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -40,7 +40,7 @@ document. A CloudEvent can be sent directly from producer to consumer. For such a scenario, the traditional parent-child trace model works well. However, CloudEvents are also used in distributed systems where an event -can go through many [hops]() +can go through many [hops]() until it reaches a consumer. In this scenario, the traditional parent-child trace model is not sufficient to produce a meaningful trace. diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 058f672dd8..f211e64c37 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -45,7 +45,7 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | | `state` | string | The state of a connection in the pool | `idle` | Required | `state` MUST be one of the following: @@ -68,7 +68,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.idle.min` @@ -84,7 +84,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.max` @@ -100,7 +100,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.pending_requests` @@ -116,7 +116,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.timeouts` @@ -132,7 +132,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.create_time` @@ -148,7 +148,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.wait_time` @@ -164,7 +164,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.use_time` @@ -180,7 +180,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation does not provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index a4873f17e6..65cccffab1 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -69,7 +69,7 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | @@ -77,15 +77,14 @@ Some database systems may allow a connection to switch to a different `db.user`, **[1]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[2]:** The value SHOULD be normalized to lowercase. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent -the server address behind any intermediaries (e.g. proxies) if it's available. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[5]:** If using a port other than the default port for this DBMS and if `server.address` is set. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 2cbbd713d5..330bdbacfe 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -61,10 +61,9 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent -the server address behind any intermediaries (e.g. proxies) if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[8]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[8]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. diff --git a/docs/database/mssql.md b/docs/database/mssql.md index b64cf49678..4873f48d11 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -18,7 +18,7 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.jdbc.driver_classname`](database-spans.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index ec64eb86bc..71f929a2a6 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -104,7 +104,7 @@ grained information from a stacktrace, if necessary. [python-stacktrace]: https://docs.python.org/3/library/traceback.html#traceback.format_exc [js-stacktrace]: https://v8.dev/docs/stack-trace-api [ruby-full-message]: https://ruby-doc.org/core-2.7.1/Exception.html#method-i-full_message -[csharp-stacktrace]: https://docs.microsoft.com/en-us/dotnet/api/system.exception.tostring +[csharp-stacktrace]: https://docs.microsoft.com/dotnet/api/system.exception.tostring [go-stacktrace]: https://pkg.go.dev/runtime/debug#Stack [telemetry-sdk-resource]: ../resource/README.md#telemetry-sdk [erlang-stacktrace]: https://www.erlang.org/doc/man/erl_error.html#format_exception-3 diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 3a9f50c2ad..bb3012e92e 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -41,7 +41,7 @@ If Spans following this convention are produced, a Resource of type `faas` MUST | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | | `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | | `faas.trigger` | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | @@ -57,7 +57,7 @@ The following well-known definitions MUST be used if you set this attribute and with the resolved function version, as the same runtime instance may be invokable with multiple different aliases. * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, +* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, *not* the function app, having the form `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share @@ -108,7 +108,7 @@ The span attribute `faas.invocation_id` differs from the [resource attribute][Fa - `faas.instance` refers to the execution environment ID of the function. [AWS lambda]: https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html -[Azure functions]: https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections#static-clients +[Azure functions]: https://docs.microsoft.com/azure/azure-functions/manage-connections#static-clients [Google functions]: https://cloud.google.com/functions/docs/concepts/exec#function_scope_versus_global_scope ## Incoming Invocations diff --git a/docs/general/attributes.md b/docs/general/attributes.md index c70eb3c13d..1b082c1649 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -69,13 +69,12 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `server.address` | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `server.address` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | Recommended | -**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent -the server address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `server.address` and `server.port` represent logical server name and port. Semantic conventions that refer to these attributes SHOULD @@ -107,12 +106,12 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `client.address` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `client.port` | int | Client port number. [2] | `65123` | Recommended | -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. ### Source and destination attributes @@ -129,10 +128,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `source.address` | string | Source address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `source.port` | int | Source port number | `3389`; `2888` | Recommended | -**[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. #### Destination @@ -142,10 +141,10 @@ Destination fields capture details about the receiver of a network exchange/pack | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | `destination.port` | int | Destination port number | `3389`; `2888` | Recommended | -**[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. @@ -166,17 +165,17 @@ if they do not cause breaking changes to HTTP semantic conventions. | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. **[3]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** The value SHOULD be normalized to lowercase. @@ -187,7 +186,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. |---|---| | `tcp` | TCP | | `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | +| `pipe` | Named or anonymous pipe. | | `unix` | Unix domain socket | `network.type` 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. @@ -345,7 +344,7 @@ Examples of where the `enduser.id` value is extracted from: [OpenID Connect 1.0 IDToken]: https://openid.net/specs/openid-connect-core-1_0.html#IDToken [Kerberos]: https://tools.ietf.org/html/rfc4120 [JavaEE/JakartaEE Servlet]: https://jakarta.ee/specifications/platform/8/apidocs/javax/servlet/http/HttpServletRequest.html -[Windows Communication Foundation]: https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.servicesecuritycontext?view=netframework-4.8 +[Windows Communication Foundation]: https://docs.microsoft.com/dotnet/api/system.servicemodel.servicesecuritycontext?view=netframework-4.8 Given the sensitive nature of this information, SDKs and exporters SHOULD drop these attributes by default and then provide a configuration parameter to turn on retention for use cases where the diff --git a/docs/general/events.md b/docs/general/events.md index 8c9a0c05a7..3ca2c7cd89 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -46,8 +46,7 @@ that identify the class of Events but not the instance of the Event. | `event.domain` | string | The domain identifies the business context for the events. [1] | `browser` | Required | | `event.name` | string | The name identifies the event. | `click`; `exception` | Required | -**[1]:** Events across different domains may have same `event.name`, yet be -unrelated events. +**[1]:** Events across different domains may have same `event.name`, yet be unrelated events. `event.domain` 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. diff --git a/docs/general/metrics.md b/docs/general/metrics.md index c5446df657..058a12e636 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -28,7 +28,7 @@ The following semantic conventions surrounding metrics are defined: * **[General Guidelines](#general-guidelines): General metrics guidelines.** * [Database](/docs/database/database-metrics.md): For SQL and NoSQL client metrics. -* [FaaS](/docs/faas/faas-metrics.md): For [Function as a Service](https://en.wikipedia.org/wiki/Function_as_a_service) metrics. +* [FaaS](/docs/faas/faas-metrics.md): For [Function as a Service](https://wikipedia.org/wiki/Function_as_a_service) metrics. * [HTTP](/docs/http/http-metrics.md): For HTTP client and server metrics. * [RPC](/docs/rpc/rpc-metrics.md): For RPC client and server metrics. * **System metrics** @@ -109,7 +109,7 @@ Metric namespaces SHOULD NOT be pluralized. Metric names SHOULD NOT be pluralized, unless the value being recorded represents discrete instances of a -[countable quantity](https://en.wikipedia.org/wiki/Count_noun). +[countable quantity](https://wikipedia.org/wiki/Count_noun). Generally, the name SHOULD be pluralized only if the unit of the metric in question is a non-unit (like `{fault}` or `{operation}`). diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index 54e02fcf92..bfac2262af 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -36,7 +36,7 @@ between a child Span and a parent Span, as defined by | Value | Description | |---|---| | `child_of` | The parent Span depends on the child Span in some capacity | -| `follows_from` | The parent Span does not depend in any way on the result of the child Span | +| `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/trace.md b/docs/general/trace.md index 01a99b61c4..2397794348 100644 --- a/docs/general/trace.md +++ b/docs/general/trace.md @@ -26,7 +26,7 @@ The following semantic conventions for spans are defined: * [Cloud Providers](/docs/cloud-providers/README.md): Semantic Conventions for cloud providers spans. * [Database](/docs/database/database-spans.md): For SQL and NoSQL client call spans. * [Exceptions](/docs/exceptions/exceptions-spans.md): For recording exceptions associated with a span. -* [FaaS](/docs/faas/faas-spans.md): For [Function as a Service](https://en.wikipedia.org/wiki/Function_as_a_service) (e.g., AWS Lambda) spans. +* [FaaS](/docs/faas/faas-spans.md): For [Function as a Service](https://wikipedia.org/wiki/Function_as_a_service) (e.g., AWS Lambda) spans. * [Feature Flags](/docs/feature-flags/feature-flags-spans.md): For recording feature flag evaluations associated with a span. * [HTTP](/docs/http/http-spans.md): For HTTP client and server spans. * [Messaging](/docs/messaging/messaging-spans.md): For messaging systems (queues, publish/subscribe, etc.) spans. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 750ab3a1ae..93a393b50e 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -79,7 +79,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | @@ -123,41 +123,41 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header +- Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Host identifier of the `Host` header. MUST NOT include the port identifier. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header +- Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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 | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -210,28 +210,28 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** Determined by using the first of the following that applies +**[2]:** Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header +- Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Host identifier of the `Host` header. MUST NOT include the port identifier. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[3]:** Determined by using the first of the following that applies +**[3]:** Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header +- Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -272,7 +272,7 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | @@ -316,41 +316,41 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header +- Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Host identifier of the `Host` header. MUST NOT include the port identifier. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header +- Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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 | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -388,7 +388,7 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | @@ -432,41 +432,41 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies +**[6]:** Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header +- Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Host identifier of the `Host` header. MUST NOT include the port identifier. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** Determined by using the first of the following that applies +**[7]:** Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header +- Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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 | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -550,18 +550,17 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** Determined by using the first of the following that applies +**[5]:** 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 +- 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. If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -569,7 +568,7 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. | Value | Description | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -647,18 +646,17 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** Determined by using the first of the following that applies +**[5]:** 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 +- 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. If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -666,7 +664,7 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. | Value | Description | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -744,18 +742,17 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** Determined by using the first of the following that applies +**[5]:** 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 +- 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. If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -763,7 +760,7 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. | Value | Description | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 46caf107a2..678e1ead41 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -125,7 +125,7 @@ sections below. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | | `user_agent.original` | 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 | **[1]:** If the request fails with an error before response status code was sent or received, @@ -172,7 +172,7 @@ The attribute value MUST consist of either multiple header values as an array of **[6]:** The value SHOULD be normalized to lowercase. -**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. **[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. @@ -184,7 +184,7 @@ Following attributes MUST be provided **at span creation time** (when provided a | Value | Description | |---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. | +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `http.request.method` 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. @@ -207,7 +207,7 @@ Following attributes MUST be provided **at span creation time** (when provided a |---|---| | `tcp` | TCP | | `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | +| `pipe` | Named or anonymous pipe. | | `unix` | Unix domain socket | @@ -237,16 +237,15 @@ For an HTTP client span, `SpanKind` MUST be `Client`. **[1]:** 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). -**[2]:** Determined by using the first of the following that applies +**[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 +- 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. If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. +**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. **[4]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -338,7 +337,7 @@ Some servers allow to bind the same HTTP application to multiple `(virtual host, [document base]: http://tomcat.apache.org/tomcat-5.5-doc/config/context.html [rfc-servername]: https://tools.ietf.org/html/rfc3875#section-4.1.14 [ap-sn]: https://httpd.apache.org/docs/2.4/mod/core.html#servername -[nx-sn]: http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name +[nx-sn]: http://nginx.org/docs/http/ngx_http_core_module.html#server_name [JSR 53]: https://jcp.org/aboutJava/communityprocess/maintenance/jsr053/index2.html [opentelemetry/opentelementry-specification#335]: https://github.com/open-telemetry/opentelemetry-specification/issues/335 @@ -351,9 +350,9 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | -| [`http.route`](../attributes-registry/http.md) | string | The matched route (path template in the format used by the respective server framework). See note below [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | +| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -364,32 +363,32 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | -**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. +**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. **[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** Determined by using the first of the following that applies +**[4]:** Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header +- Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Host identifier of the `Host` header. MUST NOT include the port identifier. -**[5]:** Determined by using the first of the following that applies +**[5]:** Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header +- Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. +- Port identifier of the `Host` header. **[6]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -397,7 +396,7 @@ MUST NOT include the port identifier. **[8]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 381910424f..bf70deff59 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -233,9 +233,9 @@ The following operations related to messages are defined for these semantic conv | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.address`](../general/attributes.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -244,7 +244,7 @@ The following operations related to messages are defined for these semantic conv **[3]:** If value is `true`. When missing, the value is assumed to be `false`. **[4]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If -the broker does not have such notion, the destination name SHOULD uniquely identify the broker. +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. **[5]:** If span describes operation on a single message or if the value applies to all messages in the batch. @@ -272,12 +272,12 @@ size should be used. **[16]:** The value SHOULD be normalized to lowercase. -**[17]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[17]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. **[18]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[19]:** The value SHOULD be normalized to lowercase. @@ -332,7 +332,7 @@ under the namespace `messaging.destination_publish.*` | `messaging.destination_publish.name` | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | **[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If -the broker does not have such notion, the original destination name SHOULD uniquely identify the broker. +the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. The *receive* span is used to track the time used for receiving the message(s), whereas the *process* span(s) track the time for processing the message(s). diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index 6644e63325..f255b94025 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -14,13 +14,13 @@ | `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | Recommended | | `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | | `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | Recommended | -| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. **[2]:** The prefix of the service SHOULD match the one specified in `cloud.provider`. -**[3]:** Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). +**[3]:** Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). **[4]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. @@ -34,7 +34,7 @@ The following well-known definitions MUST be used if you set this attribute and with the resolved function version, as the same runtime instance may be invokable with multiple different aliases. * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, +* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, *not* the function app, having the form `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index 9766919543..e9ff217754 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `deployment.environment` | string | Name of the [deployment environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka deployment tier). | `staging`; `production` | Recommended | +| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). | `staging`; `production` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/faas.md b/docs/resource/faas.md index f8560c1471..e38f88c7db 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -16,7 +16,7 @@ See also: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`cloud.resource_id`](cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | | `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | | `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | | `faas.name` | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | @@ -34,7 +34,7 @@ The following well-known definitions MUST be used if you set this attribute and with the resolved function version, as the same runtime instance may be invokable with multiple different aliases. * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, +* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, *not* the function app, having the form `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index ef50c8a818..5692ce3132 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -27,7 +27,7 @@ Kubernetes object, but "name" is usually more user friendly so can be also set. | `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | | `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | -**[1]:** K8s does not have support for obtaining a cluster ID. If this is ever +**[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the official APIs. In the meantime, we are able to use the `uid` of the `kube-system` namespace as a proxy for cluster ID. Read on for the diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index e0842a6c0b..32ebf65402 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -20,7 +20,7 @@ described on this page. | `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | Conditionally Required: If response is not successful. | | `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | Recommended | | `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | -| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | +| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Required | **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 23ed667528..a27e701e93 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -220,18 +220,18 @@ measurements. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.address`](../general/attributes.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[2]:** The value SHOULD be normalized to lowercase. @@ -240,10 +240,9 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent -the server address behind any intermediaries (e.g. proxies) if it's available. +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `network.transport` 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. @@ -251,7 +250,7 @@ the server address behind any intermediaries (e.g. proxies) if it's available. |---|---| | `tcp` | TCP | | `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | +| `pipe` | Named or anonymous pipe. | | `unix` | Unix domain socket | `network.type` 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. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 995e5918d9..695766872d 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -85,7 +85,7 @@ Examples of span names: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | | `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | @@ -96,7 +96,7 @@ Examples of span names: **[1]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[2]:** The value SHOULD be normalized to lowercase. @@ -107,7 +107,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[5]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries (e.g. proxies) if it's available. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `rpc.system` 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. @@ -151,21 +151,21 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `client.address`. | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries (e.g. proxies) if it's available. +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries (e.g. proxies) if it's available. +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. **[3]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** The value SHOULD be normalized to lowercase. diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index b5b6cee212..904dd8c74d 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -298,7 +298,7 @@ Additional **Recommended** attributes: | | | | | | `hw.type` (**Required**) | `physical_disk` | | `hw.physical_disk.endurance_utilization` | Endurance remaining for this SSD disk | 1 | Gauge | Double | `state` (**Required**) | `remaining` | | `hw.physical_disk.size` | Size of the disk | By | UpDownCounter | Int64 | | | -| `hw.physical_disk.smart` | Value of the corresponding [S.M.A.R.T.](https://en.wikipedia.org/wiki/S.M.A.R.T.) attribute | 1 | Gauge | Int | `smart_attribute` (Recommended) | `Seek Error Rate`, `Spin Retry Count`, etc. | +| `hw.physical_disk.smart` | Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) attribute | 1 | Gauge | Int | `smart_attribute` (Recommended) | `Seek Error Rate`, `Spin Retry Count`, etc. | | `hw.status` | Operational status: `1` (true) or `0` (false) for each of the possible states | | UpDownCounter | Int | `state` (**Required**) | `ok`, `degraded`, `failed`, `predicted_failure` | | | | | | | `hw.type` (**Required**) | `physical_disk` | diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index bd3957fc21..14254bf534 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -373,7 +373,7 @@ This metric is [recommended][MetricRecommended]. - Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) - Windows: The complement of - ["Disk\% Idle Time"](https://learn.microsoft.com/en-us/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) + ["Disk\% Idle Time"](https://learn.microsoft.com/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) performance counter: `uptime * (100 - "Disk\% Idle Time") / 100` @@ -534,8 +534,8 @@ This metric is [recommended][MetricRecommended]. **[1]:** Measured as: - Linux: the `drop` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) -- Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2) +- Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2) @@ -588,8 +588,8 @@ This metric is [recommended][MetricRecommended]. **[1]:** Measured as: - Linux: the `errs` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). -- Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). +- Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). @@ -643,14 +643,14 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | | `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport, for example +a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. `network.transport` 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. @@ -659,7 +659,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. |---|---| | `tcp` | TCP | | `udp` | UDP | -| `pipe` | Named or anonymous pipe. See note below. | +| `pipe` | Named or anonymous pipe. | | `unix` | Unix domain socket | `system.network.state` MUST be one of the following: @@ -730,7 +730,7 @@ follow the hierarchies listed above for different entities like CPU, memory, and network. For example, [UNIX load -average](https://en.wikipedia.org/wiki/Load_(computing)) over a given +average](https://wikipedia.org/wiki/Load_(computing)) over a given interval is not well standardized and its value across different UNIX like OSes may vary despite being under similar load: diff --git a/model/client.yaml b/model/client.yaml index 71d285f7dc..0e133f0e4c 100644 --- a/model/client.yaml +++ b/model/client.yaml @@ -7,15 +7,15 @@ groups: where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the - protocol / API does not expose a clear notion of client and server). + protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. attributes: - id: address type: string - brief: Client address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + brief: "Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent - the client address behind any intermediaries (e.g. proxies) if it's available. + the client address behind any intermediaries, for example proxies, if it's available. examples: ['client.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int @@ -23,4 +23,4 @@ groups: examples: [65123] note: > When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent - the client port behind any intermediaries (e.g. proxies) if it's available. + the client port behind any intermediaries, for example proxies, if it's available. diff --git a/model/destination.yaml b/model/destination.yaml index bad57d5a22..30d155ce56 100644 --- a/model/destination.yaml +++ b/model/destination.yaml @@ -7,14 +7,14 @@ groups: This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the - "user-facing" surface of the protocol / API does not expose a clear notion of client and server. + "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server. attributes: - id: address type: string - brief: Destination address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + brief: "Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent - the destination address behind any intermediaries (e.g. proxies) if it's available. + the destination address behind any intermediaries, for example proxies, if it's available. examples: ['destination.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int diff --git a/model/error.yaml b/model/error.yaml index 01b7b05f5f..a86b33408a 100644 --- a/model/error.yaml +++ b/model/error.yaml @@ -13,19 +13,20 @@ groups: members: - id: other value: "_OTHER" - brief: 'A fallback error value to be used when the instrumentation does not define a custom value for it.' + brief: "A fallback error value to be used when the instrumentation doesn't define a custom value." examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] note: | The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. - The cardinality of `error.type` within one instrumentation library SHOULD be low, but - telemetry consumers that aggregate data from multiple instrumentation libraries and applications - should be prepared for `error.type` to have high cardinality at query time, when no + The cardinality of `error.type` within one instrumentation library SHOULD be low. + Telemetry consumers that aggregate data from multiple instrumentation libraries and applications + should be prepared for `error.type` to have high cardinality at query time when no additional filters are applied. If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), - it's RECOMMENDED to use a domain-specific attribute and also set `error.type` to capture - all errors, regardless of whether they are defined within the domain-specific set or not. + it's RECOMMENDED to: + * Use a domain-specific attribute + * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. diff --git a/model/http-common.yaml b/model/http-common.yaml index dfee35a62e..60d084eeb5 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -45,11 +45,10 @@ groups: 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 + 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 + - 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. If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. @@ -60,7 +59,7 @@ groups: 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, `server.port` MUST match - URI port identifier, otherwise it MUST match `Host` header port identifier. + URI port identifier; otherwise, it MUST match `Host` header port identifier. - id: attributes.http.server type: attribute_group @@ -74,14 +73,14 @@ groups: brief: > Name of the local HTTP server that received the request. note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header + - Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Host identifier of the `Host` header. MUST NOT include the port identifier. @@ -89,14 +88,14 @@ groups: brief: > Port of the local HTTP server that received the request. note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header + - Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Port identifier of the `Host` header. requirement_level: conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). - ref: url.scheme @@ -104,7 +103,7 @@ groups: examples: ["http", "https"] note: > The scheme of the original client request, if known - (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), - [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto), + (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), + [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. diff --git a/model/logs/events.yaml b/model/logs/events.yaml index f3398c9ac1..aed530cb1c 100644 --- a/model/logs/events.yaml +++ b/model/logs/events.yaml @@ -27,6 +27,6 @@ groups: value: 'k8s' brief: 'Events from Kubernetes' requirement_level: required - note: | + note: > Events across different domains may have same `event.name`, yet be unrelated events. diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index fdb6a0ce2a..3df6d86a2c 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -19,7 +19,7 @@ groups: requirement_level: required brief: > The name of the connection pool; unique within the instrumented application. - In case the connection pool implementation does not provide a name, + In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used examples: ["myDataSource"] diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 22467fcd2a..a791b0f070 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -7,14 +7,14 @@ groups: - ref: server.address requirement_level: opt_in note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header + - Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Host identifier of the `Host` header. MUST NOT include the port identifier. @@ -24,14 +24,14 @@ groups: - ref: server.port requirement_level: opt_in note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header + - Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. @@ -69,14 +69,14 @@ groups: brief: > Name of the local HTTP server that received the request. note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - 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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header + - Host identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Host identifier of the `Host` header. MUST NOT include the port identifier. @@ -88,14 +88,14 @@ groups: brief: > Port of the local HTTP server that received the request. note: | - Determined by using the first of the following that applies + Determined by using the first of the following that applies: - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header + - Port identifier of [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), + [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. + - Port identifier of the `Host` header. Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, degrading the usefulness of the metric. diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index cfd20979f2..eb69d3f992 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -241,7 +241,7 @@ groups: - Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) - Windows: The complement of - ["Disk\% Idle Time"](https://learn.microsoft.com/en-us/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) + ["Disk\% Idle Time"](https://learn.microsoft.com/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) performance counter: `uptime * (100 - "Disk\% Idle Time") / 100` attributes: - ref: system.device @@ -399,8 +399,8 @@ groups: Measured as: - Linux: the `drop` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) - - Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2) + - Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2) attributes: - ref: system.device - ref: system.network.direction @@ -425,8 +425,8 @@ groups: Measured as: - Linux: the `errs` column in `/proc/dev/net` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). - - Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2). + - Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). attributes: - ref: system.device - ref: system.network.direction diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 05483ec79b..1f6c4e349a 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -118,7 +118,7 @@ groups: - id: route type: string brief: > - The matched route (path template in the format used by the respective server framework). See note below + The matched route, that is, the path template in the format used by the respective server framework. 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. diff --git a/model/registry/network.yaml b/model/registry/network.yaml index 698b9d89f7..b5ecb1efb8 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -133,7 +133,7 @@ groups: examples: '3.1.1' note: > `network.protocol.version` refers to the version of the protocol used and might be - different from the protocol client's version. If the HTTP client used has a version + different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - id: transport type: @@ -147,18 +147,18 @@ groups: brief: "UDP" - id: pipe value: "pipe" - brief: 'Named or anonymous pipe. See note below.' + brief: 'Named or anonymous pipe.' - id: unix value: 'unix' brief: "Unix domain socket" brief: > [OSI transport layer](https://osi-model.com/transport-layer/) or - [inter-process communication method](https://en.wikipedia.org/wiki/Inter-process_communication). + [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). note: | The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since - a port number is ambiguous without knowing the transport, for example + a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. examples: ['tcp', 'udp'] - id: type diff --git a/model/resource/cloud.yaml b/model/resource/cloud.yaml index c24e474855..0e3e2e2b17 100644 --- a/model/resource/cloud.yaml +++ b/model/resource/cloud.yaml @@ -46,7 +46,7 @@ groups: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), - [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), + [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). examples: ['us-central1', 'us-east-1'] @@ -55,7 +55,7 @@ groups: brief: > Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, - a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, + a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) note: | On some cloud providers, it may not be possible to determine the full ID at startup, @@ -70,7 +70,7 @@ groups: with the resolved function version, as the same runtime instance may be invokable with multiple different aliases. * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) - * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, + * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, *not* the function app, having the form `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share diff --git a/model/resource/deployment_environment.yaml b/model/resource/deployment_environment.yaml index 336cabeced..9109f6f7cb 100644 --- a/model/resource/deployment_environment.yaml +++ b/model/resource/deployment_environment.yaml @@ -8,6 +8,6 @@ groups: - id: environment type: string brief: > - Name of the [deployment environment](https://en.wikipedia.org/wiki/Deployment_environment) + Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). examples: ['staging', 'production'] diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index 32a9716dbe..ac353625ea 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -16,7 +16,7 @@ groups: A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. note: | - K8s does not have support for obtaining a cluster ID. If this is ever + K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the official APIs. In the meantime, we are able to use the `uid` of the `kube-system` namespace as a proxy for cluster ID. Read on for the diff --git a/model/server.yaml b/model/server.yaml index 8f10470221..eecdc7c8db 100644 --- a/model/server.yaml +++ b/model/server.yaml @@ -7,20 +7,20 @@ groups: where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the - protocol / API does not expose a clear notion of client and server). + protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. attributes: - id: address type: string - brief: Server address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. - note: | + brief: "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." + note: > When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent - the server address behind any intermediaries (e.g. proxies) if it's available. + the server address behind any intermediaries, for example proxies, if it's available. examples: ['example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int brief: Server port number. note: > When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent - the server port behind any intermediaries (e.g. proxies) if it's available. + the server port behind any intermediaries, for example proxies, if it's available. examples: [80, 8080, 443] diff --git a/model/source.yaml b/model/source.yaml index 9c0aa30a28..c142eaffec 100644 --- a/model/source.yaml +++ b/model/source.yaml @@ -7,14 +7,14 @@ groups: This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the - "user-facing" surface of the protocol / API does not expose a clear notion of client and server. + "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server. attributes: - id: address type: string - brief: Source address - domain name if available without reverse DNS lookup, otherwise IP address or Unix domain socket name. + brief: "Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent - the source address behind any intermediaries (e.g. proxies) if it's available. + the source address behind any intermediaries, for example proxies, if it's available. examples: ['source.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int diff --git a/model/trace/compatibility.yaml b/model/trace/compatibility.yaml index 62f85e5c08..2e3fe12dc7 100644 --- a/model/trace/compatibility.yaml +++ b/model/trace/compatibility.yaml @@ -15,7 +15,7 @@ groups: members: - id: child_of value: 'child_of' - brief: 'The parent Span depends on the child Span in some capacity' + brief: "The parent Span depends on the child Span in some capacity" - id: follows_from value: 'follows_from' - brief: 'The parent Span does not depend in any way on the result of the child Span' + brief: "The parent Span doesn't depend in any way on the result of the child Span" diff --git a/model/trace/database.yaml b/model/trace/database.yaml index e7e1659505..0f5db8edb7 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -263,7 +263,7 @@ groups: If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. examples: 'MSSQLSERVER' diff --git a/model/trace/exporter/exporter.yaml b/model/trace/exporter/exporter.yaml index bba71aac9b..2989475d71 100644 --- a/model/trace/exporter/exporter.yaml +++ b/model/trace/exporter/exporter.yaml @@ -17,5 +17,5 @@ groups: brief: Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. - id: status_description type: string - brief: Description of the Status if it has a value, otherwise not set. + brief: "Description of the Status if it has a value, otherwise not set." examples: ['resource not found'] diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 599b1075f7..5749f3a6f5 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -69,14 +69,14 @@ groups: - ref: client.address note: > The IP address of the original client behind all proxies, if - known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded), - [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). + known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), + [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. examples: ['83.164.160.102'] - ref: client.port brief: > The port of the original client behind all proxies, if - known (e.g. from [Forwarded](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded) or a similar header). + known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. - ref: network.peer.address - ref: network.peer.port diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 3313d95f55..d2cfab3302 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -51,7 +51,7 @@ groups: brief: 'The message destination name' note: | Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If - the broker does not have such notion, the destination name SHOULD uniquely identify the broker. + the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - id: template type: string @@ -92,7 +92,7 @@ groups: brief: 'The name of the original destination the message was published to' note: | The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If - the broker does not have such notion, the original destination name SHOULD uniquely identify the broker. + the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - id: anonymous type: boolean diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 8cee3efc39..8d7407b835 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -184,7 +184,7 @@ groups: type: string requirement_level: conditionally_required: If other than the default version (`1.0`) - brief: "Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted." + brief: "Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted." examples: ['2.0', '1.0'] - id: request_id type: string From e029787228d0ba232d49a2ec0a33d304b4f107e9 Mon Sep 17 00:00:00 2001 From: Bryce Buchanan <75274611+bryce-b@users.noreply.github.com> Date: Fri, 20 Oct 2023 01:11:52 -0700 Subject: [PATCH 100/482] added mobile instrumentation to log-event semantic conventions (#67) Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> Co-authored-by: Alexander Wert --- docs/mobile/README.md | 18 +++++++++ docs/mobile/events.md | 63 ++++++++++++++++++++++++++++++ model/logs/mobile-events.yaml | 73 +++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 docs/mobile/README.md create mode 100644 docs/mobile/events.md create mode 100644 model/logs/mobile-events.yaml diff --git a/docs/mobile/README.md b/docs/mobile/README.md new file mode 100644 index 0000000000..bcf994e485 --- /dev/null +++ b/docs/mobile/README.md @@ -0,0 +1,18 @@ + + +# Semantic Convention for Mobile Platform + +**Status**: [Experimental][DocumentStatus] + +This document defines semantic conventions for mobile platform spans, metrics and logs. + +Semantic conventions for the mobile platform are defined for the following signals: + +* [Mobile Events](events.md) : Semantic Conventions for mobile events in *logs*. + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/mobile/events.md b/docs/mobile/events.md new file mode 100644 index 0000000000..df020e2c04 --- /dev/null +++ b/docs/mobile/events.md @@ -0,0 +1,63 @@ +# Semantic Conventions for mobile events + +**Status**: [Experimental][DocumentStatus] + +This document defines semantic conventions for instrumentations that emit events on mobile platforms. +All mobile events MUST set `event.domain` as `device`. + + + +- [Lifecycle instrumentation](#lifecycle-instrumentation) + * [iOS](#ios) + * [Android](#android) + + + +## Lifecycle instrumentation + +This section defines how to apply semantic conventions when instrumenting application lifecycle. +This event is meant to be used in conjunction with `os.name` [resource semantic convention](/docs/resource/os.md) to identify the mobile operating system (e.g. Android, iOS). + +### iOS + + +The event name MUST be `app.lifecycle`. + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | Required | + +**[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. + +`ios.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | +| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | + + +### Android + + +The event name MUST be `app.lifecycle`. + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | Required | + +**[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. + +`android.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | +| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | +| `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml new file mode 100644 index 0000000000..797851cb48 --- /dev/null +++ b/model/logs/mobile-events.yaml @@ -0,0 +1,73 @@ +groups: + - id: ios.lifecycle.events + type: event + prefix: ios + name: app.lifecycle + brief: > + This event represents an occurrence of a lifecycle transition on the iOS platform. `event.domain` MUST be `device`. + attributes: + - id: state + requirement_level: "required" + note: > + The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), + and from which the `OS terminology` column values are derived. + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + type: + allow_custom_values: false + members: + - id: active + value: 'active' + brief: > + The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + - id: inactive + value: 'inactive' + brief: > + The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + - id: background + value: 'background' + brief: > + The app is now in the background. + This value is associated with UIKit notification `applicationDidEnterBackground`. + - id: foreground + value: 'foreground' + brief: > + The app is now in the foreground. + This value is associated with UIKit notification `applicationWillEnterForeground`. + - id: terminate + value: 'terminate' + brief: > + The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + - id: android.lifecycle.events + type: event + prefix: android + name: app.lifecycle + brief: > + This event represents an occurrence of a lifecycle transition on the Android platform. + `event.domain` MUST be `device`. + attributes: + - id: state + requirement_level: required + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + note: > + The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + and from which the `OS identifiers` are derived. + type: + allow_custom_values: false + members: + - id: created + value: 'created' + brief: > + Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + has been called in the app for the first time. + - id: background + value: 'background' + brief: > + Any time after Activity.onPause() or, if the app has no Activity, + Context.stopService() has been called when the app was in the foreground state. + - id: foreground + value: 'foreground' + brief: > + Any time after Activity.onResume() or, if the app has no Activity, + Context.startService() has been called when the app was in either the created or background states. From b23075cd6016816b9e8d93ee3e5241a4694441ff Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 20 Oct 2023 07:23:28 -0700 Subject: [PATCH 101/482] Remove dashes to underscores normalization from http header attribute keys (#369) Co-authored-by: Armin Ruech Co-authored-by: Josh Suereth --- CHANGELOG.md | 3 +++ docs/attributes-registry/http.md | 4 ++-- docs/http/http-spans.md | 4 ++-- docs/rpc/connect-rpc.md | 4 ++-- docs/rpc/grpc.md | 4 ++-- model/registry/http.yaml | 8 ++++---- model/trace/rpc.yaml | 16 ++++++++-------- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12342a0a8e..a3458f7577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -175,6 +175,9 @@ release. ([#366](https://github.com/open-telemetry/semantic-conventions/pull/366)) - Add `host.ip` resource attribute convention. ([#203](https://github.com/open-telemetry/semantic-conventions/pull/203)) +- BREAKING: remove `-` to `_` normalization from http header and rpc metadata + attribute keys. + ([#369](https://github.com/open-telemetry/semantic-conventions/pull/369)) - BREAKING: Rename/replace `(client|server).socket.(address|port)` attributes with `network.(peer|local).(address|port)`. ([#342](https://github.com/open-telemetry/semantic-conventions/pull/342)) diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index f80783cafa..62955335ba 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -9,12 +9,12 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `http.request.body.size` | 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` | -| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [1] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | +| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | | `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | | `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | | `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | | `http.response.body.size` | 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` | -| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [4] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | +| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | | `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | | `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 678e1ead41..089caa7020 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -117,11 +117,11 @@ sections below. |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.body.size`](../attributes-registry/http.md) | 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.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [2] | `http.request.header.content_type=["application/json"]`; `http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [2] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | | [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. [5] | `http.response.header.content_type=["application/json"]`; `http.response.header.my_custom_header=["abc", "def"]` | Opt-In | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index 75798f2fb8..f2b9d9ca0c 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -20,8 +20,8 @@ Below is a table of attributes that SHOULD be included on client and server Conn | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | Conditionally Required: [1] | -| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [2] | `rpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [3] | `rpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | +| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | **[1]:** If response is not successful and if error code available. diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 8ff11b8cf8..52c4903568 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -19,8 +19,8 @@ Below is a table of attributes that SHOULD be included on client and server gRPC | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]` | Opt-In | +| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | | `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 1f6c4e349a..4264ae3251 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -14,7 +14,7 @@ groups: - id: request.header type: template[string[]] brief: > - HTTP request headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. note: > Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -25,7 +25,7 @@ groups: The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - examples: ['http.request.header.content_type=["application/json"]', 'http.request.header.x_forwarded_for=["1.2.3.4", "1.2.3.5"]'] + examples: ['http.request.header.content-type=["application/json"]', 'http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]'] - id: request.method type: allow_custom_values: true @@ -100,7 +100,7 @@ groups: - id: response.header type: template[string[]] brief: > - HTTP response headers, `` being the normalized HTTP Header name (lowercase, with `-` characters replaced by `_`), the value being the header values. + HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. note: > Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -110,7 +110,7 @@ groups: The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - examples: ['http.response.header.content_type=["application/json"]', 'http.response.header.my_custom_header=["abc", "def"]'] + examples: ['http.response.header.content-type=["application/json"]', 'http.response.header.my-custom-header=["abc", "def"]'] - id: response.status_code type: int brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 8d7407b835..85f4449d41 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -159,20 +159,20 @@ groups: type: template[string[]] requirement_level: opt_in brief: > - gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. note: > Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.grpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]'] + examples: ['rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - id: response.metadata type: template[string[]] requirement_level: opt_in brief: > - gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. note: > Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.grpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]'] + examples: ['rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] - id: rpc.jsonrpc prefix: rpc.jsonrpc @@ -282,17 +282,17 @@ groups: type: template[string[]] requirement_level: opt_in brief: > - Connect request metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. note: > Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.request.metadata.my_custom_metadata_attribute=["1.2.3.4", "1.2.3.5"]'] + examples: ['rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - id: response.metadata type: template[string[]] requirement_level: opt_in brief: > - Connect response metadata, `` being the normalized Connect Metadata key (lowercase, with `-` characters replaced by `_`), the value being the metadata values. + Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. note: > Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.response.metadata.my_custom_metadata_attribute=["attribute_value"]'] + examples: ['rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] From 889b0a4827c3722ead776505d41d9b8c6b05264b Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Sat, 21 Oct 2023 06:40:31 -0700 Subject: [PATCH 102/482] Add session.previous_id (#348) --- CHANGELOG.md | 2 ++ docs/general/session.md | 5 +++++ model/session.yaml | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3458f7577..5f943bf695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ release. ### Features +- Adds `session.previous_id` to session.md + ([#348](https://github.com/open-telemetry/semantic-conventions/pull/348)) - Metric namespaces SHOULD NOT be pluralized. ([#267](https://github.com/open-telemetry/opentelemetry-specification/pull/267)) diff --git a/docs/general/session.md b/docs/general/session.md index c6d5c55920..9c58d3fc44 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -11,12 +11,17 @@ Consequently, a Session is represented as a collection of Logs, Events, and Span throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in the Logs, Events, and Spans generated during the Session's lifecycle. +When a session reaches end of life, typically due to user inactivity or session timeout, a new session identifier +will be assigned. The previous session identifier may be provided by the instrumentation so that telemetry +backends can link the two sessions. + ## Attributes | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | +| `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/session.yaml b/model/session.yaml index eacda8416d..f221265338 100644 --- a/model/session.yaml +++ b/model/session.yaml @@ -9,9 +9,18 @@ groups: Consequently, a Session is represented as a collection of Logs, Events, and Spans emitted by the Client Application throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in the Logs, Events, and Spans generated during the Session's lifecycle. + + When a session reaches end of life, typically due to user inactivity or session timeout, a new session identifier + will be assigned. The previous session identifier may be provided by the instrumentation so that telemetry + backends can link the two sessions. attributes: - id: id type: string brief: "A unique id to identify a session." examples: "00112233-4455-6677-8899-aabbccddeeff" requirement_level: opt_in + - id: previous_id + type: string + brief: "The previous `session.id` for this user, when known." + examples: "00112233-4455-6677-8899-aabbccddeeff" + requirement_level: opt_in From d2a5612e0e4611245ba2017c1a2ae38e644c7854 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 23 Oct 2023 01:22:29 -0700 Subject: [PATCH 103/482] Introduce `jvm.thread.daemon` and `jvm.thread.state` attributes (#297) Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/general/attributes.md | 1 - docs/runtime/jvm-metrics.md | 23 ++++++++++++++++++++--- model/general.yaml | 3 --- model/metrics/jvm-metrics.yaml | 29 ++++++++++++++++++++++++++++- schema-next.yaml | 8 ++++++++ 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f943bf695..2e286d80d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ release. ([#410](https://github.com/open-telemetry/semantic-conventions/pull/410)) - BREAKING: Factor in `X-Forwarded-Host` / `Forwarded` when capturing `server.address` and `server.port`. ([#411](https://github.com/open-telemetry/semantic-conventions/pull/411)) +- Remove `thread.daemon`, and introduce `jvm.thread.daemon` instead. + Introduce `jvm.thread.state` attribute and add it to `jvm.thread.count` metric. + ([#297](https://github.com/open-telemetry/semantic-conventions/pull/297)) ### Features diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 1b082c1649..047ae02744 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -358,7 +358,6 @@ a thread that started a span. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | | `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | | `thread.name` | string | Current thread name. | `main` | Recommended | diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 2ec4231fc9..f36246c653 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -189,8 +189,13 @@ of `[]` (single bucket histogram capturing count, sum, min, max). ### Metric: `jvm.thread.count` This metric is [recommended][MetricRecommended]. -This metric is obtained from [`ThreadMXBean#getDaemonThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getDaemonThreadCount--) and -[`ThreadMXBean#getThreadCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadCount--). +This metric is obtained from a combination of + +* [`ThreadMXBean#getAllThreadIds()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getAllThreadIds--) +* [`ThreadMXBean#getThreadInfo()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html#getThreadInfo-long:A-) +* [`ThreadInfo#getThreadState()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadInfo.html#getThreadState--) +* [`ThreadInfo#isDaemon()`](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/ThreadInfo.html#isDaemon()) (requires Java 9+) + Note that this is the number of platform threads (as opposed to virtual threads). @@ -202,7 +207,19 @@ Note that this is the number of platform threads (as opposed to virtual threads) | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`thread.daemon`](../general/attributes.md) | boolean | Whether the thread is daemon or not. | | Recommended | +| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | +| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | Recommended | + +`jvm.thread.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `new` | A thread that has not yet started is in this state. | +| `runnable` | A thread executing in the Java virtual machine is in this state. | +| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | +| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | +| `timed_waiting` | A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. | +| `terminated` | A thread that has exited is in this state. | ## JVM Classes diff --git a/model/general.yaml b/model/general.yaml index 4f387bac6f..5994c16ff4 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -52,9 +52,6 @@ groups: brief: > Current thread name. examples: main - - id: daemon - brief: "Whether the thread is daemon or not." - type: boolean - id: code prefix: code type: span diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index 4306fc239c..c837145a8c 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -90,8 +90,35 @@ groups: instrument: updowncounter unit: "{thread}" attributes: - - ref: thread.daemon + - id: jvm.thread.daemon + type: boolean requirement_level: recommended + brief: "Whether the thread is daemon or not." + - id: jvm.thread.state + requirement_level: recommended + type: + allow_custom_values: false + members: + - id: new + value: 'new' + brief: 'A thread that has not yet started is in this state.' + - id: runnable + value: 'runnable' + brief: 'A thread executing in the Java virtual machine is in this state.' + - id: blocked + value: 'blocked' + brief: 'A thread that is blocked waiting for a monitor lock is in this state.' + - id: waiting + value: 'waiting' + brief: 'A thread that is waiting indefinitely for another thread to perform a particular action is in this state.' + - id: timed_waiting + value: 'timed_waiting' + brief: 'A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.' + - id: terminated + value: 'terminated' + brief: 'A thread that has exited is in this state.' + brief: "State of the thread." + examples: ["runnable", "blocked"] - id: metric.jvm.class.loaded type: metric diff --git a/schema-next.yaml b/schema-next.yaml index 8fe76165a9..4c3647ce4d 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,14 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + thread.daemon: jvm.thread.daemon + apply_to_metrics: + - jvm.thread.count 1.22.0: spans: changes: From 8e40255a3991014fe4062cee95de21875180927d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 23 Oct 2023 01:27:44 -0700 Subject: [PATCH 104/482] Fix `server.port` to be not required on HTTP server spans when `server.address` is not set (#429) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 2 +- model/http-common.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e286d80d2..7a0027724c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ release. - Remove `thread.daemon`, and introduce `jvm.thread.daemon` instead. Introduce `jvm.thread.state` attribute and add it to `jvm.thread.count` metric. ([#297](https://github.com/open-telemetry/semantic-conventions/pull/297)) +- Fix `server.port` to be not required when `server.address` is not set. + ([#429](https://github.com/open-telemetry/semantic-conventions/pull/429)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 089caa7020..cd1d42e536 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -390,7 +390,7 @@ MUST NOT include the port identifier. [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header. -**[6]:** If not default (`80` for `http` scheme, `443` for `https`). +**[6]:** If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). **[7]:** When missing, the value is assumed to be `/` diff --git a/model/http-common.yaml b/model/http-common.yaml index 60d084eeb5..a32043336d 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -97,7 +97,7 @@ groups: [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - Port identifier of the `Host` header. requirement_level: - conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). + conditionally_required: If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). - ref: url.scheme requirement_level: required examples: ["http", "https"] From cd047137dda8f4c01f359d516631743e488a7af6 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:41:20 +0200 Subject: [PATCH 105/482] move user agent to registry (#418) --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/user-agent.md | 12 ++++++++++++ docs/database/cosmosdb.md | 2 +- docs/http/http-spans.md | 2 +- docs/resource/browser.md | 2 +- model/registry/user-agent.yaml | 12 ++++++++++++ model/user-agent.yaml | 10 ---------- 7 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 docs/attributes-registry/user-agent.md create mode 100644 model/registry/user-agent.yaml delete mode 100644 model/user-agent.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index ad8f844a8a..d7deb572d9 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -30,5 +30,6 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [Network](network.md) * [URL](url.md) +* [User agent](user-agent.md) [developers recommendations]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md new file mode 100644 index 0000000000..d60e19697f --- /dev/null +++ b/docs/attributes-registry/user-agent.md @@ -0,0 +1,12 @@ + + +# User agent + +## User agent Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `user_agent.original` | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | + diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 5c092cf560..3c2669879c 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -28,7 +28,7 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | Recommended | | `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | Conditionally Required: if response was received | | `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | Conditionally Required: [2] | -| `user_agent.original` | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | Recommended | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | Recommended | **[1]:** when performing one of the operations in this list diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index cd1d42e536..ec510f4c91 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -126,7 +126,7 @@ sections below. | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | -| `user_agent.original` | 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 | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) diff --git a/docs/resource/browser.md b/docs/resource/browser.md index c352b70c70..cec3fe9494 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -15,7 +15,7 @@ All of these attributes can be provided by the user agent itself in the form of | `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | | `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | Recommended | | `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | Recommended | -| `user_agent.original` | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | Recommended | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | Recommended | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). diff --git a/model/registry/user-agent.yaml b/model/registry/user-agent.yaml new file mode 100644 index 0000000000..2b93ac114d --- /dev/null +++ b/model/registry/user-agent.yaml @@ -0,0 +1,12 @@ +groups: + - id: registry.user_agent + prefix: user_agent + type: attribute_group + brief: "Describes user-agent attributes." + attributes: + - id: original + 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. + examples: ['CERN-LineMode/2.15 libwww/2.17b3', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] diff --git a/model/user-agent.yaml b/model/user-agent.yaml deleted file mode 100644 index 2f43b1af3e..0000000000 --- a/model/user-agent.yaml +++ /dev/null @@ -1,10 +0,0 @@ -groups: - - id: attributes.user_agent - type: attribute_group - brief: "Describes user-agent attributes." - prefix: user_agent - attributes: - - id: original - 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.' - examples: ['CERN-LineMode/2.15 libwww/2.17b3'] From 064fe4efda6ab370e36c451005925eac3b987663 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Mon, 23 Oct 2023 15:52:46 +0200 Subject: [PATCH 106/482] Moved rpc attributes to the registry (#395) Signed-off-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/rpc.md | 91 ++++++++++++ docs/cloud-providers/aws-sdk.md | 6 +- docs/rpc/connect-rpc.md | 8 +- docs/rpc/grpc.md | 8 +- docs/rpc/json-rpc.md | 12 +- docs/rpc/rpc-metrics.md | 6 +- docs/rpc/rpc-spans.md | 24 +++- model/metrics/rpc-metrics.yaml | 1 + model/registry/rpc.yaml | 190 +++++++++++++++++++++++++ model/trace/rpc.yaml | 213 ++++------------------------- 11 files changed, 347 insertions(+), 213 deletions(-) create mode 100644 docs/attributes-registry/rpc.md create mode 100644 model/registry/rpc.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index d7deb572d9..81002bd95a 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -29,6 +29,7 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [Network](network.md) +* [RPC](rpc.md) * [URL](url.md) * [User agent](user-agent.md) diff --git a/docs/attributes-registry/rpc.md b/docs/attributes-registry/rpc.md new file mode 100644 index 0000000000..fd112b1d2b --- /dev/null +++ b/docs/attributes-registry/rpc.md @@ -0,0 +1,91 @@ + + +# RPC + +## RPC Attributes + +RPC attributes are intended to be used in the context of events related to remote procedure calls (RPC). + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | +| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | +| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | +| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | +| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | +| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | +| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | +| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | +| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [5] | `exampleMethod` | +| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [6] | `myservice.EchoService` | +| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | + +**[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[2]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[3]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[4]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +**[5]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[6]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.connect_rpc.error_code` MUST be one of the following: + +| Value | Description | +|---|---| +| `cancelled` | cancelled | +| `unknown` | unknown | +| `invalid_argument` | invalid_argument | +| `deadline_exceeded` | deadline_exceeded | +| `not_found` | not_found | +| `already_exists` | already_exists | +| `permission_denied` | permission_denied | +| `resource_exhausted` | resource_exhausted | +| `failed_precondition` | failed_precondition | +| `aborted` | aborted | +| `out_of_range` | out_of_range | +| `unimplemented` | unimplemented | +| `internal` | internal | +| `unavailable` | unavailable | +| `data_loss` | data_loss | +| `unauthenticated` | unauthenticated | + +`rpc.grpc.status_code` MUST be one of the following: + +| Value | Description | +|---|---| +| `0` | OK | +| `1` | CANCELLED | +| `2` | UNKNOWN | +| `3` | INVALID_ARGUMENT | +| `4` | DEADLINE_EXCEEDED | +| `5` | NOT_FOUND | +| `6` | ALREADY_EXISTS | +| `7` | PERMISSION_DENIED | +| `8` | RESOURCE_EXHAUSTED | +| `9` | FAILED_PRECONDITION | +| `10` | ABORTED | +| `11` | OUT_OF_RANGE | +| `12` | UNIMPLEMENTED | +| `13` | INTERNAL | +| `14` | UNAVAILABLE | +| `15` | DATA_LOSS | +| `16` | UNAUTHENTICATED | + +`rpc.system` 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 | +|---|---| +| `grpc` | gRPC | +| `java_rmi` | Java RMI | +| `dotnet_wcf` | .NET WCF | +| `apache_dubbo` | Apache Dubbo | +| `connect_rpc` | Connect RPC | + diff --git a/docs/cloud-providers/aws-sdk.md b/docs/cloud-providers/aws-sdk.md index e412dba1d9..9eb2077746 100644 --- a/docs/cloud-providers/aws-sdk.md +++ b/docs/cloud-providers/aws-sdk.md @@ -28,9 +28,9 @@ with the naming guidelines for RPC client spans. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | Recommended | -| [`rpc.method`](../rpc/rpc-spans.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | Recommended | -| [`rpc.service`](../rpc/rpc-spans.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | Recommended | -| [`rpc.system`](../rpc/rpc-spans.md) | string | The value `aws-api`. | `aws-api` | Required | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | Recommended | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | Recommended | +| [`rpc.system`](../attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | Required | **[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index f2b9d9ca0c..dd590f75dd 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -16,12 +16,12 @@ described on this page. Below is a table of attributes that SHOULD be included on client and server Connect RPC measurements. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | Conditionally Required: [1] | -| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | +| [`rpc.connect_rpc.error_code`](../attributes-registry/rpc.md) | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | Conditionally Required: [1] | +| [`rpc.connect_rpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`rpc.connect_rpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | **[1]:** If response is not successful and if error code available. diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 52c4903568..100f17dc4b 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -16,12 +16,12 @@ described on this page. Below is a table of attributes that SHOULD be included on client and server gRPC measurements. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | +| [`rpc.grpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`rpc.grpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | +| [`rpc.grpc.status_code`](../attributes-registry/rpc.md) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index 32ebf65402..dbf79fca70 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -14,14 +14,14 @@ described on this page. `rpc.system` MUST be set to `"jsonrpc"`. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | Conditionally Required: If response is not successful. | -| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | Recommended | -| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | -| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | -| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Required | +| [`rpc.jsonrpc.error_code`](../attributes-registry/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | Conditionally Required: If response is not successful. | +| [`rpc.jsonrpc.error_message`](../attributes-registry/rpc.md) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | Recommended | +| [`rpc.jsonrpc.request_id`](../attributes-registry/rpc.md) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | +| [`rpc.jsonrpc.version`](../attributes-registry/rpc.md) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Required | **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index a27e701e93..22fe315550 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -222,9 +222,9 @@ measurements. |---|---|---|---|---| | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`rpc.method`](rpc-spans.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | -| [`rpc.service`](rpc-spans.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | -| [`rpc.system`](rpc-spans.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | [`server.address`](../general/attributes.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 695766872d..af881e2114 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -82,14 +82,14 @@ Examples of span names: ### Common attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | -| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | -| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: See below | @@ -109,6 +109,22 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + `rpc.system` 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 | diff --git a/model/metrics/rpc-metrics.yaml b/model/metrics/rpc-metrics.yaml index 43186b0765..ca29cdf194 100644 --- a/model/metrics/rpc-metrics.yaml +++ b/model/metrics/rpc-metrics.yaml @@ -7,6 +7,7 @@ groups: brief: "Describes RPC metric attributes." attributes: - ref: rpc.system + requirement_level: required - ref: rpc.service - ref: rpc.method - ref: network.transport diff --git a/model/registry/rpc.yaml b/model/registry/rpc.yaml new file mode 100644 index 0000000000..64f1f9a667 --- /dev/null +++ b/model/registry/rpc.yaml @@ -0,0 +1,190 @@ +groups: + - id: registry.rpc + prefix: rpc + type: attribute_group + brief: 'This document defines attributes for remote procedure calls.' + attributes: + - id: connect_rpc.error_code + type: + members: + - id: cancelled + value: cancelled + - id: unknown + value: unknown + - id: invalid_argument + value: invalid_argument + - id: deadline_exceeded + value: deadline_exceeded + - id: not_found + value: not_found + - id: already_exists + value: already_exists + - id: permission_denied + value: permission_denied + - id: resource_exhausted + value: resource_exhausted + - id: failed_precondition + value: failed_precondition + - id: aborted + value: aborted + - id: out_of_range + value: out_of_range + - id: unimplemented + value: unimplemented + - id: internal + value: internal + - id: unavailable + value: unavailable + - id: data_loss + value: data_loss + - id: unauthenticated + value: unauthenticated + brief: "The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values." + - id: connect_rpc.request.metadata + type: template[string[]] + brief: > + Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] + - id: connect_rpc.response.metadata + type: template[string[]] + brief: > + Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] + - id: grpc.status_code + type: + members: + - id: ok + brief: OK + value: 0 + - id: cancelled + brief: CANCELLED + value: 1 + - id: unknown + brief: UNKNOWN + value: 2 + - id: invalid_argument + brief: INVALID_ARGUMENT + value: 3 + - id: deadline_exceeded + brief: DEADLINE_EXCEEDED + value: 4 + - id: not_found + brief: NOT_FOUND + value: 5 + - id: already_exists + brief: ALREADY_EXISTS + value: 6 + - id: permission_denied + brief: PERMISSION_DENIED + value: 7 + - id: resource_exhausted + brief: RESOURCE_EXHAUSTED + value: 8 + - id: failed_precondition + brief: FAILED_PRECONDITION + value: 9 + - id: aborted + brief: ABORTED + value: 10 + - id: out_of_range + brief: OUT_OF_RANGE + value: 11 + - id: unimplemented + brief: UNIMPLEMENTED + value: 12 + - id: internal + brief: INTERNAL + value: 13 + - id: unavailable + brief: UNAVAILABLE + value: 14 + - id: data_loss + brief: DATA_LOSS + value: 15 + - id: unauthenticated + brief: UNAUTHENTICATED + value: 16 + brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." + - id: grpc.request.metadata + type: template[string[]] + brief: > + gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] + - id: grpc.response.metadata + type: template[string[]] + brief: > + gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + note: > + Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. + Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + examples: ['rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] + - id: jsonrpc.error_code + type: int + brief: "`error.code` property of response if it is an error response." + examples: [-32700, 100] + - id: jsonrpc.error_message + type: string + brief: "`error.message` property of response if it is an error response." + examples: ['Parse error', 'User already exists'] + - id: jsonrpc.request_id + type: string + brief: > + `id` property of request or response. + Since protocol allows id to be int, string, `null` or missing (for notifications), + value is expected to be cast to string for simplicity. + Use empty string in case of `null` value. Omit entirely if this is a notification. + examples: ['10', 'request-7', ''] + - id: jsonrpc.version + type: string + brief: "Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted." + examples: ['2.0', '1.0'] + - id: method + type: string + brief: 'The name of the (logical) method being called, must be equal to the $method part in the span name.' + note: > + This is the logical name of the method from the RPC interface perspective, + which can be different from the name of any implementing method/function. + The `code.function` attribute may be used to store the latter + (e.g., method actually executing the call on the server side, + RPC client stub method on the client side). + examples: "exampleMethod" + - id: service + type: string + brief: 'The full (logical) name of the service being called, including its package name, if applicable.' + note: > + This is the logical name of the service from the RPC interface perspective, + which can be different from the name of any implementing class. + The `code.namespace` attribute may be used to store the latter + (despite the attribute name, it may include a class name; + e.g., class with method actually executing the call on the server side, + RPC client stub class on the client side). + examples: "myservice.EchoService" + - id: system + brief: 'A string identifying the remoting system. See below for a list of well-known identifiers.' + type: + allow_custom_values: true + members: + - id: grpc + value: 'grpc' + brief: 'gRPC' + - id: java_rmi + value: 'java_rmi' + brief: 'Java RMI' + - id: dotnet_wcf + value: 'dotnet_wcf' + brief: '.NET WCF' + - id: apache_dubbo + value: 'apache_dubbo' + brief: 'Apache Dubbo' + - id: connect_rpc + value: 'connect_rpc' + brief: 'Connect RPC' diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 85f4449d41..29fa0bf9be 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -5,50 +5,10 @@ groups: brief: 'This document defines semantic conventions for remote procedure calls.' events: [rpc.message] attributes: - - id: system + - ref: rpc.system requirement_level: required - brief: 'A string identifying the remoting system. See below for a list of well-known identifiers.' - type: - allow_custom_values: true - members: - - id: grpc - value: 'grpc' - brief: 'gRPC' - - id: java_rmi - value: 'java_rmi' - brief: 'Java RMI' - - id: dotnet_wcf - value: 'dotnet_wcf' - brief: '.NET WCF' - - id: apache_dubbo - value: 'apache_dubbo' - brief: 'Apache Dubbo' - - id: connect_rpc - value: 'connect_rpc' - brief: 'Connect RPC' - - id: service - type: string - requirement_level: recommended - brief: 'The full (logical) name of the service being called, including its package name, if applicable.' - note: > - This is the logical name of the service from the RPC interface perspective, - which can be different from the name of any implementing class. - The `code.namespace` attribute may be used to store the latter - (despite the attribute name, it may include a class name; - e.g., class with method actually executing the call on the server side, - RPC client stub class on the client side). - examples: "myservice.EchoService" - - id: method - type: string - requirement_level: recommended - brief: 'The name of the (logical) method being called, must be equal to the $method part in the span name.' - note: > - This is the logical name of the method from the RPC interface perspective, - which can be different from the name of any implementing method/function. - The `code.function` attribute may be used to store the latter - (e.g., method actually executing the call on the server side, - RPC client stub method on the client side). - examples: "exampleMethod" + - ref: rpc.service + - ref: rpc.method - ref: network.transport - ref: network.type - ref: server.address @@ -76,7 +36,6 @@ groups: recommended: If `network.peer.address` is set. - id: rpc.server - prefix: rpc type: span extends: rpc span_kind: server @@ -94,85 +53,19 @@ groups: - ref: network.type - id: rpc.grpc - prefix: rpc.grpc type: span extends: rpc brief: 'Tech-specific attributes for gRPC.' attributes: - - id: status_code - type: - members: - - id: ok - brief: OK - value: 0 - - id: cancelled - brief: CANCELLED - value: 1 - - id: unknown - brief: UNKNOWN - value: 2 - - id: invalid_argument - brief: INVALID_ARGUMENT - value: 3 - - id: deadline_exceeded - brief: DEADLINE_EXCEEDED - value: 4 - - id: not_found - brief: NOT_FOUND - value: 5 - - id: already_exists - brief: ALREADY_EXISTS - value: 6 - - id: permission_denied - brief: PERMISSION_DENIED - value: 7 - - id: resource_exhausted - brief: RESOURCE_EXHAUSTED - value: 8 - - id: failed_precondition - brief: FAILED_PRECONDITION - value: 9 - - id: aborted - brief: ABORTED - value: 10 - - id: out_of_range - brief: OUT_OF_RANGE - value: 11 - - id: unimplemented - brief: UNIMPLEMENTED - value: 12 - - id: internal - brief: INTERNAL - value: 13 - - id: unavailable - brief: UNAVAILABLE - value: 14 - - id: data_loss - brief: DATA_LOSS - value: 15 - - id: unauthenticated - brief: UNAUTHENTICATED - value: 16 + - ref: rpc.grpc.status_code + tag: grpc-tech-specific requirement_level: required - brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." - - id: request.metadata - type: template[string[]] + - ref: rpc.grpc.request.metadata + tag: grpc-tech-specific requirement_level: opt_in - brief: > - gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. - note: > - Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. - Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - - id: response.metadata - type: template[string[]] + - ref: rpc.grpc.response.metadata + tag: grpc-tech-specific requirement_level: opt_in - brief: > - gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. - note: > - Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. - Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] - id: rpc.jsonrpc prefix: rpc.jsonrpc @@ -180,31 +73,20 @@ groups: extends: rpc brief: 'Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/).' attributes: - - id: version - type: string + - ref: rpc.jsonrpc.version + tag: jsonrpc-tech-specific requirement_level: conditionally_required: If other than the default version (`1.0`) - brief: "Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted." - examples: ['2.0', '1.0'] - - id: request_id - type: string - brief: > - `id` property of request or response. - Since protocol allows id to be int, string, `null` or missing (for notifications), - value is expected to be cast to string for simplicity. - Use empty string in case of `null` value. Omit entirely if this is a notification. - examples: ['10', 'request-7', ''] - - id: error_code - type: int + - ref: rpc.jsonrpc.request_id + tag: jsonrpc-tech-specific + - ref: rpc.jsonrpc.error_code + tag: jsonrpc-tech-specific requirement_level: conditionally_required: If response is not successful. - brief: "`error.code` property of response if it is an error response." - examples: [-32700, 100] - - id: error_message - type: string - brief: "`error.message` property of response if it is an error response." - examples: ['Parse error', 'User already exists'] + - ref: rpc.jsonrpc.error_message + tag: jsonrpc-tech-specific - ref: rpc.method + tag: jsonrpc-tech-specific requirement_level: required note: > This is always required for jsonrpc. See the note in the general @@ -235,64 +117,17 @@ groups: brief: "Uncompressed size of the message in bytes." - id: rpc.connect_rpc - prefix: rpc.connect_rpc type: span extends: rpc brief: 'Tech-specific attributes for Connect RPC.' attributes: - - id: error_code - type: - members: - - id: cancelled - value: cancelled - - id: unknown - value: unknown - - id: invalid_argument - value: invalid_argument - - id: deadline_exceeded - value: deadline_exceeded - - id: not_found - value: not_found - - id: already_exists - value: already_exists - - id: permission_denied - value: permission_denied - - id: resource_exhausted - value: resource_exhausted - - id: failed_precondition - value: failed_precondition - - id: aborted - value: aborted - - id: out_of_range - value: out_of_range - - id: unimplemented - value: unimplemented - - id: internal - value: internal - - id: unavailable - value: unavailable - - id: data_loss - value: data_loss - - id: unauthenticated - value: unauthenticated + - ref: rpc.connect_rpc.error_code + tag: connect_rpc-tech-specific requirement_level: conditionally_required: If response is not successful and if error code available. - brief: "The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values." - - id: request.metadata - type: template[string[]] + - ref: rpc.connect_rpc.request.metadata + tag: connect_rpc-tech-specific requirement_level: opt_in - brief: > - Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. - note: > - Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. - Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - - id: response.metadata - type: template[string[]] + - ref: rpc.connect_rpc.response.metadata + tag: connect_rpc-tech-specific requirement_level: opt_in - brief: > - Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. - note: > - Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. - Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - examples: ['rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] From 6a2519baeb511bd81adf87297ea959587f2f2201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zapa=C5=9Bnik?= <9281806+adamzapasnik@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:36:02 +0300 Subject: [PATCH 107/482] Update http-spans.md (#437) --- docs/http/http-spans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index ec510f4c91..27f2aee1b9 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -74,7 +74,7 @@ If there is no (low-cardinality) `http.route` available, HTTP server span names SHOULD be [`{method}`](#method-placeholder). 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 be +is not generally aware of the "route", and therefore HTTP client span names SHOULD be [`{method}`](#method-placeholder). From 5aa01542b97e73a0c48a60bd71d762017d0d65e1 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 24 Oct 2023 09:42:11 +0200 Subject: [PATCH 108/482] BREAKING: Use seconds as default duration for FaaS duration histograms (#384) Co-authored-by: Trask Stalnaker Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/faas/faas-metrics.md | 18 +++++++++++++++--- model/metrics/faas-metrics.yaml | 6 +++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a0027724c..527764e4a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ release. ([#297](https://github.com/open-telemetry/semantic-conventions/pull/297)) - Fix `server.port` to be not required when `server.address` is not set. ([#429](https://github.com/open-telemetry/semantic-conventions/pull/429)) +- Use seconds as default duration for FaaS duration histograms + ([#384](https://github.com/open-telemetry/semantic-conventions/pull/384)) ### Features diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index b64d90dd01..e84a0921dc 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -45,10 +45,14 @@ The following metrics are recorded by the FaaS instance. This metric is [recommended][MetricRecommended]. +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `faas.invoke_duration` | Histogram | `ms` | Measures the duration of the function's logic execution | +| `faas.invoke_duration` | Histogram | `s` | Measures the duration of the function's logic execution | @@ -71,10 +75,14 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `faas.init_duration` | Histogram | `ms` | Measures the duration of the function's initialization, such as a cold start | +| `faas.init_duration` | Histogram | `s` | Measures the duration of the function's initialization, such as a cold start | @@ -227,10 +235,14 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `faas.cpu_usage` | Histogram | `ms` | Distribution of CPU usage per invocation | +| `faas.cpu_usage` | Histogram | `s` | Distribution of CPU usage per invocation | diff --git a/model/metrics/faas-metrics.yaml b/model/metrics/faas-metrics.yaml index 6a753a7351..d68119f320 100644 --- a/model/metrics/faas-metrics.yaml +++ b/model/metrics/faas-metrics.yaml @@ -4,7 +4,7 @@ groups: metric_name: faas.invoke_duration brief: "Measures the duration of the function's logic execution" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: faas.trigger @@ -13,7 +13,7 @@ groups: metric_name: faas.init_duration brief: "Measures the duration of the function's initialization, such as a cold start" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: faas.trigger @@ -67,7 +67,7 @@ groups: metric_name: faas.cpu_usage brief: "Distribution of CPU usage per invocation" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: faas.trigger From bf2a10db509b14269f5c5cc561ccf5e35526def3 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 25 Oct 2023 00:56:28 -0700 Subject: [PATCH 109/482] should -> SHOULD (#442) --- docs/attributes-registry/url.md | 4 ++-- docs/database/elasticsearch.md | 4 ++-- docs/http/http-spans.md | 4 ++-- docs/url/url.md | 4 ++-- model/registry/url.yaml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index 60f99ea205..f3997f3d96 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -14,8 +14,8 @@ linkTitle: URL | `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | | `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | -**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. **[2]:** When missing, the value is assumed to be `/` diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 330bdbacfe..1d82327cee 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -67,8 +67,8 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +**[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 27f2aee1b9..5791fac6a5 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -249,8 +249,8 @@ If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x. **[4]:** If not default (`80` for `http` scheme, `443` for `https`). -**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/url/url.md b/docs/url/url.md index e337f68a37..a85c4cbb59 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -31,8 +31,8 @@ This document defines semantic conventions that describe URL and its components. | [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | -**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. **[2]:** When missing, the value is assumed to be `/` diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 7443e87919..ea626baa32 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -13,10 +13,10 @@ groups: brief: Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) note: > For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment - is not transmitted over HTTP, but if it is known, it should be included nevertheless. + is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. - In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. + In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. From 384edab5106016fa974693bce93e0fcb0d230d3e Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 25 Oct 2023 11:03:47 -0700 Subject: [PATCH 110/482] Editorial: Fix url.scheme examples on http client metric (#445) --- docs/http/http-metrics.md | 6 +++--- model/metrics/http.yaml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 93a393b50e..e514452a41 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -514,7 +514,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -610,7 +610,7 @@ This metric is optional. | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -706,7 +706,7 @@ This metric is optional. | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index a791b0f070..3a9984368b 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -43,6 +43,7 @@ groups: attributes: - ref: url.scheme requirement_level: required + examples: ["http", "https"] - id: metric.http.server.request.duration type: metric From b8a493b915d2b6fc25c07be4099001eb6e8c50e1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 25 Oct 2023 14:11:44 -0700 Subject: [PATCH 111/482] Remove outdated section in rpc-metrics.md that no longer applies (#447) --- docs/rpc/rpc-metrics.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 22fe315550..4821b500e7 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -271,10 +271,6 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `connect_rpc` | Connect RPC | -To avoid high cardinality, implementations should prefer the most stable of `server.address` or -`server.socket.address`, depending on expected deployment profile. For many cloud applications, this is likely -`server.address` as names can be recycled even across re-instantiation of a server with a different `ip`. - For client-side metrics `server.port` is required if the connection is IP-based and the port is available (it describes the server port they are connecting to). For server-side spans `server.port` is optional (it describes the port the client is connecting from). From 6121966bf71a3d86061178375c163d8ddd075378 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 25 Oct 2023 23:02:44 -0700 Subject: [PATCH 112/482] Rewrite HTTP server definitions section (#423) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 2 + docs/http/http-metrics.md | 158 ++++++------------------ docs/http/http-spans.md | 115 +++++++---------- docs/http/reverse-proxy-http-server.png | Bin 0 -> 175136 bytes docs/http/simple-http-server.png | Bin 0 -> 82962 bytes model/http-common.yaml | 35 +----- model/metrics/http.yaml | 67 +++------- 7 files changed, 107 insertions(+), 270 deletions(-) create mode 100644 docs/http/reverse-proxy-http-server.png create mode 100644 docs/http/simple-http-server.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 527764e4a6..e1382e9c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ release. ([#412](https://github.com/open-telemetry/semantic-conventions/pull/412)) - Remove outdated note about not recording HTTP `server.address` when only IP address available. ([#413](https://github.com/open-telemetry/semantic-conventions/pull/413)) +- Clarify HTTP server definitions and `server.address|port` notes. + ([#423](https://github.com/open-telemetry/semantic-conventions/pull/423)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index e514452a41..2dcfd27171 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -125,31 +125,15 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies: - -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. -- 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header. - -MUST NOT include the port identifier. - -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. - -**[7]:** Determined by using the first of the following that applies: - -- Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header. +**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -210,31 +194,15 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** Determined by using the first of the following that applies: - -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. -- 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header. - -MUST NOT include the port identifier. - -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. - -**[3]:** Determined by using the first of the following that applies: - -- Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header. +**[2]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. +**[3]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. `http.request.method` 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. @@ -318,31 +286,15 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies: - -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. -- 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header. - -MUST NOT include the port identifier. - -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. - -**[7]:** Determined by using the first of the following that applies: - -- Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header. +**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -434,31 +386,15 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** Determined by using the first of the following that applies: - -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. -- 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header. - -MUST NOT include the port identifier. - -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. - -**[7]:** Determined by using the first of the following that applies: - -- Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header. +**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. -Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker -to trigger cardinality limits, degrading the usefulness of the metric. +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +> **Warning** +> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -552,15 +488,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** 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. - -If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then -`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -648,15 +578,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** Determined by using the first of the following that applies: +**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -- 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. - -If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then -`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -744,15 +668,9 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** 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. - -If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then -`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[7]:** If not default (`80` for `http` scheme, `443` for `https`). diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 5791fac6a5..e57d33931f 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -22,6 +22,9 @@ and various HTTP versions like 1.1, 2 and SPDY. * [HTTP request retries and redirects](#http-request-retries-and-redirects) - [HTTP server](#http-server) * [HTTP server definitions](#http-server-definitions) + + [Setting `server.address` and `server.port` attributes](#setting-serveraddress-and-serverport-attributes) + + [Simple client/server example](#simple-clientserver-example) + + [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) * [HTTP Server semantic conventions](#http-server-semantic-conventions) - [Examples](#examples) * [HTTP client-server example](#http-client-server-example) @@ -237,15 +240,9 @@ For an HTTP client span, `SpanKind` MUST be `Client`. **[1]:** 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). -**[2]:** Determined by using the first of the following that applies: +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -- 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. - -If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then -`server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - -**[3]:** When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier; otherwise, it MUST match `Host` header port identifier. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[4]:** If not default (`80` for `http` scheme, `443` for `https`). @@ -294,52 +291,47 @@ See the examples for more details about: ## HTTP server -To understand the attributes defined in this section, it is helpful to read the "Definitions" subsection. +Read the following section to understand how HTTP server instrumentations are suggested to capture server information. ### HTTP server definitions -This section gives a short summary of some concepts -in web server configuration and web app deployment -that are relevant to tracing. - -Usually, on a physical host, reachable by one or multiple IP addresses, a single HTTP listener process runs. -If multiple processes are running, they must listen on distinct TCP/UDP ports so that the OS can route incoming TCP/UDP packets to the right one. - -Within a single server process, there can be multiple **virtual hosts**. -The [HTTP host header][] (in combination with a port number) is normally used to determine to which of them to route incoming HTTP requests. - -The host header value that matches some virtual host is called the virtual hosts's **server name**. If there are multiple aliases for the virtual host, one of them (often the first one listed in the configuration) is called the **primary server name**. See for example, the Apache [`ServerName`][ap-sn] or NGINX [`server_name`][nx-sn] directive or the CGI specification on `SERVER_NAME` ([RFC 3875][rfc-servername]). -In practice the HTTP host header is often ignored when just a single virtual host is configured for the IP. - -Within a single virtual host, some servers support the concepts of an **HTTP application** -(for example in Java, the Servlet JSR defines an application as -"a collection of servlets, HTML pages, classes, and other resources that make up a complete application on a Web server" --- SRV.9 in [JSR 53][]; -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 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 -to the `com.example.webshop` web application). - -Some servers allow to bind the same HTTP application to multiple `(virtual host, application root)` pairs. - -> TODO: Find way to trace HTTP application and application root ([opentelemetry/opentelementry-specification#335][]) - -[HTTP host header]: https://tools.ietf.org/html/rfc7230#section-5.4 -[PEP 3333]: https://www.python.org/dev/peps/pep-3333/ -[modwsgisetup]: https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html -[context root]: https://docs.jboss.org/jbossas/guides/webguide/r2/en/html/ch06.html -[context prefix]: https://marc.info/?l=apache-cvs&m=130928191414740 -[document base]: http://tomcat.apache.org/tomcat-5.5-doc/config/context.html -[rfc-servername]: https://tools.ietf.org/html/rfc3875#section-4.1.14 -[ap-sn]: https://httpd.apache.org/docs/2.4/mod/core.html#servername -[nx-sn]: http://nginx.org/docs/http/ngx_http_core_module.html#server_name -[JSR 53]: https://jcp.org/aboutJava/communityprocess/maintenance/jsr053/index2.html -[opentelemetry/opentelementry-specification#335]: https://github.com/open-telemetry/opentelemetry-specification/issues/335 +An HTTP request can be routed to a specific HTTP application via intermediaries such as reverse proxies. +HTTP requests sent to the same domain name may be handled by multiple applications depending on the port, path, headers, or other parameters. + +For example, different versions of the same web-application can run side-by-side as independent applications behind the reverse proxy which routes request to one or another based on the request path. + +Instances of different HTTP server applications may run on the same physical host and share the same IP address, but listen to different TCP/UDP ports. +In order to route the request to a specific application, reverse proxies usually modify the [HTTP Host header][Host and authority] replacing the original value provided by the client with an actual proxied server name. This behavior depends on the reverse proxy configuration. In some cases, the `Host` header is not used when routing request to a specific application, making it prone to having bogus content. + +HTTP server frameworks and their instrumentations have limited knowledge about the HTTP infrastructure and intermediaries that requests go through. In a general case, they can only use HTTP request properties such as request target or headers to populate `server.*` attributes. + +#### Setting `server.address` and `server.port` attributes + +In the context of HTTP server, `server.address` and `server.port` attributes capture the original host name and port. They are intended, whenever possible, to be the same on the client and server sides. + +HTTP server instrumentations SHOULD do the best effort when populating `server.address` and `server.port` attributes and SHOULD determine them by using the first of the following that applies: + +* The original host which may be passed by the reverse proxy in the [`Forwarded#host`][Forwarded], [`X-Forwarded-Host`][X-Forwarded-Host], or a similar header. +* The [`Host`][Host header] header. +* The [`:authority`][HTTP/2 authority] pseudo-header in case of HTTP/2 or HTTP/3 + +> **Note**: The `Host` and `:authority` headers contain host and port number of the server. The same applies to the `host` identifier of `Forwarded` header or the `X-Forwarded-Host` header. Instrumentations SHOULD populate both `server.address` and `server.port` attributes by parsing the value of corresponding header. + +Application developers MAY overwrite potentially inaccurate values of `server.*` attributes using a [SpanProcessor][SpanProcessor] and MAY capture private host information using applicable [resource attributes](/docs/resource/README.md). + +#### Simple client/server example + +![simple-http-server.png](simple-http-server.png) + +#### Client/server example with reverse proxy + +![reverse-proxy-http-server.png](reverse-proxy-http-server.png) + +[Host and authority]: https://tools.ietf.org/html/rfc9110#section-7.2 +[Host header]: https://tools.ietf.org/html/rfc7230#section-5.4 +[HTTP/2 authority]: https://tools.ietf.org/html/rfc9113#section-8.3.1 +[Forwarded]: https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded +[X-Forwarded-Host]: https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host ### HTTP Server semantic conventions @@ -370,25 +362,9 @@ For an HTTP server span, `SpanKind` MUST be `Server`. **[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** Determined by using the first of the following that applies: - -- The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. -- 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Host identifier of the `Host` header. - -MUST NOT include the port identifier. - -**[5]:** Determined by using the first of the following that applies: +**[4]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -- Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. -- Port identifier of the `Host` header. +**[5]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). **[6]:** If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). @@ -581,3 +557,4 @@ Span name: `POST /uploads/:document_id`. | `error.type` | `WebSocketDisconnect` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[SpanProcessor]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/sdk.md#span-processor diff --git a/docs/http/reverse-proxy-http-server.png b/docs/http/reverse-proxy-http-server.png new file mode 100644 index 0000000000000000000000000000000000000000..1649e41255ff36367c89bab9b30e17fdcc3c0ec4 GIT binary patch literal 175136 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 z zc{vv7)KiHaUt3AfJ=Acd0?+-Gh38f3r>d)1?^$|bxbIIy+yDc6bo{_nt^j3Mg1NsLba~dslOk6tp zYi*QKVfItSQKcGrHJQ&k?mBO{W6#eVK-37Ty^Vq6ICeRI1)@t6MIb}v&g<7zUKS%T zK%_`rP;WVqN_$h|N2Q{xDBMf+G1XgICnjf5lw#29J~=1JReki2>Z->Jtxhjf>cwAq z494}LTJc;x^z>K+jZZHr=t2FtOc_jbOuw>(gPh3!`Y-U3sHbRn#V%?RlZDUL9rg>YU3C{(l?4lbS>`b+f#+i0$a9eOU%CRa2+ajo=X0+c|qw+ z8nhyh7X3n>Bk;R}imi9<@LFI~mR>0+c0%HDS9W(`CSPu_fXnorDKb0q%`7Id76KPn zzyTVV1!7S;feQhY2Fhycd&-36M&@|*kPE2=wxrN3rWA}8bBx4xg>`()E;l*7j&58 z@*2@Kx!IkV_t5$)(v`){m4b`4h(k=9`0S%yyj)lK&vQKt zFa;dF2uvSklUW?;)4~(>{|)tHTW*Sb*YVt@`}&YU;&MAR{2Yp80=ForPPIZ@9-dMl%{| z0bzuIbT=rCbV`j71f)S4Mu?zvcSv`4jqZ@{Zjg}fv){R{b6w|8*!JFgp7;L7$ISE? zO}Rz>S)NM1RUQsR;;=y8uT+3Q25=w)3DzdWn7kYxyChy-iYJy{R7$Tcf-g%P@W}c2@l54*mc$$GaN5@n)uGI zwWjfak&ugO;usHjw1ab&ibbg@*3pLf>zROC6cXXxF4oL>ZZ`5cCvglR8|lXbuVE=% z%ym(dJRP9O7XWP!Q5MJ{(ABlCiubWuSal2f7VTQrm7RZ+N|&nC(OZ>keizOSkT&=V zvcef5BjqWl{EFh2m+I$_CfOCfM__MipM}BcTAgbq1=Vy^-4xK2{&Cg6hJx1vRPOaX zJ@4Sosmr0f&)iy|u~0uMekwg5M}u+ty-HH*Y5GK%zK~t>Z;6rRf{~O`_+?l2Uwrjd z0|)s>#JG7O*ZaA|{@V@H@$UYnaB}->SD=rWHx==xX&~jAZ$}S(jIfs;O*T!Z_;2kn zddaR|KuG9wwj}N7vEk?V*OPyWICp`lQIL!Ql+tFjP}WIewM~Dp1ZIYclghCPQB=s3+&$1A8U^=; z+8KZ@fOw3oWxBD+70E2zTAv@RZP%(-IdR2q&*2d=oW-;W47AeQOFoqQXRkz7yMgGF&LJIXAnY=p}LHe;G9kO53 z^}HmwVeeYz2L1TFpkuIiq-3{VG<3yAoV)Cx3uFfrzVJb(`Eh`WTs637!wdfIT8@;X z%WS8wMP`4DP3MvA`Q$SKXjdy4=u6`Kb~tw4koL(8=4wmME}R%F{z3Opq@s8M&HhaCOkaM zS~xH19Gs!})V86(85WP+1Z{DOFMWMJqb2x8Wd~rgYz1b}?+iuHLOTZ?%NOS@)L0%3 zGEz;Aka5>qJTdgg2|nL$x%R%&**|+v{uak7^p~-!Jjxx01YQ+CAIPlxH0T-dP3|OG zkES6@knH1`zrX9Jhq{V;)4sxpJ6I$UBl&Hx>Ll;naKO)BaT*&mPe)sWClmRj_-JoA zsYL&MTf;3SKr1z8DPS@hp8DzP(6*@Xc6mFQazGzYsmqSY{ozWm#v6%SinTBlo)8F3 z(Xr5$129l=I;#QTk|hRhh1prus1V*fW3TXsP($4l5M780k@n_%*-=cEkOGaB$r{ob zjaBvhxss)N%R7#u9guE9&^ZeY!3e(2W__9^?VGg#Y4y6$TX6hhX@>HlQ+`I$-Q)QE z>&R^uah9)tKB^%j?)TEjPOFDmkG=Lq-suSn2gp;7b7e{(O2ow0%0yC?$s3Ppc$O!o zMB%mII>asH{*x0C}!~P=rJRrw%xR`a8cdg9!Jo-^)i~s_5hl_}+%-KH^Kl=9f z1I;vX0hzVO-n=S45p>fk;R99$0?A%Qb*V&x#I28+JB{jSz2EC3wP1O>D3h4&^!_*!2% zB6o!Jy{-#NeyiuzilfuaM$l5@nvRkJ5@zjU$+g3)zAZ1JDUpNJ0DXn5AegB-eIGK# z?#LF-Oj*M>og01o=fTG33WF$N+Z3o%TwQ&`p!n9>yQnj|(3cYl|27o*YfCAk+1V36 zM-lM?rBW?LllG2UQw6=y1q3WS&tf#?;JlwY@{VuX>MeZ`m_zVjT=8ZdRh}J=JV+DD zg^{nt{{~<7XMh1x6zoGXG8tZg7o`TRvV!sc@Nmp>N>F#0Vl;1KF>5CpG1B)Jf9~rb z+lii+4&R?~fCoARpbBD+wT>i{2YffhsYHx2Ba_kx0iVQWOg+Hpf$mY)ZPb}sepM)o z^$J!L+6T#rYg4~oy!8(b4y>2gB@BHXg$=(gd@i1%iQ?B4`~*nb_PoD8s&Lh>F#1$O zJpOC)ouHteU(-J%*T2h>Z_!>KnN`}x|C~&;nQeA&dt9Wrf4ms4vlu0R?Rfh}=z1Vu zXz#ej<nm+J660f-$EO?noc&8s{P!z);au*dLSeh z8!=NDja#TZ1Iaw@mIFF$d?KZV$@ctF`dBloxCEe`7w+84`>WsjhY3a)|K-c__-fHd zkuIB#h19IBEU2;Lr!FHP<>rIK455xG{}i_nDb^e?_xl47Hnh53vNOM$t5XALCRw;4y1(i?@Pp^^zD*SDJKRZuhSV;&qynL53kA z?(c(23LSncZ=$7k5jaYqJv$B=2@24_W&Lv#2_0DqFm23uCt;?3L)2_&M z(JKYzK18EA=t|HIVu%!+LJAnNv)PMF0As582{Hs>tocr@e))q~q~bT{U1p4%Qc1<61-1WxRn0kyfB3m5OMxS zoQoRI%!P&#$))*jna=fqKJm*y)Elqcy_{oX8B?@@DziS^m&PYjGa4k+q31;zy2o?$ zM*`KHF30{NQQ=QfFNcrjmUMyXs7@t04|hS*Of4r z4ietDVa+#T+$$a9^nYe7KO)VlkSrRW7y}vRkY-)z943Zc?hc&^u63Cp(l`Qi*wR0 z`=^suI080YpdhW^_BDvNWLC}tWwPV>E=)%JJT0O85{?Cvx3eoBd+rWx_M1pA)+;EF zMB(ghfD}bM3)>`@H|>(U`LxtLXQ7?8$ZEy1^lXc{dsW*1GZEwo1ES$v>aEZ9nA3Ck zMWJem3VahEp~wKP6P2?DLcWW>%3SXxgQ4vPdN3*B#8PlpzFYGki;2xf*76)l?afuL zzd8F3EUf8!MoP>*g#5qB^`%8xus6sJ$U80cK6F%QvRJgMV4DK;|3}V6p!$^TeZ(4i z_G6LpcLB%X5=iHr>IM~^#~G?C0(t(l1{mpVe~v& zsETN}F0*U9Z_d-#+4~-yl(fGYaQEdpKfXBs>ub;b>`!TGV{OC@7Qv`1Qz{pG<2ntg z_J2ZkmW!D&r0@5(x-YMn?2nF}$J8!j*(W4F;>`SfdulVVE@{28i+n}OHR}`A3yXOZw?HYtF`iqPa`@fG&-oL zFcb{%GZTj%I0XI+g$C3S=WsCl_DEFs^D7rp775fB%$*&Duw=(7Dj2V3Vs@G3F`4fg z#XK5QU;}!7t$XVHksiwA^p$U9o%oe*oz+xdrk%{Y|J0`!guCv`nSKA|ffv0fXMW%5 zt7&w0+ROVuTru5BF~149fAtkNT77~u=vAmyI6RI(4|OEGi_&hM@G9G>eAImI=@A3=y-tg zv&5(N=dWK^m$52e_ABvEGTMFYbP_3An!C{vePQaOsdwQr;x`%3PnqK`y`K{g&+g-S zc28sDGNSb+Ra$D4b^4uEG^I>Yo-BuuK6>tn_EX81YpS`et}5!h+}+1mZU$C6jyheD zKc|`bPRNLJ=)N8kl5}KNcZ?5C;k0Z=#ckBDK~ztRS0Ip3LT)FeTEmI^y@^IznNlR?42Ly^G<6%Q?*4eN9F# zT3L|qeGz^_ebZXZYm-MVI6QrNos@0Wt1#Gnm4V;9b9l|n#H4Csl1*%>rOIbS#hd3* zlV60Oom#t2S~YvklWJ8Mt@I9Pr3{`sQ9ge!sr0T{Ra6=Aj_;)9G*#wcY@8(}my-kt zgDHVMrYe=Ia@wV)n3E|7lJW@fM`#~2Y9!Lea@5?IPx^6u$i$XSBpDizjKT^uRz8u*?z z`J?f1tk!)u8qmRXm=*&AoAJyb@GboygA?$gj3yezWg{rld@(#7lB8b!?y<%_R;sv5 zSne+|LW4AvpPos1SfMp^TT-=Mt{oJmZBmapX(>o#d)~Sl8eAyH@BVT0oy1u4skx5V zX__?MVN)J~Tu!~eJTATwd#+#;s7Mc9d&w%+#*X?1Bg^H}N-d7ZSdoj>={QV?3&MJ#;CIBrFv*V^Xnb z#+W>jeJf1yJ;%nw(Y|FSs3JbARuBAC%e2#d(*& z@~1`OZwpxSDy7Ktq-oFhvS9`mf!IV-yr})6qDH7Sa5g$sB!_8HqqjPz?WI1+r~<(_ zuZ!hl8LWng#+6`pk^Yc)j?!r8W&s?-D=8Y-2&^=bXOv%?qukUy6C>wQ?vTe5j7Ni_ z4;w(h@jP+Lm3Wk*Cs^yfp(clynm z^6@cOn^@x|S`zXyCtXQc+DcQrI^U*8`PWLR+B|J6K6&&LebIfZg0M+UBBaFWgNO}v zb*C5kFa zW9KS#WuB1XO~75?AgdEKxeb~#C|DWsRabtulqDU2icWo#W1J56hyYl05=egPYB#qf zW1QP1mj6+$!t6`hEAbmWb5JT-fN2OjP^tK`{MU0JsE>ar>lpnua=X6y zJdSly=ek3Awa>2<+mV*fnIl`=ExmV_)I7vI;7@S%yi{?}r|-!k*c6lDzHXQ9X(!7r z*_qfC9~gcCj{_P3Kma|tpOpJVNe#e&&cbXV%yZPoMUkny_(uuyZLsYhTK=Cv&E-fJ zWLPJR6;2ArHs|c4G)+(MP*@+8k~hiN3$qEd7G&e6YafY`Be1N?k7T%T_=&DdAPdJsysGk_Jd<6 z+)e4U_$;a*QR4bls#hqlWU1-A{!JKueTIeBP|&dEJT7{_9jkJ=lW5%h!NDit<_CHr zRWB0}9#R5uR0QX&qH=?F*n#ozoYNuDCYm8ig!Tzg%Tc2Uz%7oZvCIx)%mA|`FEhM0 z=wZCfOBeU$$hYtLpRiSuwGI}ilY zw!gT@6yE7j{xyUartv(#0z@W_wJeY!5p~PB7r6|3o@kaH8HVKOjz4XEezN^w zd;{DKwp*FW?{+Oti`xez-Zq+UBzL9oe*M;XA4Xch{fST8K(hRV%DuwK%Ok+kU#wtGSBzdaq{-%j?@+O_QFyXgNWb);nP31@zs8ci1}R;%geJvn#$&5RC5 zI_lbsap)zKzzP!tc7}*z!_j5XJ`juW&C?qp+h^StYrTJQ$5DG=7uMjA=zG|=2iNZ zI$|49!VoOjQXq~Ars9GT#Y2&0+F#{u3*{$I6~C+BNB?=7=lk(*1$QD%Y#_!if9%4o zZ_bGf+>*DBN(5}m2qF)E=hkE{Grot@;2&(Ry*#_EQLkb_oYQ>uC&|+^g+oJtWTc9A zL9PJMCaE76E_#(upeDF1mhg#OvNvYI$W-Dxfeno5v0K%}(o7|cvkX$mf~F|1qr8Y4 zMxS1Oyid$-%c1wHq_(;bL=h+DYHzxf=c?gDVEalSEt_8b6$=G9_$P9ThNoDVW?_Dn zpVv&hUIX91PW(gnUh1a?4sgBw!~-|qexIGF0ey-iF1Ax?u-%Qw@4Gd2<~#5PfS43H zY&gckoa}BXUO%r1Bm-SG@*M0Xcha}a(=1-^x0fl?^nO!SzSvX6UAT?rpNDRUDTL(M_?j+;)Z4CbD9zi;9A8Fmok z1xCN!-^%~}-0OdROod;uzNqdT)oBe;cP!f~`4X(pXZ~q@x?bXSJ=AQwuNW*RK*9J; z-{wvkb-86J;YvV$x;Mq=3GY^(mcK2kS7+luuDe_Bg_-+9NSXrab0BG04RXnM8E++H zpPW8rN(owKD`JTfM5hbBm?lJl*2nacQ}22mx14P!I4yI zyig;w|KndJr0m;om4M-zugVt*rRwAQ_J4lcTNc?OsB|ImxtXZzvBs)}DvV*XJ)wl@ zyS1J*+IBbtqyVK=?~9LD`+wf2w_IsI*t7_9z>_`qc8gD8URQlAggno8I<6;Hw#(e| z`Qqtqnkv}G`O<6SI$I1MT}@jQXAa}IU8HK76+&2C#wi~L=!WD}=Ez74%O8HMmI%!- zTm9`TYd)W)O1Ze&jwwTyn6zAX;Qg{>gciS4*y82pX7~3!m9OSU^Y48RX5 zVzw!E2g_OS0VLYCK|h?|9iv^#HzJKqhpVf5oc3;zk{>)fgW}!i zg;9|Kr8FpxBjH1w97q%Xb45V`M1AprA1`d0odtFK00O`-l5{7>hH$nE{|(n`t@*bxBzTUuHYC^!a>bOzw7zBMB~EnlEi}+IFX&- zvoa{j=udM5PBqGEW?<-j1g&Z?ZRO^?+07T8&!J^iCBS|_1Vy~dHK7+zfw5 zE1chYXDB}9c3PEw&bqL?;mS=W=j8rk{9jmbSl+g5xix?QwsknnJ`Gzc*Xgys z63qfqAo+y^DYSnI&;8F}foRx@jbUNfPjMeRT)WNg4k#$^= z`)e^h-vl>IE#BJygb**gP=ZXKuV^o;>VA7_+~r|(uJ|Z(Ov~FED{*_z-0n}M*Td0w zzxEuVI_v$S{{G^f^Mcza_^pX!WqDs36s%98C|vIj>jA5V5+22n7mw6*=KdGr!~X_& z)t8^`vk@k#TC8pkf zR{3vg1|3)-hxk8#7Lk8C9TXgKdtbnGS3LfWB8v;#!R2(-(0R|N#DDyyMN?20?bFwP zlgLA1)~ITmwduKWJ@^~|JY*RZ zV~{!G(Y66PWGyq!=^f}PAI$B#o5?~DrH{0vGDt>AVMrdxU}P{;wBXs-XHJIa&S{Ag zDWs8GlhPuK34Hf8M-uHS9o!(uL(98>AY+d&R_aRM-y)e6@)6e6V9=lY2ST&gUUXtrzq#r+HD9{5TkL$W z{l4UmiR~bh+zkGzKRlNd<@q~I3U`$4@E1C6?I@Hk6PS@3mk~buXYm zrx;Me)EH4`G{HfGgom~Z`bx1)Wx;$nPomfUDZ8k2K z;kOSL#n#;=ywXf-Qx26~%gwF14zD`D+smwIc0GEY2n>{TmcnlAlotuZnR@q$3qx-G z5ff<_B=iA}6ANvOy}6{>z+O!Qu*>1a3ZP&pq6T~*T&Lv}v@mUQ=29Y1ngrjfspIfX zG0s8Y05XPO>v0)Fth|9AQrf3>J@kW`<(Bg{k8WzP~v- z1G*Jz-_>S)uzLM;(~&VFpL*LR&_BtcHacs%wpu^YuOU zXV;3G7aP+r-~zP`$!Q? zzbK~SB!KSRdE~vE;e;u%kSxw7**u#wyMWgw>#}!E; zURiGzPXZ+sT^w%@M98({#6`485O=qNx?VfYEn@I0?zMk|VpzC(b;z-3hJHhxrNaa} z0a23FNT<1$NT%=nMcmeopHZM8GU5#p>)QAS)>4szLQIC=!4+vpLqW%7OCt`dsatd4sQ{hn`05_L*!GmgRZZo{cn#%xCkf8-2BY^>$FhMhm^m5E`?IvcPxTZQ@ zl(Q_;(0BriQVuR0^yFnEWiYyPqH@{AJT(lPZ?wLRebd>zO3=4cvzBV!{KplqzoYt2w^qr%?J9v~ zN0B}rYfMbv2&%_Gg>sKGE~ImeMDb zztiUdQ?8fMqgrj>4AJ^nGal;f4rXL8NbYVD4eQXT+$D639GlScIpjdMNNKdYJZM5? z;1SEfar`mrz(WXjUL0J4s1l?C)>)kk8trTcfI(TN#u9|CStwd6DLoL5%id>6+V`(s zXGnUOJ_<&q0DcSDC*1k|J)f<_6j~mBUaX$4k#}FoEH?Y^Yq{1_c0AU4xytXEQ${H zwTN097JEMaQN<5uq8wI0f&f>+RrntmSh-w2>U@F*|J$kYT{|Xb_>`BT`5l!u+DO_*cm>u`@kc}ga zINtW`9U!qQO2wGHa?th4uoC0xaXsJc9UITz?%p21vpL5)4FyCPlfw6}*L;wnj@!za zC%ehs8{a=?AnxucgWe)qy@C|+?k+m?>2(j*`W?Hb8D1w%Li<^Pm(vvpqEk+y7-~f6&aj>XZ-Z<=wl&YthYd>Y!!*v_9OQ*# zNW&C#tdHtNt{T0P82p~YjXZWup8=4S1 z+o#oF4^NLxVb9x8lK70OQJ?yz3S&1zZ%@Vek`)7w;{AC+gf#Q^e0$$_%6Pg)#V?+H zK+|y%$%n)B`$?N$DWYEFBG4|C&-QRAm)c1}nwl<`14g0wHd~F0bRFb}A6o+0Ugr$h z?oQ$=WnU+)#%oD@h>ig;R4OOI`*hB-W*CMBXW8EUaytIyN=4%@-IW11k7H)le%-4z zv2fUC2rkXa{Hrel-MzN6RA07G!o#$wa{2^kT|(d;`r=EtR; zF3>OWSA3%)_eL-JRF=Ya^sPb2aMmasNdb7A(3JXUNtyc!wfsyd^u{fAZF-_z6uHc8 z{|v3RJgZvq8Mo|>&tv(`o*9?Z>batKpoSCJ71ETy zdkV6JV{@e6k*0CXtQeDPi&xNC+cxuS!=+5m3C7(DeVviHC%11};pDuRXZx~o`c3V> z1UYGaS@^zcof;t^F~fu8_i#Da=1IS^uCK0V^J1lzFaPHSu)I1R=xpBq{VQ!6g%J@; zC~?lEi(=Kelpv8n1`rSs#bV-{!J^#5CRuuBrh>NrPN^TUHkBdIr|%%kkU|}LEXm8D_%adEHLYv>&8LjDDyYJB(=Ne!v&>Y03MHN z59tO4@YKvM@CGj}HoWRKsDdjtOVZQ~~(tx=?Q z#|J*GDoOxEyNoa=o}%BJktAA^rj-gO3^*0ds!<6z%AYliQFK>PhY7;|(2Zb;5DNGd z02@`)zaKK~f~q{~<1$%ZueVhxkpCmw#%$e+y+kVIxcT?0j+a|Q^u$9qmQiK4$FKdj z8E(WJqw(mUdCN7I5$sP-&8{x1$+lOCsh$V$z_w+Jr~9izkKyop>qA!8jyr~{;}zK* zPFDSgcr?oq?touF9gff8zjTyM4cneh&^(W>bgp{m+RaPr=pqE9EYn=Vgwh<-QYihR zHv!&X7AP*S^$A^v4R2cPUpM}F;WPAJjAqukP(76mm}FvCJni6=#EtNhq~NogP4_uf z-z#BLqvS+!C|Xpd;J2H$VHYj9yXcsD^Mmq`xzgu)N7K)JvLRKSqYY^p&;$MW1@g$j zj@Ze|`JRa`hz!3_!a`AnX#)w`WD~DNfgC_NGau}%uI;#|z@h>ze#dd$tx+-HGE}wF zK1zi?&lA>N{w99|Q>b;U{rzFjYMv&mPi03`5+EPmQz?o)4B}I`>Neep_Fy=EbItic zj%d9aTicx%Br(2bL}WRMPgiI;m*4stlEyd+w|~fL|P?ARX%H`FB(9g2l4hgaUOZ)7^2-A zoKyma2E_s2waREVdL+2O%29INms!<6>8me6!a*O1nlR^RBHvW)_!1cE(hhK@p~*!| z3qbtWjZP%_0=NBpp8qziX}>%_y`G6h6}>sG8J~UYCt%oHhpSabUN>EBCl%U(s)P<9 zgpBGb<`+5djg7_qEk~o$DGS7PgkywqXASbE3mu)AEq-~-$?N|2v;=m zl8JiOP7rtZ=tZ&dDxFIt$QuH(blFQ1K+Yfze;K9H9(E{6)_W(@(h+7eVC_0tUkuJKApE5BuoqzJ$HVq1ilT|$iKAo( zL*BIRCJ|H;S$MuzH`C*AkCDv9n87(8EaD}wP#!kn2LwB8;yi#dQH$#w0#vv@ZGN9v z_Qx%6vP81u35ieY4U0KsNHTD$Xu*;1<{PKvh}AGctMu1GR6DAom}$mBiAZd0Oth}{ zT~pBnp7{*QB7~OZUEM1riq+YiL)AAgh|tgpQNLEte%aM|`Ez0Kmq*pGva!aWcKX2| z&9D?-T&D@7r$qPy7LlqS(eZTxeSUQpOC!dfOJvDpx5OomW<~@T8u(OURkK%eQ3hI0 zy1#DMGGr4}JLi4Bqclns>$+((k49RgP8)y7D<|~@_Db;RHB(I8=k$B=%Tgo1Eo@Pa z+K%#8yozcmTqLrn53cwy03!>~rP`_T;_(7V`$aBtau?NxAhz?qPVaaanH%*w<)SU= zU9X7(1sBa{6+mB{=5=<@k;_}LKY>sl7&Cx>2>VC4&4Rdlm1Ze%rR2{ip_<)G9SQjk zI94#P{KIPhfRYoC4{$DU4gez|gT4Tv{@5|P(tnp4-16KqeXbYQ{^`_B*U;S!iD9`; zt0DYSZum@7fFJUjMm|TPdwYlwnngH(uo7Ruq=C=_h8`pH$e<(z{~6-~@{9`lVazBm zZKSHYUy=cE60ib2li#vwULNDLyJ47DCDu>K(VjoSr#er1hyB&7AtjK}-E$~7fO){t z4Y98*qQOU#%Vs~}#Kqe+6QfF4MiL7OXU4+%#k;Y_ec83&`RTSyJanNcyJ^R`M7vBg z+tG%eLE9xPqPCW21wn~MbgV^Q&Mn=S3}4M9_I&OPrVRJImEgp`Mc;A$Ox@{hWh(0)8eN1o@yw zp*BKUv2=M_`*?KV$O|I@2mYh9MwT zVASNeDsjM3^V5OpXZwY$L}On;B!TC(r_e|SN@?ht42`qFyI1xq8k?LAOb21I*YbOE zn&doRvd*{qAIx1eqQXACdZk>(KXMkz3kPC50Ax_*x#cr1+Oifg@-u|#3t%{qOvpKa zdNz%7my4YpD6qkkZXVk%$C19AJr5#lN>+~tnGqmmB(^aWCK05q#yV_Pb%wU5KRPSe z$Dk^&lnFvVC!>iZk*s5u;u08vHA?sb}$#`9-3CN$b3^mxXd3@#Oo- zBt~jGx$cI(_ZteO@(YG$6sUtDPhFZYA3#=MX}4BAh6FMx(b!UMLaY<(vTjy+!=lgfl+ZtiYZ*dQftd-5OFhqs))r+OzPs2Avq zM|`I{2y+Pm5rjiCZNvAPjRt(w_iVWm@C1gdm3*qs@Ho3pG9D4T`@2(V6_^q6*3J0J3*a3zhtt0MP1!n+AC5l{>JY@q~ zp1Hh(d_17!}e`Z<_pkDK#x%}pOO^{FrtB!aEPA)sy-x~ufGfM?jj}N zV^3mHUQ~UjV(fdD_k14dw_o$(d!kF+V$F~1uG?18QrZ)DRpOy|HMl+QVsJ$0a&o@< zmlB2|v0jmDaE|eIhaZBVRz}n8nM{QPTo$`;VW^7DCUWqf5>m($@99o@@SK$;00cg8>__EWF@&WO zvHeUGyIl{AIY{^IOKv_7X0x8k5C8XbND$7#+xwuO^oVSM>S*~990FLDDA(ZB{QasA zdma7AM$3I4T?Ung$cU;hM0d6Dj*KhfxxoWx)142{tST0Wcr4?4&P%xNb~lLP7x8kZK;~ zp7TkGpArX3+<0}9scFlJae*rkTm2J41I1fgbr`P4!fH-ntRq^kDh}~$TMfTg7~B|k zJHeddD0_Djb>WMgIcfw8R~mT=b>0DrTRha%crkx_4C4YnDI?4oEY#{<$}Hanv3TJLTNW<}FpP3GDb0U*#Q{VGP~#-= z%X2*;2_27kXM@?DZ~=s|4>S$))dOoPF&`&Cc3}^HCtZ3ZW64kIK|MpB2?5HH=T9EDqZ;r^jk54XSQq&~c=qC;>%= zL&k}LrAV!nSG9F(TJ)4Uj%fX7bY@;ZElH<>NGImKjwvj;Fz35N2NfFG+NpIm=)a78 zL{@2C{y;B>V~C*rVdzhI?;sPgFGxHb7v!7BxQ&H+EkYEY{D7 z$?(0`Ge)rxuaj%9&P1Yi{m(s0?4OA&un0~s*3x&HX)y#{*^vnNp61Y~GWs0+d*ylC z>ldG9t#M$=3~pED8aNOjKvJ&egw~?^P)~HqGf9Q1`{Fos771d!1%RsYwu#fKFL2Lb z$Svv~Z%eXV1a)(Pr0Fs1U6bn{GINv7DWTm2dVRgz@^(OGQji2D;}sd;&D-Zs$}1)r zQLt`;tmsm^p=jnFFL(?}bB{*G#ETB4D+$n%#JKUOwvXv6DB6dL4UWDJb^z6*VviHg!kGCit}*s| zZbPF7rAdWHa7{@p^Z=y5@*saiXB*O)sRSkTwMDILFb=97?ln#prc41UGCoTmAP2oE zylgM!EADTyb^k~-XIm}V=Eu#8I;R~49ZbCNzliaIS9Q=*Ur``VKItq0aeZlhk|J;2 zp)(4%wQ@sYOOC$?UN^-cWRTN{vQNxGi?#ml!$gceOPf5x9I6zhzaA|~K#i)j50daV zCx*e9zkW@56TgN1!>L#fXZ9{At~yk*Agr0bI?eWoxLBp*+4D5Eg4c2LL;tRe7#Ok%<6`)`F4%Oi3XkcT zBXFDtw)Q2JekdN4hQ5uu<*r{D|od}o%&;iIoD9)YN2ht|N6u+p&x2Q7w z5eP9_`}%`0Gn18DOxAKI>@3MVp`n5Bsn>1xQ)tvarRO;(GfkG6dY}GvKAJ27l1S;$ ztgw_`nM?bh{@_!(`4?ZghyH|5GEaMJKEDXk?Hq7K&Gp~Ia$GnIj|;JvSLI7=>W=9& zC(=gon(`O@_t3d5dEa!;0WTi7~7>sstgW7hm{a#aEFTJ8@#7J_PVAC zBb0b;u8C*@lfDz$E9KT~P_`9)`FGTDZhw>^y1LC0OYE~wO69eLXw}ge90y`F2eb`I>aSvD&p*=84mSt%-eCIl1aP7Rg~Zu9<7Cp)0-!4imoqm`*gnKmya@ z1CwMeK?RINj!CMwHO>4xa@3K$w>*Qqh0Tvvh+I^(1^`0J(V6xZUqMhiMqkmw#K>VN zGCPkx39^7_fT7~xmHT4C5#_)>bheHfDvW_B%2hr!p#qo-6e%Vo`a~_0JHwvS{Vft) z46MO4x{35*&d6p4rRKg)4y$?_Qc==H zaN3EwiN*w_Wk7*_0k zCqY-s?(6S%NQc<&yr0Nn%Rzq>50Q9_D(l`335i>W9Moz!#)u(a2YAEU5N_EhARPk0 zO&Z=sgkaZ$@I|QC1NOQ|Vg3?yo!hx>C+E*zA|wLwdmmPYIul64k<3-U(=(mRh$F6j z96bG$Nhh7b4s`^+eQ9anJQ^mn)W4Eg75#w-Bu`99`;#M&K6rd&wEK+6;cz7 zy4EGaqNp`6;HqlHWO59oC9#V<=>DKy^?R-&ra5j|sCZ-3(rqNOAs@-E6fHoK2Fr9A z01`>%ghL(I2SmmzB?C;vNPBQO3I)azw|72C(37IWC^!U{DR#+?x6%dS$cRKUyI5u^ zo1vZNuiYPCj-Nnri#$*T2hlJ*SbzeW`wI?v7SOEn5Mrn7{OG(uxUmZ;MxlamOawo{ z23d{BckjAHm4kmL^#_}Evtso{o_{Sz^FoBj^hYRqc6)V!8vp}9tJAE9#CO5&_R6E^ zMS#Qq&~(;OP5$p2f7Sy=NH?RUbcA#aRHQ*ln$aL2B??lbLrS^?R0Kh!q(K-Rq9CG# z2vZOQ>27}ee9!s)x4(9Fp0oG;-0%CouGhu=xNAOoxpvg;bMPK|RL3sG&Z14ytjVYG z^X7y$LfVyew^m5$-}!+xX}aq5B1N90gK_3HX!a=`{&D)}fx3Aqh^qe8glAbhe^OL> zFXa+A{;DVi?JZiLV2ZVjA0}6(*U~L%jf3ebpAi*`s1n&ljvZ--ZkcVU`95_7#gn5b zLH6vFU^wb)C4Ud=IEKmJ#A4_XXnxjCHIy(U*C!LM-i`(Jv4*YuPvvAE_rCG5W(p2 zU*AeB!lQZ|`FaaOL1_WX?mFF6fCGV^1S#dfsG@HD=KLLh=gw1B&KmTzi_Ot%V9?Bo z$&ni`ph&Gw9#bW?)SK5mi^+nEM}Gj{>~1%}r32SW06ydW(HAMxY)UkYSy{4U_uqyU z9;a`~#mo9}1ujh?*rerZ%&N1QR(HOagE2`K|KYmsLPL{~z;9`{@mmZ1 z(Zl0u&@`R43MNo=dR=a=_6P1)nO~z?QX7qYwd-`cwd>+sVvo5oW_Zd)4vb0wmC6EC z+3T%J=AD^{iO2*tJb!;0dgaywyb3%KQ1~M#F7QjwlOw&4Wb`H&`AW?K&KmvJa#NAP zV5;5X=7P?-rCW9R2k#O@Uf}vMzqe4X)0~9zuDO~t#x{iXu`e97<6h3GBWRw zsTs~~bv_?^+6^+^EjgmU?#W}C{6}KG`aMWs1M&k!JwrhHPI_iYk7nQJS{cxv6;F3k z0p_Cq=;IZ78EB}M64LWT(+#P1647{3hl!kQEivI!=!pmZ#yu*T(MY3dw%5OdZPgk3 z^_y!i>tz1!xo`Mn#@Ph?ind+2w<8m%PMTWkcC#u;krW5UB)o?A^PMH7x4jN+A}f31 zZ5%-)Bf+)KGhZ=_`oUvmvp#w)+nE)mAu&zPq1XJCe9tp9V0$&=`O-nO!5iGFOVC0- zPJC1^iF%{i`z$Y2aRFi%@+=NqlPZ;055!ZfkvTHhwLlW_ivgoi#ClFVq$cWXP+@E~ zQe`1SxpPdgi*L{BCav}kg_#{X=G3a@W?sjTtvit%4Ic%fFj>H49!R7(_5)Q8cKp++ zD48;mVlCS%S7j$IufrAqFUr_SlaE5p2YbTgB1fvG`ksIo)rH#r4`n z0Z}R>fihSS_XSWVJOXg&jS)dI9GdSV+SC}YY6v;)$z$>7glS86NgBBV*3*LtYWz02 zOhhmdHTr@(dphog$0z2vK6X${-1Azg07?v)CgLdDSSLK>?q7aUc-0l7rQsWRsss5# zv6Yt4v$Mnx(A0^Fs(BG9ha$k4-HKn}tz8k=qNZ$`spfX-R~nIFP9vY#59G4FbC9d# zk=E~0R8+SaL{@rIRD|q4pXs09cuMkg{ZH-16_0(&C}#Xxiy?&c9=H&eY7;t*M%T_Xz(Q#LWD;3FM|`kj%)4z{1Iz zL=bH4zX&vTD89d@C*PRKX5Gi3_)KpYb-qkU`kNhfbu}Fl-HE~gjKLX_Ig;m8%9D+} z$ivu0?7nP1dnxJfHJ@*?LMUDZRAJ@+t9{p5T+Mft$P?W|^c#G*!m{G$W0Wk1@(29{xfS|sg?$p>_ zM^#0atDS*96oA}toPcEYZ{!7u8UcodY>zP3w1Lt`C2|wk1K|zjAgv>j@B5 zRJ$QyKCA|A(5fJ36Dp3TbvYmzG!Je_h!E)WESqSarcW*0Hf(!6Q{bC*f3oV`HS*X~Ye8I^e0nL}0aes6XVMu)RYPbrRPNOUVUdHmt zL6pKqa7e)CbvJq0epN)DI<+$Zm3{Ro*mj%&jufTTo@siwMZ9Ik2;uF@O!K^=ko1_; zMT=QvQ}O$~OrsFU$kFC`$E^xav}1oHtS_M>XH?ar%~MsdyRbUD!peWI;!RoM6AQ5v z%5bVZ1O#*tC9Z`kKn7(2R9h)gMI9O&*1qk7AN6tcW|G&_TL%LB@j<+l!?oR<;^qi= zE}pkWJ<$%5AAV{rXQmg&dJLUE4k+ngB8!8{{ysBGa3C6gm;Z2iaoSpYh<+ZnA@_v% z;#q}N?pM*(rs{1X@Xt$AIf!)Z@azOoj?9snF|y^GB;q?uF&K?>PRWh!u0dwg#VDz+ z*ab^YS=L-Fn2p;;2)qJrDn8AL<=1GBu@V|7P)%DXeBV3Wa8JMT-I#3$6wO8XfpkuoRIrM^wzZh8#7d9 z>ly!=sivRbV&{LH$WS;HnCHYwEap7CNv%|}tbF{PKW53YhTGDjV1@1%=3{tNelG(V zmU$1e8Ces*T%bFCP^>6ADt*&HZxX~aV%zh4&TC&3k!Gj2t$U3SL|M(k3zS1fqsYSb zBXS*D69oHgEFyaG=|L5igqRxN3TMON<{tG-QD!1MBnMRP;OarbsV}LRk|OnB51&csDy1|*5o19|}(0EGzy5R&s!S;%;QGC%%%c}+v}?n}@2HieTH`_e+q zSQFE4kVj$wxxxD+vv*|<8xg*1pDe)eD_2tHIDl5c9RLAvyzUEb4T0K>=LfA z@C!RB-~>?1osA5n^*WIz;AOjL?Lx{o)E1NpWc_5a4u5kDVaKp4$Q@8Qc{SB6(34dT+|Iz&IY|JMRg;~TpC4VdD}^A(Vn zR@Aal(+E7|$9JuUn*az;Y2u1|hhDMc)WD?Xqcb(B?0=uhMFdK?RKW~?h~57 zF;ku;Y6x{UtCRnEIUdgf?zk6;2w%C?`j1{ zpud#|-tu_9mQ8`9IJgski1-sFj*h<1miW~DIn#h4b#iVeg^7P^vY8WIRrpY(P(@$Q zyZ1vcX_Z`~n8-R`IY4pDi z)BlH}Ax_eP0jGtfIKx^&>30>AtsD*dE@xlvaFqugZk$YJ99OBqDA5rm*?iwiSlc@! zv@LR1=oT@5e+`F~w(O#^Q`1BtnCA2y$0EnH!5!9OX#Z=0fA}ldh!IJufrojAf56xG zN#i?lwCamzju2*mhJdSI{N_k+Oc~Cv>O0cFS1Q1ZuKfe$EVf&|f87`X@*p9s=Tsmp zu`H=EU4RG&MNl_NMAui1)JOlm0e~S9%rXo18_a2}K@nyU=-o&3m~c2olB-3N)MAW* z5Q+56Xy&H8GI${iUQEE`SE!jxFAV{)1a*%#COv;`ahh;<&>g@t`5hg^N@GL(3)BOI zB6w%{3uYbZqgB8UiON_yg4lO5b&90WzbQwtPD%=q1{(P!9e=m-`|-DHYy|Epak$>L z6_zbnIknF$*X%p_7?h062HoH5vyC!2^ZOPm(VjwaI>PE6Ar-GB5Advs^!F5YpJg7s zR}ZExhVb&umO=?reFHMzln!TKxmSO9RCIBn{`@vc0Yq~fXL}3Z8*;q!XJhXI@d>49 zCp0yrGy)mOK(|o7c@)5gJJRUB|1gYG-9CO3{6>*PPLd~+O@rVm6~dQ|IZfen^h+tk ziW<>_vcn~FyVs7-J~QV-fi6v0a>B9pSd;crHmqTWjx_I9;j7}S;cJ3Fkd^LtrhZ^1 zK@nH$nIsVM!7yZ#rBd&?d?22e`qK*Ss8wxC>oH=eCHG!8yN}KlsWx4EzX96_a-J+J zNz)uO0BtwDfwA$g%N1>N_NK%|FL{Jv z3k*<{qlz;iy1&mxSzKDk4b^ZReIIIM)J*)f?2$D67e1YI&HG-4KfcbCuakM+@Lh8_ z{eAC1<{xib^_laFBu@6*#X7gp?rLldRYfn4)R%>h#}6MVl#)8PU=ow>WVh&YO}M=I z@V))Y(}s>)F0!goF`JGwL$CE~S_b&5!u7#vWO^NTfl(j$aI)SrNs1BaPXJhnNWq-f z^&P=wW3ykZX%2h>e3j0>H7*su@`?991f;lG23|!#GZr}m!Nqa>lLfPWl*Pc1&lJtK z;Vw?D0IMzK6ck7r-a##pgewHZ6CnrTET%hFwDzRr1QkbF5sCKWt80jRRMJY$9d09# z9AqyQ(3iuTRSaQ_`olw7S^kZ+N3*s!{dNE~1G09wr{UOOeH8$T=K&Od?c zOB0IMw^j*FkYl)sYbCpAU9PV29qk*GIIijChN*_AfgPA$;2zPS>&KcTe--2O83u;kDl7{ZpbX5#DCT) zUHxkLsaj|^`h^kimd`JiUO7qI`<60{E!zN%l7#`NQVG7p`Ztv$p^!(h&v$?W`BA9x!FIHh>Y4VUb{ClDCYDR_nlMbt5KFP)Lt9Ab;zT3I zAT4nwBR+EiawG;ci9gK@NS+yXe>08qvuQ;X#EIdqjIdOc5k^Sz2X-FiN;)juB!K;? zQ(LuYBzxTEagkDYETy2!%*tXU1Rh|8GH^3#nk zq~>kD@5w!-Kg-MR1IZj4wj>zRsmk^1qv!9d*I8{A+)w3fnds@8H`o6?zq~Fg`cP#d ztcvn-bn-0n8`H&1$MWUx-}Z;QTaz35p*}uCDyO0McArutmK}#JhmrhXe$~;J%kHOz z_hSx}E@L}MAC=GigM)*Iln&&pxA#9^_KYp;_x9d8lq7xA)?~YLwcpRrwm(KijNcGL z`)?#Rh}P5MUv0y*IvfuRRfAC8Ybg@7Boy3#-eTqRJtHO~J{mlO7=#Q|oeTN{5)wDk zv;_3Fo~4`pPLK+RvPj1TvI9EaT2x4?pzbs`JPIJ0pq9Q6_4XbIp!*ahDru1&3{nob zN_F-0YYn}Gx|c4Az%_3z>Q{KaB52;?(dCo^wd~u3_eq_PHxJY-<)!nkGSV1`GT%_2 z;A7Q(A}W6ORc*1lcz-gCEe<`krTtP|yz%IY_QaHKhnY}<#Xy>KE?wmr9 zH54Ya^m+9BU4fF5^Jh7~rI4k-!t9rG%$)4R`G8RG6>tv+1sOIAw2|Jh; z6pnn_8kq>v!?^$$AP;y%2q@ls!)vYq_@LPF=K!wv@CrJ*I3LEYqemg`NZFB1ir-?w z(dFcK{Fl@)qDo6~1!l(YEo_PQ-z~2x6efgLA=*DQR=13}CO&l-} z(5)*hu{P*+J7Ag5W4uVIu%rYm@GcY`*J?4pt+Q1LnC2`~6pv3xJf6SlO^GK*KMi6% zDb*37v$LkjLOJzY3_v9WsDAu)QPc)L<2soAVj8RZc~J+NY|HU#AoMTg9mSrdViKkS zMOAp^V4-jvj;~$2_1>8&U?nne{57B8kn9X6yj+JvLMe46yxNx9Sj89LYuX_K>)}eB z4f#APOnK|Gyz>b2@n7EYq?3qcwQu0-OxDFD@wXpOd?hB~p| zBxe!5!E8t@NJfJ#FN4Nd;X3sch}`ig7}w}aMO3>>ASx}l&_tlmD96C5g!Ze*mt;?l zWmq&4bxAubbeXQ#B%B-%tE5|{)6$rr_p6}pRr(m=UfEw%^3;Lr??CxbIB#C`t2@FP zF?UtDIVv*0GYheIK1hDsIUHifkNqxg!k4c+E#lu^8hN`(3v07_lIy;(t@^~);f*Ui zmmDDv>L&gGnH8g$99j6sbBu)l8%F39DeFF94{Y3+qyjP z!owj~QS~(>oDM0M&f~NR_7`Byxox>s#JR@iN&`j!O(Q-afg^=Ze^=7K=k)R+&VeKl zG_e?$VRiD$CjiL<@71MQL|Fs!D{5>xdP>}>?A2jOkXx6yK((!iKxY4lti%MCjqxO+Hh17I^$g@l>(+=5nluUJs*fZR;P(` zxKG|}SI2x1D@V#z=IwH1wkjgzZ*nxDQoHIR0X4vz8H+y_4xt?udlTfTj>u?24tKCgP7>uQJ>nP4G|Vjwpk|cnuxZ z*Kz3&9~#}plAUmrQ=H!?l83}P!UXh?YM@6T4|0ge6GQ|vuJ3(!h_gzL z5MGL&Sz_XGO}6|O^^K5LY9xVKrM~Ein02c$mE0mt?%B?OFY(&#Tv1_5Kj5R4$XCc^ zw330`i+6miBK%%keQ9AwQ}4zh|0OM+{k@}Nm=(d8sXao^?OzIO>d!#`b$R_9|(o81dmjsibgpNb1N-HE-0nj7m<< ztuf<@9ILd#8&|WavP?o98K89QwuB|Ud~?zM`2mJwE<&<_=Q;d!4#isjXN?!GqnINyX%AX}7gDgs zc=fO3r*K|p;{6e>Rj)$+J)w0q^@ylw`<3`@ZqU@P(5px~{}8)$2Ts}60%as9jcK4uQ{Qcgoy^gLleOvhFgUvpqw31FwzZcaSG#(1R^DSnYwMp8 zF9<9a6u)owL%TfWwYi~!(!Cz&r5<`&M}?Bhu#-T>>o%evp6nYw0-wfoQliPiV#A7L zybAks9?kY2%#VcvYHjO{mUTtrEbJ>D$*J4V=9u=pnkkohmlz=iYG{6_pM^skbAS_? zy0fL)-{1cP0x(`o%_qKd=uGN+Z{J7$%cl0j%~&d5QaJF{aJ#7*JKN^KZ`9OTQ>)Z` zZHGRF54$rcIXmy-7bt84DL4tAh+Q8}I}oqmT*^d`&@=A&vQW0tiQVg))+6X|HF1SI zJQ$7=-%~~tCnsLSX919Lz>yAmzVr-ah7WWa=$=SW20$W*XUPNBSWTkNm_DY8lc7&f zPYwU^A>16fgIq=7Rh>~)c6C&%R9}GuXdR8ijd}r)oh^7y|GV6-3FPXQANt6J6H0TF zh>BBXWI7P1(>mbBmZ|h)yaaBNIuaIv@bG=rwu8;QGy`IYssIhZEP3tudp$>!50HEm z27`t*f&s)i6a(!6(R3|dmoM8f}?3W+~sr}oa_LmH4TQC70K z(}kdLJyv*k7Hx10#rjJX65R|MNeTHFB`SOrYYO966yY4oC;Q|P!gs2>G7>;Z03d>n7KA6x(QiK29SloF?VbaHFrV3%zKRM zE#n6_IHQ6bhd=s$yX`V$>7}2^`MmKOc6!DDvlQLuYp~g9$szhPqQ`K_IG1y9kFdOl z{Szgf=31H7-j%I!@ynsn!gjs&UsaxXiBTI*lW=vpLP+WW0=M7BI>P@od=+uXyLlT^ z>~x~TN7o=?mFf!Ws2Z-;dN)UxXs)b_2#aE+(KmA;aI@55dO~RpKW`VF-I0eo^+oZ`k#FA? z8IN=c^j*BrmblP@y)yX~l%~S<1Eg3jeviQsru*#(TC`cYK zT6)HNN7x7`k_PLE<$ZE{u5qu(J}{_a@4$xX?Ae-S&4)>Uwu#M!6qT(1445QmoB7bk zp{(xT(yg-Fkz8lE^jwZ_)SH5}-@fvdjUJY41?hX$F#NbdPP@__h$o6v8H>}D*{L1D91I<0x)T}X?;NEiGS~viO8s= z4`!A{4CFIKC96>C9gMZ<3S$xI;){tZV^PHXe>4vvm1d_P9pu*Z03P~zsJ6xt{z%6O zbhjKOqz55HdI;jF0?m`%RIz#?sg`3!FYXFs$xC1AaJfRz2qN51#_%|A8G4#(9i?1L zC=BJT5tO7vF>G*SpPu9_%5BBDf3cZKjv`y3NMt4-VaGCmru^E)EPs|C+K-~2r}-B| z-~mwhtB}W2@V8)TN?0gpzdcNfefy@VF3B~ch--jBZ<*| zroj7a8=yW+alb1#bq(*i##H+A&&i0}T&do1`NhKA&(MEjJF`Wb>A8|FT6Qlc^SvTf zle91Pf13Di+b#`$=GghO{&svE{os|n)3yASa2;xoY0fw7wme7PiovS#$k-_&Cu7VipmF_)eiiL4GRq zD%#{_2*;p3>Pq|V)cwDbF{CT9u>wyEn5%KCQ)ALgj6{-=eP4#tljQ7rmxV+mtUl}(5 z4e?0nF#Ztg?Js1CVN>wtA=!~;=WvcqILpg`%kJ(e>M7R|Ii-$~@DI|DW}0huth2S` z+dE1j`VK2X$b8esW`2q5E0bmK>=^l~`k4CzXl#mn`s!q&_ibrF*A?Ooz7rauhRQQ6A*?POAC{8+zF!vskF2$h|((kPf3@93+9~`8!X4Zc3jF zPAc#6y5*hcEUv2 z$;0YoDkO2nu~E}Sk_HEf z$q7aTlGm}D2@7!4HGb7Qk(0VKUebtkumLbW*UpqvJ;!ABl<;If#OF(j)EG=owyh|z z3GTT}h#ykV*W?ifAU*(NAi9nr#%O9Z>(}3~W{e(MiFIdB1slOh(s_8+?VR;Huhrat zevt7dE2cD{8cm8QFqXI3nExU2e1zB3Jpxkp*nx%^L>9FNEO z!IVChOjB$QHfAN?%#;ttJguK|te$+#zCM{TT~^?mfMU&HY+o}F8!|rlHwVdFc*_69 z`2Clmfvk;KuaJM1<7N6>EstmaW~H}N=9);TLTivLWYB>>6jnqxkc0rl0<(?7pBKH)%O2#{qRi}UkHaatlXUU15D)x#h-K-5l+aD7fm%f=jZoL+lf|(W{`fVw;H}fn8F!ze{H}CNo^a%^`|n3lj}P%of|? zs+fstH87+DQT^{1Rib`~Y#HpBd;>b3LkW_esdoJ6wu3d8ux1;BEtv1#`*Q9q%Lr8# zwMxNJFPJY%GHP^vCI%>vkar&ifiaQgR}Yb;Fi%qThzF(K#`Ok1>^9jTAn_a@yL*OP zhcW@H0A)83;0jS4nX_^pD`dP8o?~^Wa~H9?SoE{#;wX0K0%7#$=j6pT&(_nR&eyhM z>u151-5GlY;bm?W)1QQDv_1!47%KJ2ojw;BIApoV1UN_yai$)J!mwo6<@^M5_Ys07 zJp3KVqjlW@5ySH8>9El0QysN%t`z4o2_u)yBmFT--URVJKt9=Wy9y$x_TJth8B;ZN zY7dA5<=-@u3g`X81O8fJDB8h!PqePzs<#lN(SX8R2rleo3{Jetyd0oow-;Rn%fUBS2 z&!v#U1sP{?Po=QmK@l9IPos>v_jCirfUV1CeS8pkoY14S>fRL-SqQMMk%{(Iz;E2SNO~4@m6Suge{3@k>wQtIy3| zu3$rF?*33BsA|0@?di2h;THVOEozsDdh}nZUHzG;$6y@SIsRk~5VF#dJ7w3>mfuWp}ehJ0K*7Zp~%jM_`LSp2zuutQpUwt~*j| zm*^D9y>{li=}9ZP1w6nAM*gvP;>Us2U*Q?~^&<8@lOvjQY$;BCi{@yi z2lb*{r;ASYJ5k%kFdg>umfX|7e7?dR9i&%9Cufr52AlR<+ zdwzQnuj${b8pcZGdK76=M>NpF;|-Kk;MsU^*_R@ zsnpGpOmWVN@$xH_s>nm-pLjYn3Zh^46o8u3^zCA8&Bb4R8UJ8J0!d2Z4GShu;#|PQ z$TgYohk3a%mH3IGjGo&M_;W%?wLCMuQvpV8k`Ey2C(7 za-VCrZtlpe1}`2JT^@6_{EA_lFvu9uvPfM7ZActUnUyWfOEDG403xH9rH?hDiApeD zD&iH)*M9y_c~T$vMV`8gR{?zW0rS~$80oDGmcJvXNE%gwSLIcu&^!q8=6ieQyY26( zR0jWF3&3TqalZaOgb-sSo!~O(BT9r$Qg>;<=7{h;HvrnSOGo zavw$fU5sf1e1nZR;dcF5@a4HSSlzJ?Nnq%3OT2DZGW}(T#W8h;@eH4dlWn zQqEl!C;)-CCGY&*9hWYZM3${Di|gHOg=0CNykX_^dN92KqOuD4PwjBL?iD67!2UR` zJvNGW%e5E+D5bj76yzU9I5Benm81dFK!>29(p)uK=88KI-yABv``wQZ9TeZOa%guY z--%JhfBp>p?EErb3QPMULy#m&&)B99gph3`x0Rh^XDm9Nhfl8xBAd;6*E8wB(Nn~PF zgpUw9Hk@rw$#c2m6+1|(wywm`(fpmpayflRRC2u1WM!VJ#V zOW-)TonrhcgMO@$^nNx zie;3p^NmbQ@g2d(Q~(VhcDC)`^^<5;=_^~$>~NOZ|CO8V@1!6?q0G!oi3hW?Za==? zr5s4%x=yWfR)Yzjaw!UFG|OfqhzD%pZbbHY7L32TLwy5w>UC|FqJz4+eJ3H2Q^~@* z^%KWgXNzs4$q$hY;fc(DNnh?XJv_f4t&RuvLwD$2x8B#Rx>~!l{PTr>=D!e`_$CIQ z1CyS<+z0lbN;1hLGF^Z*&)nqFGhfRb=?5E!5%x_zhXe5s0q zyals7BVj{7s@ab`e;9)Vq4r%OpgrBI<+*N4a!awbf=Hrl(McU2*iA3;pHc7~twSHr zC0Rg3;7wziZV}-GaMdnrfIw?Iof3b^V|?GFyepM99kLufH?Lyfy~85w8rJf!s;zO) zz2#<+m!FR2vuxCgJeGyyY|iYL#eC>lhUw!U<7h8dIlj(Mf@R#c%?~*&P(mDYm&V8rn?V-lj-;G5@Qan2<#Ce ziA-l=j#5C?1a^Tc;sM)bDg|q*yHLjvfnMUyUcr8qE~Mo!n&cgG!G)^pfTnVHs+L8YN4!Xn!`eaPO}M;()C& zFI|G7X2j`UJl9v|NYnQ9jt~LJVxvb~Aeb;4s8R7eF{~gvv`)IqFp7U1i~&b!y-jDa z-%TPvE%c&Y_nN$;Y|*UOarj|V)5oV)hlIa*zwGm0&yr98p_0WG8(B+j+|3M%>Og2P zZ%yIdaK*3@km>2C*vQj6G`g6$vu@K-hC$%S%NH8~Vu3!#3j~;&X3F3-C@G6b*K1$Mho zR{-(hsB(%Bs{7sbI4!CpPG?E?Ztl)#CE@@@ z|LpYG2god7Mc&1*nouA8wQCkL7T@ZtKb;*4Gk&!J1lcvR@oDDFQ?0B548uR(7Tg=` z4m+<7ZO1N)Q}SM&``)K0TVHr@z1oId!51__m`K&MJ3ZKNa{2M}ddF3g-nXgszSn(j zjmxbb>Te=2#I9H9Za%ra;_irK9@#P}X=M!5Sz4;DPgVo+TXa!5&1EN{2J&7ec9K@< zVchVZnFja$R==f@XCDsdEC zCvFUiI?%f+O3XaL<2}c^-)-ig`6J_`TFBnEjs0Yp-I`VveO^&&z0W1?lpdf$Zc1mq z(r5XSy+v;%96p48^IeiBwRKNRw{^wngd9C6QB@D0+ImPES5y5Y@rdC{W<`xJi@{Ga z`y8T?pu^$PTJw@!6Mrtzk@Vs5h10(g;ZOb?fGQwZ(c-9v?y%K z5>LijA9RVN>}8T4dVXx@`bZ%0$x}-SS{&bvdu=*8&eD~2gurV=eF@ssr>V*cNzaN! zpGh$73Fh(+u5XQ_{~q`%nBB*}sA2DZd^48|9|NMnjZl|Jzi8KvypWm~ApN5OUEB4q zimPqXA3xmd-vJ(0;VKFAQ`Nyc9dDuhVr`jP2CF~i-T_d_IU!j(gCjZR+$Xb}I{nvR zaYJi=C^i*D*_f{lEvy)sapD!;)hOa}nVTW$rB5_JKB}nqs!DI2k^?1`t584$+)K!V zT_%Emq!i)V5;KR@DVT-xrcq;ZF#DeY3rRbBMkybAXVJr>Xr3VXse~Fo9Ao zY=#(6DO`;%rQ7R9qjMSva=9-XZVJ;3RD)VzUCJWFrEE%Gki*^G0HTGqQV?Js_u85t zE0`l#+?O#9_K^I;M+0LAVX)Wml`!w#h*0n&GZ1v0n->pc5;E7A8?T2;;dGv8-8JJB z_sO+GNkt`r(Ex8>j!5O6(RF|=-4fu#dE|DSTyEU=>R>HV=En)*sXt&WK8oJV#|Trh zNbGU>rVI-VbkrPW55YEgQ%qTka;wJ;*N8d#qo3y}Jg$1Aay%n$T*v+g zs9d$3|LVa+v?yCi*T;R{ z5UF2R7m;~oc*E`X9m~xP4iJ6)T571C0TgRG*5^4%-=q;y#}Ux=p$V`1TH?>OI4N%m z8sYDYNmSa_Z9Qv}zk-Tc90IPjw(R;|!?H8;Xiy{dGD`IU3v^G%T7PY z^6>THwX~RTbE=fRb}8EzN1{~D6CVSBppk?Vzsh}4p-#1t_e0x2xSassnHcUd_q)26 zZh0V{kP|01l|UwBm0i(a1xlR6z=yXlvTwOxuusH4W;55JFfzo`uO<{dtA5K08TDOn z^0}QG#+9)6IIE$y(f6nSq~^e*Xy5IX`DfBU!DM9n7RSj5k6@MeluPUjU~Dt&(OJHD zyw4oK^^?gvPU`32dbbzl{`~dSr^d2l;R`(nyXQER>zA^@2*yCNGFy5>G9GLUBDO*Q zBRg)msb@opD0_}deSxh+y!phH;Pb5eFs@ZZ!FSYHf#vWh)Mx(a;%H~+$7O2zXtPFD z$BD)9wti@xd1Q||D4GA?s?!?9(?5vQ$J5T`9A8=;(ESOobqA9YI*sB#%D)_Kb>eng zV5U5&vaeqWp+myWJ zXK3cKi~c%dFu*zS6Kpp#U$Gfot%4=_i=jVAzHjTi*+_R@RTiY|73P1w9C(tJ;*r=1 z^jL>tNiAuxfP8>e{5x5=;#w?KpwJQp9#Y8Fepn;7R?t5NvJ$^ejiFy z_K`Dajho5JyUUr9)^e3dx|@O8elO*FnP&Cfn6!G87+z5!tlOfFPjP%%UaqMMMP&?s z458uW5iAO>v+^C{&!awT-~F7fuY7z9Ir3TMGT6yECl(5lCxDkDk1_VWNZ1vNU1E;B ze}zrDySQGcP1h@8cIVk^c!VMwX}nhf238WubC`jTcuoz+tCdG+mJ&{*Qk^gEJC`+U z7&WJ0cr$SpkiuBBKJ<|nnV}%Y{1U5VnmKX$OnnnV+6(4qT!=cx0GwS>cC?2(AFm6x zMYNLAIBr{XiaoOo)&9U_+q7$}B89bgch=|<4@;f>pf_LfX(14dUASlhR*^KiMV`Du zbUp$OIa(5`GCyTSw4mwMUwrTUj4B%9pu0E-Diuh(AJ^3A#F&-mbZwAQs9ioDzJ-5H z6U<)B1-VAER(FEvWA=`Eo!FiF+F*I_6SSWZ>JfMUIqE@MT#e<5Xk`~WmqI!E;He86M=^i7Nh3EUOb9(uR*TDciq9JN9SqIH%mxA?`(jiK~t zlc2=#Q}R8A9@Pj=WVCd)A6}fwH@#9k9%yqK{59~JbK6wuPWxR+Wr4d6k;ctFFtk+0 z!Ai5E4QFUAZ5Hc7Tq*D2Q^Vo*ZBC{aQPHAiNk`JK^|H%m#(Al9Z{fHbUz0i?=|AHK z|Bk}Tp*S|IZ#J|E3YdV+mdw9+xnwz1ZtG&c$A=T|3se3r$ZDJoQeQv*WIO0q_WasC zE1y1RN;)=}tj0eLT-`e(1?9`L-BvZZ;3MxAzu)Kg>ov#Red)l)5_(Zf`HXS2igW=M zdHQ%1SS`Xby`hHMkSUn$39MYjE)*yra@b*!sw!_+E8np3LQ;@mV=O&H73oM;1+rX| zpCH45(flK3U{~NY{K?Grnl?Ha1sUrx;{>?f-EYe?DFnh`-w|^ZN9tw?cdJr5k;DXX zMG{#b<@*!@X@Pr?k4RAe&1==mL~wLZyz=NVruRxpO|swbee;#Tjpb8v$)>M~iiKm< zTuRgn`R&|XKuka^fVzs|N!`Rv++XH{P;{{641rq>_Kq5==GC$wYs`tJc7LO=y%UkVt0bo-2S;V_o_ zNLo%vxvG%(zZRLKpp{M=5Y?gx{7vxm>F|9HDeOpoisFt2<;k%UF$fqU;kQG6l$^2wyFGoJe^~Eo!=L&cWm3XZQG5l#%^q@ zL1Wu?8fzzMlk8Y+jK;Qk_V0hLbH2gzV$El+x#k%6nChC|;vyf-3=9+f?3A`h|HX8m z#BKEcYR~%TL>~^7xXQW};BElGgy)pf{AAG*H&Q%K6(CEL7IvO3Jlj&dy-;awTO~@()vHj%2ih^2m$P?U z<+?X=6Q0KvCs|X?O@S@5R7aqe4-tT-1z|T^B?L+Uq{tOWAd<|cvKFZWkQVEBChF(y z(IN3A{dkWm!I=YxF$13KO0q_7U5eNQndX7k6jXiw6-T6+xu_=#^zlL2xN(6J-Hh6AJj%|J=vqCuA+q7V^ zx7YtCVTyKOFL=@hezxi7fgUu9dyF(&-6Iul98>BZv}I@E-xL@_fhx5DXe6MuBH4`; zuT1l&djF0c-`4Rx_znl>Gt;TsQ^2CRbqt!I72rhhnYyBKHJ`OP&j;Ge4e3$%CUP)h`hr+p87gjF zWxvTBAN?~r1kp^y_(Lj?r!}6<8h*{Lh&bREhaldj(It=scDo1(Of-NY`5w3GmE_LW zB{}`3jz}S805}aLUqGCM!pDB1ijXZ1!KzCkLJx6)9<20nB61kmX!cD3;$M|HCm4pM?m$G13A60-7L*o1K0_u%Y8)G?5|a{WG{_Bv}~L zC}DKBN{7-=UX{>6oiDDabcR{h-?icxu?`IcYcr$dV}d`c#X`^=p(oD5;9y&DSMe(> zXpX?9>f8|k9;DYYk{ot z0Kgby9X@{x*m~@6^&)un}gL`SDU26j*bi!UWDN?V9JS(OV*6GaVl`#CsZ zj)0Hh&A99l+6c%X_Um8bIA&0|zYif;tz-R02yEz!LNYPWaA|b_+^2u**XnL7#TL9o z@HrOK1oUxrBAF`cEj%(indowsr zg$xC$l@5GLOtpeVm}0vxg*o~cZrD>l4zG8NEI)G zPPR50QJHu^QW+rrdQCUS-Mqp|znx7jPWip1e?G*iVM5Qs5!3jeY^(hnJ^ z-LEKb!@;TsS{!?Z^HcW2LX=w}d<>$+a$gXpv&ZwaVyi%T<&AWC{sxD$2H^FR*6_K7 zd=x{Dm?He~n92L?Lb*_IRqe&IjvmWS$%`H>>bik_^Qbe7Eb%d$BRF$5Kr1vNJ%I+j zB0)9^qea-P6@njV^0ntj8}vK$O*{pA5`FKIgD5%(#S)p;0io5H;-7^wtRqUe|LxAd zcNG)3s1dhE)d)^bm94iJI4US8H7*{jUar~5_8V4%oU3k50DX}m+OQDjh5VCB{dCS1|HmpHO9 z{#EVVqN$33O2aV?&H+J5fqK4{^$&&5DCI<~DNjt(#~A4aeP6rAD^!?oM|{0?%0bt0 zreomlS%ak`Sn^opGBzFfm|_8UUQz3v_BUP@Aql|`#49<1$OK&lo&3HwnvOW_i>Etc zW$tVA(iW$*X4Fw%AxcYD7o)WF7I9{@^HA>)Kk>6A!h+nrmX`h2mt5x2?WK zl(ltfwA{hmNbr#E?kVb^Gr$NpGXVzSIPdad|FF%wLdmW%FuhnK3rl?}$e6jrEw!Zg z`yI3Eni=M#K3THYb27FPHD8(0mcaH&zl`ademO!FZs-bGB5G~Q5a5#M1x6;U7)9=QUyNeEqD@6M%UFKwxad*1i z?z$z}o%ybiUp3I8 zbwbi9(QOb5>0nntGr}2qk5#d(4K?2h6_5PQ;fD$|zhq%cp_LbhJ_-Q;zNWS|)sAdB zjqc+*>h1M+Wx3KQYRm1k5EE61G9ns@vFucwU zDgQRkP-%+}ezCM31`nLoEhvD5!vcR*T9ur=$=-m$((v~rjKPAC_ra&3tdV}=nO~{y zyDJid5!kr!7f)IEh@-$lh zeZKdm`nPP}JTOSLK>gj_DgL%X6h9=TUmbyVjXta*yHhnT((TE`^TLjSSbE# zJ_IZXbxkSIzyqNj`zvHC`}5K6uSATJw@!GiLb0bL2%N}w?arreNT=Y?Gld|{)@pk@ zaf@I62JS8E%w&&YD09WADUt`|2pxUEN{e^=DI$^T1qNWJ3hQ8H=NV9#HEDZVaI<$& zu>(Rlf>9niu!HS`4t1rH{phs`x|Fu*N?*>pGxPz=iGbV?v20XaL_Vg%5U90#HTD&pUBi)^5f<|dRC&7x2Z?KGY#Em0A+VMq~pDWf)X5(9t2GuLMse0 zH1q6CDZB0q|FCAhQJvQy!XtflByb_WI5wA|Mm6jDFZ>1FXb0_iwbdUl>l~XHP>S|> zuIK;L0?5m(h~X@o3D?pF1`RbH+v#?8W7MtOS~4w$klu-f;-&gcJlqfjr=y9yZ?uXn z_PS)qdnNb>6%P*+ex)2%Y==++*{mwXrIn|hbGFV#3-ejiD;0_}J!UfkY6y^?gV--@ z#xqVsr#NU-X8Iw4u9u6^I7jkqrm%bD)~mIjq@3nwEY(GYhxp?09L#CFdR`d#67hWY zjKT|{&MziUUA+l7?5pzEC!>h>bx*$tFb&C_vqSLRhq%`m@p2D%5yvQ23zO2yQ3@*r)-)pgOl*IOSe;+e+gc1;loV&qV<<4~~8cwx8a) z!B86Q*JmBwZS!B6m7Ve33x(g7x%>zqZ?O`H>BH7#G=KS_D@a@(i^gTz^dGf}d0p}X z+_N+Yzd@q^Y8eB*8Hfyr78MU*U$#MBzo%Gu_BP8_^u1&$`vz7hzxouATT~G9`?x$` zT)B*aD)ZSQBV|~vI{X^U`eQRSGT<@*5=mRovJ2W1(u98nfvZ3(9=nf4Usev*+zzbA ztY#)!6CcHz%pcfk0Y%0R9zI@I~kM_rnjI z7~2unfv){)47^Fhxxn8}7OfD_uC7Y} z1Jc5j0DK@KzBXItKXs^|gYURhTDD95?^Y{sE8UG3rH|A~Yh*tJfz&DKG++erCfX|4 z?YEO$)xrb#an{dE)5(SbO13Tsx(6`hX8L&bQ|Az+I9d7oYPap}<0+`(dN18exHD7y zxQ>u+!*zwpC|MDhpItm#B}lAxrE!WaE>xiYx#?Jn=H_;56qrkBwH5gI2LdAJ7!S1B zJcvhm8$ELlv4_fze+f_Zk9Vz_aJ~7C7adLEaDqOVV{+ zJ@Pt9_br4mA@7U4yT%ax&`<^dp6?Ji3^yamDRS%W$BQHKw)l;lpvp2%Q$Q!~{eHOQ zx3L;hpzKjGhSzrvT3fi5Bo7OXQ#5fne3>UF@|8hxu!E{=GgCzDJ`jvi(n1Wcl$DYS zS6!^;qpf=?-8TJC+=Z0Q!*2c?Ez+WjEvkm-v~-fGY4-sb_^6zc>(ZsY`7&DCa$5jb zPFR9fm+o8++M`vz(C-^soc9>DXY2y1d_^Hvw~(EO&1hH79ka(L6Q1`quw$`6BvYQQ z&gN#HINPBuhlcHvVQrG{UZ$$mKhcqL8k+b;OilsDM~iUrXlFzga_8XYi?6Pxm5HZr z{Cd5ss)Hei)dfdrQlOLbBaqx4V~OMavGE6van=F=kr3e()W)ac=unhLbblVG@UEG> z>%O!Qf~Ys=A5J1ZvEUfLs97+6D?AbtW*Z_`<|^>XKzc8Z@~KOz$bP%-xLb^@bk zpr#jXg{&QcCcZ} z#`Xp~hZIHTVK*fT%%?ij9!vmN6l&tQHu~XAKorV^`Jib_U6q(a{!5~JJVdTs@?wd<^BZkg2lD$Gj~@{qxQj^a zIAREUkqQJmoN(yg;)FZ8zj%n|D0RIzX-3Mrd0M=T%Z+^gINkgm*qT$?@I3W&8*17_ z{nl=Ay&funn`6J)3A{xAsjYc*jLNK7aSk&!Sl8M_lT;etuHA4cj6Puf2eIosifONT zV4!;tE?1^=&81JqudUYIkq~IEf^iY32M|pYI4YN9#A9~1D2Kep7&U@w3RNF@FTG+; zPRO~Q6#v%FgwDC8P=XA-p!I9)Yj>O3F$XI|H)pUzy_U$b+|GWX;&ef!{J##eO*0~I zy$~u#48dyu+rqNun& zH!-uGyY04UCa;Y^2R;bmbv`(qhWWJD*Cb5r)O6l4D#$A|tm$lFX9}F|YNVtl{d%Dh zjIsHA-iLm7T`8ykjj6Amnlv8Od8TuQPkpAlk(Klt$Mx6DR+9K+%QzA;52h-)XLb{s2lqi4Wlcb2OVZhi6HArj9$vWp@$X&ZYz~Tm@ zfo_V5wK`Q46%KtTU8 zq_tLYrOTTuG{TqnnRJyD9!2NNor*o|bc-Cz!iFgIvDi|0e@C{+Wq#G~cdX7)ZLnue zIyrD8_*+|l);*z`ZRQj%wXS;$S8%>$;;+(wn}11dCC<*3l!-1*r4BI*JcI;7k!QSu zgoW{X0y-pN^Ews&fpwrLuxr68}dH!8*_a{zlXDGv)})L zit5k`E`Q+Awy`rM#ecz@U#BD*q)t05P(WWAqJlb(B`93=K0xyw%A92-N}cfTt_Y;u#1*fcDd)p-W%+C)z8t4zeA(`EN_$j~^lw zLLXa+q(N!i+`PyBHIX=qIz`_e__|v_^553^ZiU?gZCY$=w}{nfQFVR|FIF>p4r;Na zZ?J%R0pH+p1=3Ik?bEZZY9Q9=oHam}vygVn#7Drc1Qm48NcV1}&S4x?l|#6RFon{> zCOvi}cyp#;0MgMB0%8%t2K!UY8SKKKpDbcU z7Os4fY>GJix1vajO*v5!D_}se8iarc50@?0TDH;fcX{i|>k6-&9rlx|Ii^ilK$ulr zvm8NbuO4%H_m|6RIKKGg!95eMO|5QGgx0KCxQy83Q`;sSEQXtG1&>)Oq-o*I_T)o_ z!S4}<3Kc3jJAW5GS<-1G2x>ge6!NNz|`xgn%u{s11Um$R0p$0mz17x@ogYE#nHhgmhrEiGVzDO*}L zfjzpr{ zQrqDef|$qz#HbFSk7i9lo_>+637UYwv&}WMUp6Bw0s{eI7jl;`o_nMc-9x+UANVir zPafU1%`?!axA~N4;mBUO*ku(htlwhUEc`mYreR`I94z$mJ>2RJ$423};kEoCa9++z z{7U7kvgvt$aDe7hy@ptC8srSsOSEf25Z7OFJkA*m0QD)>Dzq)JUr&?EZ^)I?B8&Z{ zL*pXaxBB!NP#?8Pv$)$!A#LR7hiiD^+Y;n<)8A&+gmvl-D#!}Jv6=#d{cmM~VP)bs zluOuN)T`yDFc(NyF4#2lL9$Y*2Kjcl&MTko7k@Ke0{H}fTrrf}mTh9C+Pncc*u3M& z#Ws9@19i=Dc_k>7kEl#|HzX#b!~FE=i6PF`D?Uh%0A6Mb__ZfKjo85O-IatDMu{G) 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 K6w2g`gZ~dK`pppl literal 0 HcmV?d00001 diff --git a/docs/http/simple-http-server.png b/docs/http/simple-http-server.png new file mode 100644 index 0000000000000000000000000000000000000000..41d4a2574c9563fe77ab330c532f7de282f9d1da GIT binary patch literal 82962 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 #K8)0zu?3MVr^?A+hgQ1aw+`D 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

P1`CDQ^-~(&SFKV913*U}Qf%-kZy*PzsLY?& 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 AzW@LL literal 0 HcmV?d00001 diff --git a/model/http-common.yaml b/model/http-common.yaml index a32043336d..7ec914d2c7 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -44,12 +44,7 @@ groups: 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. - + note: > If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - ref: server.port @@ -57,9 +52,6 @@ groups: 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, `server.port` MUST match - URI port identifier; otherwise, it MUST match `Host` header port identifier. - id: attributes.http.server type: attribute_group @@ -72,30 +64,13 @@ groups: - ref: server.address 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](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - - 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header. - - MUST NOT include the port identifier. - + note: > + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). - ref: server.port 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](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header. + note: > + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). requirement_level: conditionally_required: If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). - ref: url.scheme diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 3a9984368b..b1801ed20b 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -7,35 +7,17 @@ groups: - ref: server.address requirement_level: opt_in note: | - Determined by using the first of the following that applies: - - - The [primary server name](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - - 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header. - - MUST NOT include the port identifier. - - Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker - to trigger cardinality limits, degrading the usefulness of the metric. - + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + > **Warning** + > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port requirement_level: opt_in note: | - Determined by using the first of the following that applies: - - - Port identifier of the [primary server host](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header. - - Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker - to trigger cardinality limits, degrading the usefulness of the metric. - + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + > **Warning** + > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > to trigger cardinality limits, degrading the usefulness of the metric. - id: metric_attributes.http.client type: attribute_group brief: 'HTTP client attributes' @@ -70,36 +52,19 @@ groups: 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](/docs/http/http-spans.md#http-server-definitions) of the matched virtual host. - - 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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Host identifier of the `Host` header. - - MUST NOT include the port identifier. - - Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker - to trigger cardinality limits, degrading the usefulness of the metric. - + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + > **Warning** + > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port requirement_level: opt_in 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](/docs/http/http-spans.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 [Forwarded#host](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host), - [X-Forwarded-Host](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host), or a similar header. - - Port identifier of the `Host` header. - - Warning: since this attribute may be based on HTTP headers, opting in to it may allow an attacker - to trigger cardinality limits, degrading the usefulness of the metric. + See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + > **Warning** + > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > to trigger cardinality limits, degrading the usefulness of the metric. - id: metric.http.server.request.body.size type: metric From 26f499279fd396d08d7d8cbfae22fe97ca754c26 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 26 Oct 2023 11:45:24 +0100 Subject: [PATCH 113/482] Add `system.cpu.frequency` metric. (#337) Signed-off-by: ChrsMark Co-authored-by: Pablo Baeyens --- CHANGELOG.md | 2 ++ docs/system/system-metrics.md | 17 +++++++++++++++++ model/metrics/system-metrics.yaml | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1382e9c0d..a7e7f656d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -182,6 +182,8 @@ release. - BREAKING: Rename `telemetry.auto.version` resource attribute to `telemetry.distro.version` and add `telemetry.distro.name` resource attribute ([#178](https://github.com/open-telemetry/semantic-conventions/pull/178)) +- Add `system.cpu.frequency` metric. + ([#337](https://github.com/open-telemetry/semantic-conventions/pull/337)) - Improve HTTP metric briefs. ([#366](https://github.com/open-telemetry/semantic-conventions/pull/366)) - Add `host.ip` resource attribute convention. diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 14254bf534..c7bdd1703f 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -26,6 +26,7 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam * [Metric: `system.cpu.utilization`](#metric-systemcpuutilization) * [Metric: `system.cpu.physical.count`](#metric-systemcpuphysicalcount) * [Metric: `system.cpu.logical.count`](#metric-systemcpulogicalcount) + * [Metric: `system.cpu.frequency`](#metric-systemcpufrequency) - [Memory Metrics](#memory-metrics) * [Metric: `system.memory.usage`](#metric-systemmemoryusage) * [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) @@ -145,6 +146,22 @@ This metric is [recommended][MetricRecommended]. +### Metric: `system.cpu.frequency` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.cpu.frequency` | Gauge | `{Hz}` | Reports the current frequency of the CPU in Hz | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | + + ## Memory Metrics **Description:** System level memory metrics capture under the namespace `system.memory`. diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index eb69d3f992..9f582e4b19 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -61,6 +61,15 @@ groups: - ref: system.cpu.state - ref: system.cpu.logical_number + - id: metric.system.cpu.frequency + type: metric + metric_name: system.cpu.frequency + brief: "Reports the current frequency of the CPU in Hz" + instrument: gauge + unit: "{Hz}" + attributes: + - ref: system.cpu.logical_number + - id: metric.system.cpu.physical.count type: metric metric_name: system.cpu.physical.count From 849304862252a9e50fc796b7dae220f6b10b09a2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 27 Oct 2023 00:58:23 -0700 Subject: [PATCH 114/482] Fix examples still using server.socket.address (#446) Co-authored-by: Alexander Wert --- docs/database/mongodb.md | 3 ++- docs/database/redis.md | 4 ++-- docs/database/sql.md | 3 ++- docs/http/http-spans.md | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index debad64014..9b11c5890c 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -29,8 +29,9 @@ described on this page. | `db.connection_string` | not set | | `db.user` | `"the_user"` | | `server.address` | `"mongodb0.example.com"` | -| `server.socket.address` | `"192.0.2.14"` | | `server.port` | `27017` | +| `network.peer.address` | `"192.0.2.14"` | +| `network.peer.port` | `27017` | | `network.transport` | `"IP.TCP"` | | `db.name` | `"shopDb"` | | `db.statement` | not set | diff --git a/docs/database/redis.md b/docs/database/redis.md index 9be10a987b..f15332906a 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -27,7 +27,7 @@ described on this page. ## Example -In this example, Redis is connected using a unix domain socket and therefore the connection string and `server.address` are left out. +In this example, Redis is connected using a unix domain socket and therefore the connection string is left out. Furthermore, `db.name` is not specified as there is no database name in Redis and `db.redis.database_index` is set instead. | Key | Value | @@ -36,7 +36,7 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.system` | `"redis"` | | `db.connection_string` | not set | | `db.user` | not set | -| `server.socket.address` | `"/tmp/redis.sock"` | +| `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"Unix"` | | `db.name` | not set | | `db.statement` | `"HMSET myhash field1 'Hello' field2 'World"` | diff --git a/docs/database/sql.md b/docs/database/sql.md index 70beb8eead..49abc4994c 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -31,8 +31,9 @@ This is an example of attributes for a MySQL database span: | `db.connection_string` | `"Server=shopdb.example.com;Database=ShopDb;Uid=billing_user;TableCache=true;UseCompression=True;MinimumPoolSize=10;MaximumPoolSize=50;"` | | `db.user` | `"billing_user"` | | `server.address` | `"shopdb.example.com"` | -| `server.socket.address` | `"192.0.2.12"` | | `server.port` | `3306` | +| `network.peer.address` | `"192.0.2.12"` | +| `network.peer.port` | `3306` | | `network.transport` | `"IP.TCP"` | | `db.name` | `"ShopDb"` | | `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index e57d33931f..d14ea4496a 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -401,8 +401,9 @@ Span name: `GET` | `network.protocol.version` | `"1.1"` | | `url.full` | `"https://example.com:8080/webshop/articles/4?s=1"` | | `server.address` | `example.com` | -| `server.port` | 8080 | -| `server.socket.address` | `"192.0.2.5"` | +| `server.port` | `8080` | +| `network.peer.address` | `"192.0.2.5"` | +| `network.peer.port` | `8080` | | `http.response.status_code` | `200` | The corresponding server Span may look like this: From 9b7193aa199cb0abe3a20b453ec19200d91da4b1 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Fri, 27 Oct 2023 09:20:13 +0100 Subject: [PATCH 115/482] Moved container attributes to the registry (#417) Signed-off-by: ChrsMark Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 2 + docs/attributes-registry/container.md | 30 +++++++++ docs/attributes-registry/oci.md | 14 +++++ docs/resource/container.md | 46 ++++---------- model/registry/container.yaml | 86 +++++++++++++++++++++++++ model/{resource => registry}/oci.yaml | 4 +- model/resource/container.yaml | 91 ++++----------------------- 7 files changed, 159 insertions(+), 114 deletions(-) create mode 100644 docs/attributes-registry/container.md create mode 100644 docs/attributes-registry/oci.md create mode 100644 model/registry/container.yaml rename model/{resource => registry}/oci.yaml (93%) diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 81002bd95a..a4995ec5f0 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,8 +27,10 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Container](container.md) * [HTTP](http.md) * [Network](network.md) +* [OCI](oci.md) * [RPC](rpc.md) * [URL](url.md) * [User agent](user-agent.md) diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md new file mode 100644 index 0000000000..7cc959620b --- /dev/null +++ b/docs/attributes-registry/container.md @@ -0,0 +1,30 @@ + + +# Container + +## Container Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | +| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | +| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | +| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | +| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | +| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | +| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | +| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | +| `container.labels.` | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | +| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | +| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | + +**[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + +**[2]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. +K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. +The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. + +**[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. + diff --git a/docs/attributes-registry/oci.md b/docs/attributes-registry/oci.md new file mode 100644 index 0000000000..abfc4f7479 --- /dev/null +++ b/docs/attributes-registry/oci.md @@ -0,0 +1,14 @@ +# Open Container Initiative (OCI) + +The [Open Container Initiative](https://opencontainers.org/) defines open industry standards around container formats and runtimes. + +## OCI Image Manifest + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | + +**[1]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). +An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). + \ No newline at end of file diff --git a/docs/resource/container.md b/docs/resource/container.md index 827e20b779..1abdd5c277 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -9,17 +9,18 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | Opt-In | -| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | -| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | -| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | Recommended | -| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | -| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | -| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | -| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | -| `container.labels.` | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | Recommended | -| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | -| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | +| [`container.command`](../attributes-registry/container.md) | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | Opt-In | +| [`container.command_args`](../attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | +| [`container.command_line`](../attributes-registry/container.md) | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | +| [`container.id`](../attributes-registry/container.md) | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | Recommended | +| [`container.image.id`](../attributes-registry/container.md) | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | +| [`container.image.name`](../attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | +| [`container.image.repo_digests`](../attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | +| [`container.image.tags`](../attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | +| [`container.labels.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | Recommended | +| [`container.name`](../attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | +| [`container.runtime`](../attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | +| [`oci.manifest.digest`](../attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [4] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | Recommended | **[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. @@ -28,29 +29,8 @@ K8s defines a link to the container registry repository with digest `"imageID": The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. **[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. - - -## Open Container Initiative (OCI) - -The [Open Container Initiative](https://opencontainers.org/) defines open industry standards around container formats and runtimes. - -### OCI Image Manifest - -This section refers to the [specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md) -that defines an OCI Image manifest. - -**Status**: [Experimental][DocumentStatus] - -**type:** `oci` - -**Description:** Attributes of an OCI image manifest. - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | Recommended | -**[1]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). +**[4]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). diff --git a/model/registry/container.yaml b/model/registry/container.yaml new file mode 100644 index 0000000000..6909fe4ecb --- /dev/null +++ b/model/registry/container.yaml @@ -0,0 +1,86 @@ +groups: + - id: registry.container + prefix: container + type: attribute_group + brief: > + A container instance. + attributes: + - id: name + type: string + brief: > + Container name used by container runtime. + examples: ['opentelemetry-autoconf'] + - id: id + type: string + brief: > + Container ID. Usually a UUID, as for example used to + [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). + The UUID might be abbreviated. + examples: ['a3bf90e006b2'] + - id: runtime + type: string + brief: > + The container runtime managing this container. + examples: ['docker', 'containerd', 'rkt'] + - id: image.name + type: string + brief: > + Name of the image the container was built on. + examples: ['gcr.io/opentelemetry/operator'] + - id: image.tags + type: string[] + brief: > + Container image tags. An example can be found in + [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). + Should be only the `` section of the full name for example + from `registry.example.com/my-org/my-image:`. + examples: ['v1.27.1', '3.5.7-0'] + - id: image.id + type: string + brief: > + Runtime specific image identifier. Usually a hash algorithm followed by a UUID. + note: > + Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker + container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) + endpoint. + + K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io + /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. + + The ID is assinged by the container runtime and can vary in different environments. + Consider using `oci.manifest.digest` if it is important to identify the same + image in different environments/runtimes. + examples: ['sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f'] + - id: image.repo_digests + type: string[] + brief: > + Repo digests of the container image as provided by the container runtime. + note: > + [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and + [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) + report those under the `RepoDigests` field. + examples: + - 'example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb' + - 'internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578' + - id: command + type: string + note: > + If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + brief: > + The command used to run the container (i.e. the command name). + examples: [ 'otelcontribcol' ] + - id: command_line + type: string + brief: > + The full command run by the container as a single string representing the full command. [2] + examples: [ 'otelcontribcol --config config.yaml' ] + - id: command_args + type: string[] + brief: > + All the command arguments (including the command/executable itself) run by the container. [2] + examples: [ 'otelcontribcol, --config, config.yaml' ] + - id: labels + type: template[string] + brief: > + Container labels, `` being the label name, the value being the label value. + examples: [ 'container.labels.app=nginx' ] diff --git a/model/resource/oci.yaml b/model/registry/oci.yaml similarity index 93% rename from model/resource/oci.yaml rename to model/registry/oci.yaml index fc1ff2ebb3..24e0cb93f2 100644 --- a/model/resource/oci.yaml +++ b/model/registry/oci.yaml @@ -1,7 +1,7 @@ groups: - - id: oci.manifest + - id: registry.oci.manifest prefix: oci.manifest - type: resource + type: attribute_group brief: > An OCI image manifest. attributes: diff --git a/model/resource/container.yaml b/model/resource/container.yaml index 2080b7b9c6..97923e440e 100644 --- a/model/resource/container.yaml +++ b/model/resource/container.yaml @@ -5,85 +5,18 @@ groups: brief: > A container instance. attributes: - - id: name - type: string - brief: > - Container name used by container runtime. - examples: ['opentelemetry-autoconf'] - - id: id - type: string - brief: > - Container ID. Usually a UUID, as for example used to - [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). - The UUID might be abbreviated. - examples: ['a3bf90e006b2'] - - id: runtime - type: string - brief: > - The container runtime managing this container. - examples: ['docker', 'containerd', 'rkt'] - - id: image.name - type: string - brief: > - Name of the image the container was built on. - examples: ['gcr.io/opentelemetry/operator'] - - id: image.tags - type: string[] - brief: > - Container image tags. An example can be found in - [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). - Should be only the `` section of the full name for example - from `registry.example.com/my-org/my-image:`. - examples: ['v1.27.1', '3.5.7-0'] - - id: image.id - type: string - brief: > - Runtime specific image identifier. Usually a hash algorithm followed by a UUID. - note: > - Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker - container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) - endpoint. - - K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io - /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. - - The ID is assinged by the container runtime and can vary in different environments. - Consider using `oci.manifest.digest` if it is important to identify the same - image in different environments/runtimes. - examples: ['sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f'] - - id: image.repo_digests - type: string[] - brief: > - Repo digests of the container image as provided by the container runtime. - note: > - [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and - [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) - report those under the `RepoDigests` field. - examples: - - 'example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb' - - 'internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578' - - id: command - type: string + - ref: container.name + - ref: container.id + - ref: container.runtime + - ref: container.image.name + - ref: container.image.tags + - ref: container.image.id + - ref: container.image.repo_digests + - ref: container.command requirement_level: opt_in - note: > - If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. - brief: > - The command used to run the container (i.e. the command name). - examples: [ 'otelcontribcol' ] - - id: command_line - type: string + - ref: container.command_line requirement_level: opt_in - brief: > - The full command run by the container as a single string representing the full command. [2] - examples: [ 'otelcontribcol --config config.yaml' ] - - id: command_args - type: string[] + - ref: container.command_args requirement_level: opt_in - brief: > - All the command arguments (including the command/executable itself) run by the container. [2] - examples: [ 'otelcontribcol, --config, config.yaml' ] - - id: labels - type: template[string] - brief: > - Container labels, `` being the label name, the value being the label value. - examples: [ 'container.labels.app=nginx' ] + - ref: container.labels + - ref: oci.manifest.digest From 76bb38700edb7b4bf0ef69bc4b6f4d04f6d58465 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 27 Oct 2023 01:21:42 -0700 Subject: [PATCH 116/482] Fix network.transport examples (#448) Co-authored-by: Joao Grassi Co-authored-by: Alexander Wert --- docs/database/mongodb.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 9b11c5890c..ef76976e27 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -32,7 +32,7 @@ described on this page. | `server.port` | `27017` | | `network.peer.address` | `"192.0.2.14"` | | `network.peer.port` | `27017` | -| `network.transport` | `"IP.TCP"` | +| `network.transport` | `"tcp"` | | `db.name` | `"shopDb"` | | `db.statement` | not set | | `db.operation` | `"findAndModify"` | diff --git a/docs/database/redis.md b/docs/database/redis.md index f15332906a..85efb0104f 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -37,7 +37,7 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.connection_string` | not set | | `db.user` | not set | | `network.peer.address` | `"/tmp/redis.sock"` | -| `network.transport` | `"Unix"` | +| `network.transport` | `"unix"` | | `db.name` | not set | | `db.statement` | `"HMSET myhash field1 'Hello' field2 'World"` | | `db.operation` | not set | diff --git a/docs/database/sql.md b/docs/database/sql.md index 49abc4994c..2bda71546a 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -34,7 +34,7 @@ This is an example of attributes for a MySQL database span: | `server.port` | `3306` | | `network.peer.address` | `"192.0.2.12"` | | `network.peer.port` | `3306` | -| `network.transport` | `"IP.TCP"` | +| `network.transport` | `"tcp"` | | `db.name` | `"ShopDb"` | | `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation` | `"SELECT"` | From 131637a718a5d6e0a29e1cbf503637dd2dfd343e Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Fri, 27 Oct 2023 10:31:00 +0200 Subject: [PATCH 117/482] Clarify how to report the total amount of memory (#409) Co-authored-by: Alexander Wert --- CHANGELOG.md | 4 ++++ docs/system/system-metrics.md | 24 +++++++++++++++++++++--- model/metrics/system-metrics.yaml | 16 +++++++++++++--- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7e7f656d5..96a01635d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ release. ([#429](https://github.com/open-telemetry/semantic-conventions/pull/429)) - Use seconds as default duration for FaaS duration histograms ([#384](https://github.com/open-telemetry/semantic-conventions/pull/384)) +- BREAKING: Remove `total` from list of well-known values of `system.memory.state` attribute. + ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) ### Features @@ -35,6 +37,8 @@ release. ([#348](https://github.com/open-telemetry/semantic-conventions/pull/348)) - Metric namespaces SHOULD NOT be pluralized. ([#267](https://github.com/open-telemetry/opentelemetry-specification/pull/267)) +- Add opt-in `system.memory.limit` metric. + ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) ### Fixes diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index c7bdd1703f..d5848d424d 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -29,6 +29,7 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam * [Metric: `system.cpu.frequency`](#metric-systemcpufrequency) - [Memory Metrics](#memory-metrics) * [Metric: `system.memory.usage`](#metric-systemmemoryusage) + * [Metric: `system.memory.limit`](#metric-systemmemorylimit) * [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) - [Paging/Swap Metrics](#pagingswap-metrics) * [Metric: `system.paging.usage`](#metric-systempagingusage) @@ -174,7 +175,10 @@ This metric is [recommended][MetricRecommended]. | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `system.memory.usage` | UpDownCounter | `By` | | +| `system.memory.usage` | UpDownCounter | `By` | Reports memory in use by state. [1] | + +**[1]:** The sum over all `system.memory.state` values SHOULD equal the total memory +available on the system, that is `system.memory.limit`. @@ -186,7 +190,6 @@ This metric is [recommended][MetricRecommended]. | Value | Description | |---|---| -| `total` | total | | `used` | used | | `free` | free | | `shared` | shared | @@ -194,6 +197,21 @@ This metric is [recommended][MetricRecommended]. | `cached` | cached | +### Metric: `system.memory.limit` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `system.memory.limit` | UpDownCounter | `By` | Total memory available in the system. [1] | + +**[1]:** Its value SHOULD equal the sum of `system.memory.state` over all states. + + + + + ### Metric: `system.memory.utilization` This metric is [recommended][MetricRecommended]. @@ -213,7 +231,6 @@ This metric is [recommended][MetricRecommended]. | Value | Description | |---|---| -| `total` | total | | `used` | used | | `free` | free | | `shared` | shared | @@ -769,6 +786,7 @@ an `{os}` prefix to split this metric across OSes. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md [MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in ### Metric: `system.linux.memory.available` diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 9f582e4b19..d3c761b0b9 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -96,8 +96,6 @@ groups: type: allow_custom_values: true members: - - id: total - value: 'total' - id: used value: 'used' - id: free @@ -114,12 +112,24 @@ groups: - id: metric.system.memory.usage type: metric metric_name: system.memory.usage - brief: "" + brief: "Reports memory in use by state." + note: | + The sum over all `system.memory.state` values SHOULD equal the total memory + available on the system, that is `system.memory.limit`. instrument: updowncounter unit: "By" attributes: - ref: system.memory.state + - id: metric.system.memory.limit + type: metric + metric_name: system.memory.limit + brief: "Total memory available in the system." + note: | + Its value SHOULD equal the sum of `system.memory.state` over all states. + instrument: updowncounter + unit: "By" + - id: metric.system.memory.utilization type: metric metric_name: system.memory.utilization From fde7b11e61123c9d88a97034b3a359b8ad7c5fd4 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Fri, 27 Oct 2023 16:13:49 +0200 Subject: [PATCH 118/482] Moved thread and code to the registry (#434) Signed-off-by: Alexander Wert --- docs/attributes-registry/README.md | 2 ++ docs/attributes-registry/code.md | 18 ++++++++++++ docs/attributes-registry/thread.md | 15 ++++++++++ docs/general/attributes.md | 14 +++++----- model/general.yaml | 45 +++++------------------------- model/registry/code.yaml | 33 ++++++++++++++++++++++ model/registry/thread.yaml | 17 +++++++++++ 7 files changed, 99 insertions(+), 45 deletions(-) create mode 100644 docs/attributes-registry/code.md create mode 100644 docs/attributes-registry/thread.md create mode 100644 model/registry/code.yaml create mode 100644 model/registry/thread.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index a4995ec5f0..b23e40cca5 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,11 +27,13 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Code](code.md) * [Container](container.md) * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) * [RPC](rpc.md) +* [Thread](thread.md) * [URL](url.md) * [User agent](user-agent.md) diff --git a/docs/attributes-registry/code.md b/docs/attributes-registry/code.md new file mode 100644 index 0000000000..a337e239ed --- /dev/null +++ b/docs/attributes-registry/code.md @@ -0,0 +1,18 @@ + + +# Code + +These attributes allow to report this unit of code and therefore to provide more context about the telemetry data. + +## Code Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | +| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | +| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | +| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | +| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | + \ No newline at end of file diff --git a/docs/attributes-registry/thread.md b/docs/attributes-registry/thread.md new file mode 100644 index 0000000000..5a71c29cc8 --- /dev/null +++ b/docs/attributes-registry/thread.md @@ -0,0 +1,15 @@ + + +# Thread + +These attributes may be used for any operation to store information about a thread. + +## Thread Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | +| `thread.name` | string | Current thread name. | `main` | + \ No newline at end of file diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 047ae02744..5f2e6a3280 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -358,8 +358,8 @@ a thread that started a span. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | -| `thread.name` | string | Current thread name. | `main` | Recommended | +| [`thread.id`](../attributes-registry/thread.md) | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | +| [`thread.name`](../attributes-registry/thread.md) | string | Current thread name. | `main` | Recommended | Examples of where `thread.id` and `thread.name` can be extracted from: @@ -384,11 +384,11 @@ about the span. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | Recommended | -| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | Recommended | -| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | -| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | Recommended | -| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | +| [`code.column`](../attributes-registry/code.md) | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | Recommended | +| [`code.filepath`](../attributes-registry/code.md) | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | Recommended | +| [`code.function`](../attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | +| [`code.lineno`](../attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | Recommended | +| [`code.namespace`](../attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/general.yaml b/model/general.yaml index 5994c16ff4..cfcce21cef 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -37,50 +37,19 @@ groups: or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). examples: 'read:message, write:files' - id: thread - prefix: thread type: span brief: > These attributes may be used for any operation to store information about a thread that started a span. attributes: - - id: id - type: int - brief: > - Current "managed" thread ID (as opposed to OS thread ID). - examples: 42 - - id: name - type: string - brief: > - Current thread name. - examples: main + - ref: thread.id + - ref: thread.name - id: code - prefix: code type: span brief: > These attributes allow to report this unit of code and therefore to provide more context about the span. attributes: - - id: function - type: string - brief: > - The method or function name, or equivalent (usually rightmost part of the code unit's name). - examples: serveRequest - - id: namespace - type: string - brief: > - The "namespace" within which `code.function` is defined. Usually the qualified class or module name, - such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. - examples: com.example.MyHttpService - - id: filepath - type: string - brief: > - The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). - examples: /usr/local/MyApplication/content_root/app/index.php - - id: lineno - type: int - brief: > - The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - examples: 42 - - id: column - type: int - brief: > - The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - examples: 16 + - ref: code.function + - ref: code.namespace + - ref: code.filepath + - ref: code.lineno + - ref: code.column diff --git a/model/registry/code.yaml b/model/registry/code.yaml new file mode 100644 index 0000000000..373a4bc6c3 --- /dev/null +++ b/model/registry/code.yaml @@ -0,0 +1,33 @@ +groups: + - id: registry.code + prefix: code + type: span + brief: > + These attributes allow to report this unit of code and therefore to provide more context about the span. + attributes: + - id: function + type: string + brief: > + The method or function name, or equivalent (usually rightmost part of the code unit's name). + examples: serveRequest + - id: namespace + type: string + brief: > + The "namespace" within which `code.function` is defined. Usually the qualified class or module name, + such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. + examples: com.example.MyHttpService + - id: filepath + type: string + brief: > + The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). + examples: /usr/local/MyApplication/content_root/app/index.php + - id: lineno + type: int + brief: > + The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + examples: 42 + - id: column + type: int + brief: > + The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + examples: 16 diff --git a/model/registry/thread.yaml b/model/registry/thread.yaml new file mode 100644 index 0000000000..f6b5b5a509 --- /dev/null +++ b/model/registry/thread.yaml @@ -0,0 +1,17 @@ +groups: + - id: registry.thread + prefix: thread + type: span + brief: > + These attributes may be used for any operation to store information about a thread that started a span. + attributes: + - id: id + type: int + brief: > + Current "managed" thread ID (as opposed to OS thread ID). + examples: 42 + - id: name + type: string + brief: > + Current thread name. + examples: main From 03aba2a50cff60c00bef9c5dd9dfd768e6b8b26f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 27 Oct 2023 07:33:38 -0700 Subject: [PATCH 119/482] Change the precedence between `:authority` and `Host` headers when populating `server.address` and `server.port` attributes (#455) Co-authored-by: Liudmila Molkova Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/http/http-spans.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a01635d5..c85977b6f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,9 @@ release. ([#413](https://github.com/open-telemetry/semantic-conventions/pull/413)) - Clarify HTTP server definitions and `server.address|port` notes. ([#423](https://github.com/open-telemetry/semantic-conventions/pull/423)) +- Change the precedence between `:authority` and `Host` headers when populating + `server.address` and `server.port` attributes. + ([#455](https://github.com/open-telemetry/semantic-conventions/pull/455)) ## v1.22.0 (2023-10-12) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index d14ea4496a..f11fae9ee9 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -312,8 +312,8 @@ In the context of HTTP server, `server.address` and `server.port` attributes cap HTTP server instrumentations SHOULD do the best effort when populating `server.address` and `server.port` attributes and SHOULD determine them by using the first of the following that applies: * The original host which may be passed by the reverse proxy in the [`Forwarded#host`][Forwarded], [`X-Forwarded-Host`][X-Forwarded-Host], or a similar header. -* The [`Host`][Host header] header. * The [`:authority`][HTTP/2 authority] pseudo-header in case of HTTP/2 or HTTP/3 +* The [`Host`][Host header] header. > **Note**: The `Host` and `:authority` headers contain host and port number of the server. The same applies to the `host` identifier of `Forwarded` header or the `X-Forwarded-Host` header. Instrumentations SHOULD populate both `server.address` and `server.port` attributes by parsing the value of corresponding header. From a3bec5e5c0a979ab895fac9f96b934b610ff871d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 28 Oct 2023 02:05:20 -0700 Subject: [PATCH 120/482] Remove `url.path` default value (#462) --- CHANGELOG.md | 2 ++ docs/attributes-registry/url.md | 8 +++----- docs/http/http-spans.md | 12 +++++------- docs/url/url.md | 8 +++----- model/registry/url.yaml | 1 - 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c85977b6f9..f08fcdcd49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ release. ([#384](https://github.com/open-telemetry/semantic-conventions/pull/384)) - BREAKING: Remove `total` from list of well-known values of `system.memory.state` attribute. ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) +- Remove `url.path` default value. + ([#462](https://github.com/open-telemetry/semantic-conventions/pull/462)) ### Features diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index f3997f3d96..f361f46e8b 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -10,15 +10,13 @@ linkTitle: URL |---|---|---|---| | `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | | `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | | `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. -**[2]:** When missing, the value is assumed to be `/` - -**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[2]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. \ No newline at end of file diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index f11fae9ee9..9fb630a43a 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -351,9 +351,9 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. @@ -368,11 +368,9 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). -**[7]:** When missing, the value is assumed to be `/` +**[7]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[8]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/url/url.md b/docs/url/url.md index a85c4cbb59..f9605574ee 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -27,17 +27,15 @@ This document defines semantic conventions that describe URL and its components. |---|---|---|---|---| | [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Recommended | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | Recommended | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. -**[2]:** When missing, the value is assumed to be `/` - -**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[2]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. ## Sensitive information diff --git a/model/registry/url.yaml b/model/registry/url.yaml index ea626baa32..0e0d202720 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -25,7 +25,6 @@ groups: type: string brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' examples: ['/search'] - note: When missing, the value is assumed to be `/` - id: query type: string brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' From 3070635a74294ffc235de6f98fa838f9a74e6515 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 01:14:10 -0700 Subject: [PATCH 121/482] Remove conditional requirement on `network.peer.address` and `network.peer.port` (#449) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/database/database-spans.md | 2 +- docs/http/http-spans.md | 6 ++---- docs/messaging/messaging-spans.md | 2 +- docs/rpc/rpc-spans.md | 4 ++-- model/trace/database.yaml | 2 -- model/trace/http.yaml | 12 ++++-------- model/trace/messaging.yaml | 2 -- model/trace/rpc.yaml | 4 ---- 9 files changed, 12 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f08fcdcd49..c2b5d85136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ release. ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) - Remove `url.path` default value. ([#462](https://github.com/open-telemetry/semantic-conventions/pull/462)) +- Remove conditional requirement on `network.peer.address` and `network.peer.port` + ([#449](https://github.com/open-telemetry/semantic-conventions/pull/449)) ### Features diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 65cccffab1..92678e42c5 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -67,7 +67,7 @@ Some database systems may allow a connection to switch to a different `db.user`, | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 9fb630a43a..cee0b7738c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -126,6 +126,8 @@ sections below. | [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | @@ -232,8 +234,6 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.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] | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | @@ -347,8 +347,6 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index bf70deff59..009b5ff501 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -229,7 +229,7 @@ The following operations related to messages are defined for these semantic conv | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | | `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [15] | `publish` | Required | | `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index af881e2114..3d9e12185c 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -158,7 +158,7 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `server.address`. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | @@ -169,7 +169,7 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended: If different than `client.address`. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 0f5db8edb7..7540e58c15 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -237,8 +237,6 @@ groups: requirement_level: conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - ref: network.peer.address - requirement_level: - recommended: If different than `server.address`. tag: connection-level - ref: network.peer.port requirement_level: diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 5749f3a6f5..a6b48c28c5 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -19,6 +19,10 @@ groups: - ref: http.request.method sampling_relevant: true requirement_level: required + - ref: network.peer.address + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. - ref: network.transport requirement_level: opt_in note: > @@ -39,12 +43,6 @@ groups: sampling_relevant: true - ref: server.port sampling_relevant: true - - ref: network.peer.address - requirement_level: - recommended: If different than `server.address`. - - ref: network.peer.port - requirement_level: - recommended: If `network.peer.address` is set. - ref: url.full sampling_relevant: true requirement_level: required @@ -78,8 +76,6 @@ groups: The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. - - ref: network.peer.address - - ref: network.peer.port - ref: url.path requirement_level: required sampling_relevant: true diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index d2cfab3302..ccad5e1289 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -174,8 +174,6 @@ groups: requirement_level: conditionally_required: If available. - ref: network.peer.address - requirement_level: - recommended: If different than `server.address`. tag: connection-level - ref: network.peer.port requirement_level: diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 29fa0bf9be..02a64dbce4 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -29,8 +29,6 @@ groups: extends: rpc attributes: - ref: network.peer.address - requirement_level: - recommended: If different than `server.address`. - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. @@ -44,8 +42,6 @@ groups: - ref: client.address - ref: client.port - ref: network.peer.address - requirement_level: - recommended: If different than `client.address`. - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. From 002ace1b08dd386a212615351d5bab1123796f96 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 03:25:49 -0700 Subject: [PATCH 122/482] Change `user_agent.original` from recommended to opt-in on HTTP client spans (#468) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 3 ++- model/trace/http.yaml | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2b5d85136..aa09e19c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ release. ([#462](https://github.com/open-telemetry/semantic-conventions/pull/462)) - Remove conditional requirement on `network.peer.address` and `network.peer.port` ([#449](https://github.com/open-telemetry/semantic-conventions/pull/449)) +- Change `user_agent.original` from recommended to opt-in on HTTP client spans. + ([#468](https://github.com/open-telemetry/semantic-conventions/pull/468)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index cee0b7738c..9b5ac4ba25 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -131,7 +131,6 @@ sections below. | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -237,6 +236,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../general/attributes.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] | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Opt-In | **[1]:** 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). @@ -352,6 +352,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | | [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index a6b48c28c5..47a2ff9a34 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -28,7 +28,6 @@ groups: note: > Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. - - ref: user_agent.original - id: trace.http.client type: span @@ -46,6 +45,8 @@ groups: - ref: url.full sampling_relevant: true requirement_level: required + - ref: user_agent.original + requirement_level: opt_in - id: trace.http.server type: span @@ -85,3 +86,4 @@ groups: sampling_relevant: true - ref: url.scheme sampling_relevant: true + - ref: user_agent.original From 12e49ad056c5361883a5ac593eaae1cf2d9610f1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 03:32:39 -0700 Subject: [PATCH 123/482] Update text to reflect recent change in #423 (#464) Co-authored-by: Joao Grassi --- docs/http/http-metrics.md | 16 ++++++++-------- model/metrics/http.yaml | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 2dcfd27171..be6b93d449 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -127,12 +127,12 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -196,12 +196,12 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[2]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[3]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. `http.request.method` 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. @@ -288,12 +288,12 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. @@ -388,12 +388,12 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** -> Since this attribute may be based on HTTP headers, opting in to it may allow an attacker +> Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. **[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index b1801ed20b..233ca32993 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -9,14 +9,14 @@ groups: note: | See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** - > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port requirement_level: opt_in note: | See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** - > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. - id: metric_attributes.http.client type: attribute_group @@ -54,7 +54,7 @@ groups: note: | See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** - > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. - ref: server.port requirement_level: opt_in @@ -63,7 +63,7 @@ groups: note: | See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** - > Since this attribute may be based on HTTP headers, opting in to it may allow an attacker + > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. - id: metric.http.server.request.body.size From a2bbcc3f216f9f046dfe5d94ac1171ac1c1e2f7d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 03:40:41 -0700 Subject: [PATCH 124/482] Update `Forwarded` header links to use specific anchors (#458) Co-authored-by: Joao Grassi --- docs/http/http-metrics.md | 6 +++--- docs/http/http-spans.md | 10 +++++----- model/http-common.yaml | 2 +- model/trace/http.yaml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index be6b93d449..9db7178843 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -135,7 +135,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -296,7 +296,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -396,7 +396,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 9b5ac4ba25..380e47f30c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -311,7 +311,7 @@ In the context of HTTP server, `server.address` and `server.port` attributes cap HTTP server instrumentations SHOULD do the best effort when populating `server.address` and `server.port` attributes and SHOULD determine them by using the first of the following that applies: -* The original host which may be passed by the reverse proxy in the [`Forwarded#host`][Forwarded], [`X-Forwarded-Host`][X-Forwarded-Host], or a similar header. +* The original host which may be passed by the reverse proxy in the [`Forwarded#host`][Forwarded#host], [`X-Forwarded-Host`][X-Forwarded-Host], or a similar header. * The [`:authority`][HTTP/2 authority] pseudo-header in case of HTTP/2 or HTTP/3 * The [`Host`][Host header] header. @@ -330,7 +330,7 @@ Application developers MAY overwrite potentially inaccurate values of `server.*` [Host and authority]: https://tools.ietf.org/html/rfc9110#section-7.2 [Host header]: https://tools.ietf.org/html/rfc7230#section-5.4 [HTTP/2 authority]: https://tools.ietf.org/html/rfc9113#section-8.3.1 -[Forwarded]: https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded +[Forwarded#host]: https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host [X-Forwarded-Host]: https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host ### HTTP Server semantic conventions @@ -343,7 +343,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | +| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | @@ -354,7 +354,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | -**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. +**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. **[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. @@ -369,7 +369,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[7]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/model/http-common.yaml b/model/http-common.yaml index 7ec914d2c7..a3b8970db0 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -78,7 +78,7 @@ groups: examples: ["http", "https"] note: > The scheme of the original client request, if known - (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), + (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 47a2ff9a34..e811dc4296 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -68,14 +68,14 @@ groups: - ref: client.address note: > The IP address of the original client behind all proxies, if - known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded), + known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. examples: ['83.164.160.102'] - ref: client.port brief: > The port of the original client behind all proxies, if - known (e.g. from [Forwarded](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded) or a similar header). + known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for) or a similar header). Otherwise, the immediate client peer port. - ref: url.path requirement_level: required From ed054bc8287e7f6cf302149140e9739a127976f7 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Mon, 30 Oct 2023 04:52:35 -0600 Subject: [PATCH 125/482] Move cloud attributes to the registry (#453) Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/cloud.md | 85 ++++++++++++++ docs/faas/faas-spans.md | 2 +- docs/resource/cloud.md | 14 +-- docs/resource/faas.md | 2 +- model/registry/cloud.yaml | 179 +++++++++++++++++++++++++++++ model/resource/cloud.yaml | 178 +--------------------------- 7 files changed, 280 insertions(+), 181 deletions(-) create mode 100644 docs/attributes-registry/cloud.md create mode 100644 model/registry/cloud.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index b23e40cca5..fdff795789 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,6 +27,7 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Cloud](cloud.md) * [Code](code.md) * [Container](container.md) * [HTTP](http.md) diff --git a/docs/attributes-registry/cloud.md b/docs/attributes-registry/cloud.md new file mode 100644 index 0000000000..a51ac490aa --- /dev/null +++ b/docs/attributes-registry/cloud.md @@ -0,0 +1,85 @@ + + +# Cloud + +## Cloud Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | +| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | +| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | +| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | +| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | +| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | + +**[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. + +**[2]:** The prefix of the service SHOULD match the one specified in `cloud.provider`. + +**[3]:** Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). + +**[4]:** On some cloud providers, it may not be possible to determine the full ID at startup, +so it may be necessary to set `cloud.resource_id` as a span attribute instead. + +The exact value to use for `cloud.resource_id` depends on the cloud provider. +The following well-known definitions MUST be used if you set this attribute and they apply: + +* **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invokable with + multiple different aliases. +* **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) +* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. + +`cloud.platform` 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 | +|---|---| +| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | +| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | +| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | +| `aws_ec2` | AWS Elastic Compute Cloud | +| `aws_ecs` | AWS Elastic Container Service | +| `aws_eks` | AWS Elastic Kubernetes Service | +| `aws_lambda` | AWS Lambda | +| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | +| `aws_app_runner` | AWS App Runner | +| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | +| `azure_vm` | Azure Virtual Machines | +| `azure_container_instances` | Azure Container Instances | +| `azure_aks` | Azure Kubernetes Service | +| `azure_functions` | Azure Functions | +| `azure_app_service` | Azure App Service | +| `azure_openshift` | Azure Red Hat OpenShift | +| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | +| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | +| `gcp_cloud_run` | Google Cloud Run | +| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | +| `gcp_cloud_functions` | Google Cloud Functions (GCF) | +| `gcp_app_engine` | Google Cloud App Engine (GAE) | +| `gcp_openshift` | Red Hat OpenShift on Google Cloud | +| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | +| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | +| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | +| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | + +`cloud.provider` 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 | +|---|---| +| `alibaba_cloud` | Alibaba Cloud | +| `aws` | Amazon Web Services | +| `azure` | Microsoft Azure | +| `gcp` | Google Cloud Platform | +| `heroku` | Heroku Platform as a Service | +| `ibm_cloud` | IBM Cloud | +| `tencent_cloud` | Tencent Cloud | + \ No newline at end of file diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index bb3012e92e..8088cf7c42 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -41,7 +41,7 @@ If Spans following this convention are produced, a Resource of type `faas` MUST | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`cloud.resource_id`](../resource/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | | `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | | `faas.trigger` | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index f255b94025..c8ced8c2c3 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -6,15 +6,15 @@ **Description:** A cloud infrastructure (e.g. GCP, Azure, AWS). - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | Recommended | -| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | Recommended | -| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | Recommended | -| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | -| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | Recommended | -| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.account.id`](../attributes-registry/cloud.md) | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | Recommended | +| [`cloud.availability_zone`](../attributes-registry/cloud.md) | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | Recommended | +| [`cloud.platform`](../attributes-registry/cloud.md) | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | Recommended | +| [`cloud.provider`](../attributes-registry/cloud.md) | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | +| [`cloud.region`](../attributes-registry/cloud.md) | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | Recommended | +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. diff --git a/docs/resource/faas.md b/docs/resource/faas.md index e38f88c7db..c83eabc193 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -16,7 +16,7 @@ See also: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`cloud.resource_id`](cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | | `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | | `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | | `faas.name` | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml new file mode 100644 index 0000000000..695bf64719 --- /dev/null +++ b/model/registry/cloud.yaml @@ -0,0 +1,179 @@ +groups: + - id: registry.cloud + prefix: cloud + type: attribute_group + brief: > + A cloud environment (e.g. GCP, Azure, AWS). + attributes: + - id: provider + type: + allow_custom_values: true + members: + - id: 'alibaba_cloud' + value: 'alibaba_cloud' + brief: 'Alibaba Cloud' + - id: 'aws' + value: 'aws' + brief: 'Amazon Web Services' + - id: 'azure' + value: 'azure' + brief: 'Microsoft Azure' + - id: 'gcp' + value: 'gcp' + brief: 'Google Cloud Platform' + - id: 'heroku' + value: 'heroku' + brief: 'Heroku Platform as a Service' + - id: 'ibm_cloud' + value: 'ibm_cloud' + brief: 'IBM Cloud' + - id: 'tencent_cloud' + value: 'tencent_cloud' + brief: 'Tencent Cloud' + + brief: > + Name of the cloud provider. + - id: account.id + type: string + brief: > + The cloud account ID the resource is assigned to. + examples: ['111111111111', 'opentelemetry'] + - id: region + type: string + brief: > + The geographical region the resource is running. + note: > + Refer to your provider's docs to see the available regions, for example + [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), + [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), + [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), + [Google Cloud regions](https://cloud.google.com/about/locations), + or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). + examples: ['us-central1', 'us-east-1'] + - id: resource_id + type: string + brief: > + Cloud provider-specific native identifier of the monitored cloud resource + (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, + a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, + a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) + note: | + On some cloud providers, it may not be possible to determine the full ID at startup, + so it may be necessary to set `cloud.resource_id` as a span attribute instead. + + The exact value to use for `cloud.resource_id` depends on the cloud provider. + The following well-known definitions MUST be used if you set this attribute and they apply: + + * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invokable with + multiple different aliases. + * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) + * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. + examples: + - 'arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function' + - '//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID' + - '/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/' + - id: availability_zone + type: string + brief: > + Cloud regions often have multiple, isolated locations known as zones + to increase availability. Availability zone represents the + zone where the resource is running. + note: > + Availability zones are called "zones" on Alibaba Cloud and Google Cloud. + examples: ['us-east-1c'] + - id: platform + type: + allow_custom_values: true + members: + - id: alibaba_cloud_ecs + value: 'alibaba_cloud_ecs' + brief: Alibaba Cloud Elastic Compute Service + - id: alibaba_cloud_fc + value: 'alibaba_cloud_fc' + brief: Alibaba Cloud Function Compute + - id: alibaba_cloud_openshift + value: 'alibaba_cloud_openshift' + brief: Red Hat OpenShift on Alibaba Cloud + - id: aws_ec2 + value: 'aws_ec2' + brief: AWS Elastic Compute Cloud + - id: aws_ecs + value: 'aws_ecs' + brief: AWS Elastic Container Service + - id: aws_eks + value: 'aws_eks' + brief: AWS Elastic Kubernetes Service + - id: aws_lambda + value: 'aws_lambda' + brief: AWS Lambda + - id: aws_elastic_beanstalk + value: 'aws_elastic_beanstalk' + brief: AWS Elastic Beanstalk + - id: aws_app_runner + value: 'aws_app_runner' + brief: AWS App Runner + - id: aws_openshift + value: 'aws_openshift' + brief: Red Hat OpenShift on AWS (ROSA) + - id: azure_vm + value: 'azure_vm' + brief: Azure Virtual Machines + - id: azure_container_instances + value: 'azure_container_instances' + brief: Azure Container Instances + - id: azure_aks + value: 'azure_aks' + brief: Azure Kubernetes Service + - id: azure_functions + value: 'azure_functions' + brief: Azure Functions + - id: azure_app_service + value: 'azure_app_service' + brief: Azure App Service + - id: azure_openshift + value: 'azure_openshift' + brief: Azure Red Hat OpenShift + - id: gcp_bare_metal_solution + value: 'gcp_bare_metal_solution' + brief: Google Bare Metal Solution (BMS) + - id: gcp_compute_engine + value: 'gcp_compute_engine' + brief: Google Cloud Compute Engine (GCE) + - id: gcp_cloud_run + value: 'gcp_cloud_run' + brief: Google Cloud Run + - id: gcp_kubernetes_engine + value: 'gcp_kubernetes_engine' + brief: Google Cloud Kubernetes Engine (GKE) + - id: gcp_cloud_functions + value: 'gcp_cloud_functions' + brief: Google Cloud Functions (GCF) + - id: gcp_app_engine + value: 'gcp_app_engine' + brief: Google Cloud App Engine (GAE) + - id: gcp_openshift + value: 'gcp_openshift' + brief: Red Hat OpenShift on Google Cloud + - id: ibm_cloud_openshift + value: 'ibm_cloud_openshift' + brief: Red Hat OpenShift on IBM Cloud + - id: tencent_cloud_cvm + value: 'tencent_cloud_cvm' + brief: Tencent Cloud Cloud Virtual Machine (CVM) + - id: tencent_cloud_eks + value: 'tencent_cloud_eks' + brief: Tencent Cloud Elastic Kubernetes Service (EKS) + - id: tencent_cloud_scf + value: 'tencent_cloud_scf' + brief: Tencent Cloud Serverless Cloud Function (SCF) + brief: > + The cloud platform in use. + note: > + The prefix of the service SHOULD match the one specified in `cloud.provider`. diff --git a/model/resource/cloud.yaml b/model/resource/cloud.yaml index 0e3e2e2b17..4699f84842 100644 --- a/model/resource/cloud.yaml +++ b/model/resource/cloud.yaml @@ -5,175 +5,9 @@ groups: brief: > A cloud environment (e.g. GCP, Azure, AWS) attributes: - - id: provider - type: - allow_custom_values: true - members: - - id: 'alibaba_cloud' - value: 'alibaba_cloud' - brief: 'Alibaba Cloud' - - id: 'aws' - value: 'aws' - brief: 'Amazon Web Services' - - id: 'azure' - value: 'azure' - brief: 'Microsoft Azure' - - id: 'gcp' - value: 'gcp' - brief: 'Google Cloud Platform' - - id: 'heroku' - value: 'heroku' - brief: 'Heroku Platform as a Service' - - id: 'ibm_cloud' - value: 'ibm_cloud' - brief: 'IBM Cloud' - - id: 'tencent_cloud' - value: 'tencent_cloud' - brief: 'Tencent Cloud' - - brief: > - Name of the cloud provider. - - id: account.id - type: string - brief: > - The cloud account ID the resource is assigned to. - examples: ['111111111111', 'opentelemetry'] - - id: region - type: string - brief: > - The geographical region the resource is running. - note: > - Refer to your provider's docs to see the available regions, for example - [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), - [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), - [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), - [Google Cloud regions](https://cloud.google.com/about/locations), - or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). - examples: ['us-central1', 'us-east-1'] - - id: resource_id - type: string - brief: > - Cloud provider-specific native identifier of the monitored cloud resource - (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, - a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, - a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) - note: | - On some cloud providers, it may not be possible to determine the full ID at startup, - so it may be necessary to set `cloud.resource_id` as a span attribute instead. - - The exact value to use for `cloud.resource_id` depends on the cloud provider. - The following well-known definitions MUST be used if you set this attribute and they apply: - - * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). - Take care not to use the "invoked ARN" directly but replace any - [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) - with the resolved function version, as the same runtime instance may be invokable with - multiple different aliases. - * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) - * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form - `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. - This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - a TracerProvider. - examples: - - 'arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function' - - '//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID' - - '/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/' - - id: availability_zone - type: string - brief: > - Cloud regions often have multiple, isolated locations known as zones - to increase availability. Availability zone represents the - zone where the resource is running. - note: > - Availability zones are called "zones" on Alibaba Cloud and Google Cloud. - examples: ['us-east-1c'] - - id: platform - type: - allow_custom_values: true - members: - - id: alibaba_cloud_ecs - value: 'alibaba_cloud_ecs' - brief: Alibaba Cloud Elastic Compute Service - - id: alibaba_cloud_fc - value: 'alibaba_cloud_fc' - brief: Alibaba Cloud Function Compute - - id: alibaba_cloud_openshift - value: 'alibaba_cloud_openshift' - brief: Red Hat OpenShift on Alibaba Cloud - - id: aws_ec2 - value: 'aws_ec2' - brief: AWS Elastic Compute Cloud - - id: aws_ecs - value: 'aws_ecs' - brief: AWS Elastic Container Service - - id: aws_eks - value: 'aws_eks' - brief: AWS Elastic Kubernetes Service - - id: aws_lambda - value: 'aws_lambda' - brief: AWS Lambda - - id: aws_elastic_beanstalk - value: 'aws_elastic_beanstalk' - brief: AWS Elastic Beanstalk - - id: aws_app_runner - value: 'aws_app_runner' - brief: AWS App Runner - - id: aws_openshift - value: 'aws_openshift' - brief: Red Hat OpenShift on AWS (ROSA) - - id: azure_vm - value: 'azure_vm' - brief: Azure Virtual Machines - - id: azure_container_instances - value: 'azure_container_instances' - brief: Azure Container Instances - - id: azure_aks - value: 'azure_aks' - brief: Azure Kubernetes Service - - id: azure_functions - value: 'azure_functions' - brief: Azure Functions - - id: azure_app_service - value: 'azure_app_service' - brief: Azure App Service - - id: azure_openshift - value: 'azure_openshift' - brief: Azure Red Hat OpenShift - - id: gcp_bare_metal_solution - value: 'gcp_bare_metal_solution' - brief: Google Bare Metal Solution (BMS) - - id: gcp_compute_engine - value: 'gcp_compute_engine' - brief: Google Cloud Compute Engine (GCE) - - id: gcp_cloud_run - value: 'gcp_cloud_run' - brief: Google Cloud Run - - id: gcp_kubernetes_engine - value: 'gcp_kubernetes_engine' - brief: Google Cloud Kubernetes Engine (GKE) - - id: gcp_cloud_functions - value: 'gcp_cloud_functions' - brief: Google Cloud Functions (GCF) - - id: gcp_app_engine - value: 'gcp_app_engine' - brief: Google Cloud App Engine (GAE) - - id: gcp_openshift - value: 'gcp_openshift' - brief: Red Hat OpenShift on Google Cloud - - id: ibm_cloud_openshift - value: 'ibm_cloud_openshift' - brief: Red Hat OpenShift on IBM Cloud - - id: tencent_cloud_cvm - value: 'tencent_cloud_cvm' - brief: Tencent Cloud Cloud Virtual Machine (CVM) - - id: tencent_cloud_eks - value: 'tencent_cloud_eks' - brief: Tencent Cloud Elastic Kubernetes Service (EKS) - - id: tencent_cloud_scf - value: 'tencent_cloud_scf' - brief: Tencent Cloud Serverless Cloud Function (SCF) - brief: > - The cloud platform in use. - note: > - The prefix of the service SHOULD match the one specified in `cloud.provider`. + - ref: cloud.provider + - ref: cloud.account.id + - ref: cloud.region + - ref: cloud.resource_id + - ref: cloud.availability_zone + - ref: cloud.platform From a1ec47777fd7e42fd5fbf7e9c294742857c165cd Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 08:18:33 -0700 Subject: [PATCH 126/482] Change `http.request.body.size` and `http.response.body.size` attributes from recommended to opt-in (#460) --- CHANGELOG.md | 3 +++ docs/attributes-registry/http.md | 4 ++-- docs/http/http-spans.md | 2 -- model/registry/deprecated/http.yaml | 4 ++-- model/registry/http.yaml | 2 ++ model/trace/http.yaml | 2 -- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa09e19c62..b882b80cb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,9 @@ release. ([#449](https://github.com/open-telemetry/semantic-conventions/pull/449)) - Change `user_agent.original` from recommended to opt-in on HTTP client spans. ([#468](https://github.com/open-telemetry/semantic-conventions/pull/468)) +- Change `http.request.body.size` and `http.response.body.size` + from recommended to opt-in. + ([#460](https://github.com/open-telemetry/semantic-conventions/pull/460)) ### Features diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 62955335ba..04d52c8a25 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -68,8 +68,8 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin | Attribute | Type | Description | Examples | |---|---|---|---| | `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | -| `http.request_content_length` | int | Deprecated, use `http.request.body.size` instead. | `3495` | -| `http.response_content_length` | int | Deprecated, use `http.response.body.size` instead. | `3495` | +| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | +| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | | `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | | `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | | `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 380e47f30c..65a0bcf71f 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -119,11 +119,9 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.body.size`](../attributes-registry/http.md) | 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.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [2] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | | [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | -| [`http.response.body.size`](../attributes-registry/http.md) | 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.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | diff --git a/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index f904126c67..de45180bbd 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -31,11 +31,11 @@ groups: examples: ['/search?q=OpenTelemetry#SemConv'] - id: request_content_length type: int - brief: 'Deprecated, use `http.request.body.size` instead.' + brief: 'Deprecated, use `http.request.header.content-length` instead.' stability: deprecated examples: 3495 - id: response_content_length type: int - brief: 'Deprecated, use `http.response.body.size` instead.' + brief: 'Deprecated, use `http.response.header.content-length` instead.' stability: deprecated examples: 3495 diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 4264ae3251..ec763f0eaa 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -11,6 +11,7 @@ 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 + stability: experimental # this should not be marked stable with other HTTP attributes - id: request.header type: template[string[]] brief: > @@ -97,6 +98,7 @@ 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 + stability: experimental # this should not be marked stable with other HTTP attributes - id: response.header type: template[string[]] brief: > diff --git a/model/trace/http.yaml b/model/trace/http.yaml index e811dc4296..fb8c59bae1 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -10,10 +10,8 @@ groups: - ref: http.request.method_original requirement_level: conditionally_required: If and only if it's different than `http.request.method`. - - ref: http.request.body.size - ref: http.request.header requirement_level: opt_in - - ref: http.response.body.size - ref: http.response.header requirement_level: opt_in - ref: http.request.method From de4125d0307e97474ea05d40b3c7945a027745b3 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 08:42:07 -0700 Subject: [PATCH 127/482] Clarify that `client.port` is the port of whichever client was captured in `client.address` (#471) --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 2 +- model/trace/http.yaml | 5 +---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b882b80cb7..60b5bd3232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ release. - Change `http.request.body.size` and `http.response.body.size` from recommended to opt-in. ([#460](https://github.com/open-telemetry/semantic-conventions/pull/460)) +- Clarify that `client.port` is the port of whichever client was captured in `client.address`. + ([#471](https://github.com/open-telemetry/semantic-conventions/pull/471)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 65a0bcf71f..4919481e88 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -341,7 +341,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for) or a similar header). Otherwise, the immediate client peer port. [2] | `65123` | Recommended | +| [`client.port`](../general/attributes.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Recommended | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | diff --git a/model/trace/http.yaml b/model/trace/http.yaml index fb8c59bae1..e9f3146105 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -71,10 +71,7 @@ groups: Otherwise, the immediate client peer address. examples: ['83.164.160.102'] - ref: client.port - brief: > - The port of the original client behind all proxies, if - known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for) or a similar header). - Otherwise, the immediate client peer port. + brief: The port of whichever client was captured in `client.address`. - ref: url.path requirement_level: required sampling_relevant: true From c99d35bc33cd47a6249be32378ed648108f41121 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 30 Oct 2023 23:54:37 -0700 Subject: [PATCH 128/482] Fix lint warning (#475) --- model/registry/http.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/registry/http.yaml b/model/registry/http.yaml index ec763f0eaa..57a7de3ce7 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -11,7 +11,7 @@ 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 - stability: experimental # this should not be marked stable with other HTTP attributes + stability: experimental # this should not be marked stable with other HTTP attributes - id: request.header type: template[string[]] brief: > @@ -98,7 +98,7 @@ 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 - stability: experimental # this should not be marked stable with other HTTP attributes + stability: experimental # this should not be marked stable with other HTTP attributes - id: response.header type: template[string[]] brief: > From 3b76932c6a70a0fa7323990b4758fb2634fc7700 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 31 Oct 2023 00:01:56 -0700 Subject: [PATCH 129/482] Change `client.port` from recommended to opt-in on HTTP server spans (#472) Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 2 +- model/trace/http.yaml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b5bd3232..7b25da9c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ release. ([#460](https://github.com/open-telemetry/semantic-conventions/pull/460)) - Clarify that `client.port` is the port of whichever client was captured in `client.address`. ([#471](https://github.com/open-telemetry/semantic-conventions/pull/471)) +- Change `client.port` from recommended to opt-in on HTTP server spans + ([#472](https://github.com/open-telemetry/semantic-conventions/pull/472)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 4919481e88..00721efd60 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -341,7 +341,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Recommended | +| [`client.port`](../general/attributes.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Opt-In | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | diff --git a/model/trace/http.yaml b/model/trace/http.yaml index e9f3146105..d67627ecb8 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -71,6 +71,7 @@ groups: Otherwise, the immediate client peer address. examples: ['83.164.160.102'] - ref: client.port + requirement_level: opt_in brief: The port of whichever client was captured in `client.address`. - ref: url.path requirement_level: required From a8535bdeb311d0e23687159e742dfbb8f281bdba Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 31 Oct 2023 02:59:22 -0700 Subject: [PATCH 130/482] Make url.scheme opt in for HTTP client metrics and make server.port required (#459) Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/http/http-metrics.md | 18 ++++++------------ docs/http/http-spans.md | 21 +++++++++------------ docs/rpc/rpc-spans.md | 7 +++---- model/http-common.yaml | 8 +++++--- model/metrics/http.yaml | 4 ---- model/trace/http.yaml | 1 + model/trace/rpc.yaml | 2 +- 8 files changed, 28 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b25da9c40..f06b06560f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,9 @@ release. ([#471](https://github.com/open-telemetry/semantic-conventions/pull/471)) - Change `client.port` from recommended to opt-in on HTTP server spans ([#472](https://github.com/open-telemetry/semantic-conventions/pull/472)) +- BREAKING: Make `url.scheme` opt_in for HTTP client and remove default value for + `server.port` making it required on the client. + ([#459](https://github.com/open-telemetry/semantic-conventions/pull/459)) ### Features diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 9db7178843..2f6ff557b5 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -449,8 +449,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -492,8 +492,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7]:** If not default (`80` for `http` scheme, `443` for `https`). - `error.type` 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 | @@ -539,8 +537,8 @@ This metric is optional. | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -582,8 +580,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7]:** If not default (`80` for `http` scheme, `443` for `https`). - `error.type` 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 | @@ -629,8 +625,8 @@ This metric is optional. | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -672,8 +668,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7]:** If not default (`80` for `http` scheme, `443` for `https`). - `error.type` 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 | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 00721efd60..2c43c44788 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -232,8 +232,9 @@ For an HTTP client span, `SpanKind` MUST be `Client`. |---|---|---|---|---| | [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | | [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.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] | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`server.port`](../general/attributes.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` | Required | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Opt-In | **[1]:** 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). @@ -242,9 +243,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. **[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[4]:** If not default (`80` for `http` scheme, `443` for `https`). - -**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +**[4]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. @@ -346,10 +345,10 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | | [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: [6] | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [7] | `http`; `https` | Required | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. @@ -363,11 +362,9 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[6]:** If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). - -**[7]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[6]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[7]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 3d9e12185c..e65c6844ed 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -91,7 +91,7 @@ Examples of span names: | [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | | [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: See below | +| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | **[1]:** The value SHOULD be normalized to lowercase. @@ -109,6 +109,8 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** if the port is supported by the network transport used for communication. + `network.transport` 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 | @@ -136,9 +138,6 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `connect_rpc` | Connect RPC | -For client-side spans `server.port` is required if the connection is IP-based and the port is available (it describes the server port they are connecting to). -For server-side spans `client.socket.port` is optional (it describes the port the client is connecting from). - #### Service name On the server process receiving and handling the remote procedure call, the service name provided in `rpc.service` does not necessarily have to match the [`service.name`][] resource attribute. diff --git a/model/http-common.yaml b/model/http-common.yaml index a3b8970db0..748b39c60d 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -48,10 +48,12 @@ groups: If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - ref: server.port - requirement_level: - conditionally_required: If not default (`80` for `http` scheme, `443` for `https`). + requirement_level: required brief: > Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + - ref: url.scheme + requirement_level: opt_in + examples: ["http", "https"] - id: attributes.http.server type: attribute_group @@ -72,7 +74,7 @@ groups: note: > See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). requirement_level: - conditionally_required: If `server.address` is set and the port is not default (`80` for `http` scheme, `443` for `https`). + conditionally_required: If `server.address` is set. - ref: url.scheme requirement_level: required examples: ["http", "https"] diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 233ca32993..9e12896e88 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -22,10 +22,6 @@ groups: type: attribute_group brief: 'HTTP client attributes' extends: attributes.http.client - attributes: - - ref: url.scheme - requirement_level: required - examples: ["http", "https"] - id: metric.http.server.request.duration type: metric diff --git a/model/trace/http.yaml b/model/trace/http.yaml index d67627ecb8..e3da9342b6 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -45,6 +45,7 @@ groups: requirement_level: required - ref: user_agent.original requirement_level: opt_in + - ref: url.scheme - id: trace.http.server type: span diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 02a64dbce4..de36d6767a 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -21,7 +21,7 @@ groups: `server.address` to the IP address provided in the host component. - ref: server.port requirement_level: - conditionally_required: See below + conditionally_required: if the port is supported by the network transport used for communication. - id: rpc.client type: span From 8ff4ea682198b41dad89c0484fee57c78777496f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 31 Oct 2023 03:08:23 -0700 Subject: [PATCH 131/482] Make `client.address` sampling relevant on HTTP server spans (#469) Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 1 + model/trace/http.yaml | 1 + 3 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f06b06560f..50adef6b59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ release. - BREAKING: Make `url.scheme` opt_in for HTTP client and remove default value for `server.port` making it required on the client. ([#459](https://github.com/open-telemetry/semantic-conventions/pull/459)) +- Make `client.address` sampling relevant on HTTP server spans. + ([#469](https://github.com/open-telemetry/semantic-conventions/pull/469)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 2c43c44788..6e2ba2f685 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -368,6 +368,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: +* [`client.address`](../general/attributes.md) * [`server.address`](../general/attributes.md) * [`server.port`](../general/attributes.md) * [`url.path`](../attributes-registry/url.md) diff --git a/model/trace/http.yaml b/model/trace/http.yaml index e3da9342b6..7162eebf0e 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -65,6 +65,7 @@ groups: requirement_level: opt_in brief: Local socket port. Useful in case of a multi-port host. - ref: client.address + sampling_relevant: true note: > The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), From 514d737d85b0a11524633b51b84a1363d71988d7 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 31 Oct 2023 15:10:11 +0100 Subject: [PATCH 132/482] Update messaging "Receive", "Deliver", and "Create" operations according to OTEP 220 (#284) Co-authored-by: Liudmila Molkova Co-authored-by: Joao Grassi --- docs/messaging/messaging-spans.md | 225 ++++++++++++++++++------------ 1 file changed, 134 insertions(+), 91 deletions(-) diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 009b5ff501..6ff2bc03a3 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -18,8 +18,11 @@ - [Conventions](#conventions) * [Context propagation](#context-propagation) * [Span name](#span-name) - * [Span kind](#span-kind) * [Operation names](#operation-names) + * [Span kind](#span-kind) + * [Trace structure](#trace-structure) + + [Producer spans](#producer-spans) + + [Consumer spans](#consumer-spans) - [Messaging attributes](#messaging-attributes) * [Attribute namespaces](#attribute-namespaces) * [Consumer attributes](#consumer-attributes) @@ -28,7 +31,6 @@ - [Examples](#examples) * [Topic with multiple consumers](#topic-with-multiple-consumers) * [Batch receiving](#batch-receiving) - * [Batch processing](#batch-processing) - [Semantic Conventions for specific messaging technologies](#semantic-conventions-for-specific-messaging-technologies) @@ -196,21 +198,78 @@ Examples: * `AuthenticationRequest-Conversations process` * `(anonymous) publish` (`(anonymous)` being a stable identifier for an unnamed destination) -### Span kind - -A producer of a message should set the span kind to `PRODUCER` unless it synchronously waits for a response: then it should use `CLIENT`. -The processor of the message should set the kind to `CONSUMER`, unless it always sends back a reply that is directed to the producer of the message -(as opposed to e.g., a queue on which the producer happens to listen): then it should use `SERVER`. - ### Operation names The following operations related to messages are defined for these semantic conventions: | Operation name | Description | | -------------- | ----------- | -| `publish` | A message is sent to a destination by a message producer/client. | -| `receive` | A message is received from a destination by a message consumer/server. | -| `process` | A message that was previously received from a destination is processed by a message consumer/server. | +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | +| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | + +### Span kind + +[Span kinds](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind) +SHOULD be set according to the following table, based on the operation a span describes. + +| Operation name | Span kind| +|----------------|-------------| +| `publish` | `PRODUCER` if the context of the "Publish" span is used as creation context. | +| `create` | `PRODUCER` | +| `receive` | `CONSUMER` | +| `deliver` | `CONSUMER` | + +For cases not covered by the table above, the span kind should be set according +to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind), +e. g. it should be set to CLIENT for the "Publish" span if its context is not +used as creation context and if the "Publish" span models a synchronous call to +the intermediary. + +Setting span kinds according to this table ensures that span links between +consumers and producers always exist between a PRODUCER span on the producer +side and a CONSUMER span on the consumer side. This allows analysis tools to +interpret linked traces without the need for additional semantic hints. + +### Trace structure + +#### Producer spans + +"Publish" spans SHOULD be created for operations of providing messages for +sending or publishing to an intermediary. A single "Publish" span can account +for a single message, or for multiple messages (in the case of providing +messages in batches). "Create" spans MAY be created. A single "Create" span +SHOULD account only for a single message. "Create" spans SHOULD either be +children or links of the related "Publish" span. + +If a user provides a custom creation context in a message, this context SHOULD +NOT be modified, a "Create" span SHOULD NOT be created, and the "Publish" span +SHOULD link to the custom creation context. Otherwise, if a "Create" span +exists for a message, its context SHOULD be injected into the message. If no +"Create" span exists and no custom creation context is injected into the +message, the context of the related "Publish" span SHOULD be injected into the +message. + +#### Consumer spans + +"Deliver" spans SHOULD be created for operations of passing messages to the +application when those operations are not initiated by the application code +(push-based scenarios). A "Deliver" span covers the duration of such an +operation, which is usually a callback or handler. + +"Receive" spans SHOULD be created for operations of passing messages to the +application when those operations are initiated by the application code +(pull-based scenarios). + +"Deliver" or "Receive" spans MUST NOT be created for messages that are +pre-fetched or cached by messaging libraries or SDKs until they are forwarded +to the caller. + +A single "Deliver" or "Receive" span can account for a single message, for a +batch of messages, or for no message at all (if it is signalled that no +messages were received). For each message it accounts for, the "Deliver" or +"Receive" span SHOULD link to the message's creation context. ## Messaging attributes @@ -335,19 +394,12 @@ under the namespace `messaging.destination_publish.*` the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. -The *receive* span is used to track the time used for receiving the message(s), whereas the *process* span(s) track the time for processing the message(s). -Note that one or multiple Spans with `messaging.operation` = `process` may often be the children of a Span with `messaging.operation` = `receive`. -The distinction between receiving and processing of messages is not always of particular interest or sometimes hidden away in a framework (see the [Message consumption](#message-consumption) section above) and therefore the attribute can be left out. -For batch receiving and processing (see the [Batch receiving](#batch-receiving) and [Batch processing](#batch-processing) examples below) in particular, the attribute SHOULD be set. -Even though in that case one might think that the processing span's kind should be `INTERNAL`, that kind MUST NOT be used. -Instead span kind should be set to either `CONSUMER` or `SERVER` according to the rules defined above. - ### Per-message attributes All messaging operations (`publish`, `receive`, `process`, or others not covered by this specification) can describe both single and/or batch of messages. Attributes in the `messaging.message` or `messaging.{system}.message` namespace describe individual messages. For single-message operations they SHOULD be set on corresponding span. -For batch operations, per-message attributes are usually different and cannot be set on the corresponding span. In such cases the attributes MAY be set on links. See [Batch Receiving](#batch-receiving) and [Batch Processing](#batch-processing) for more information on correlation using links. +For batch operations, per-message attributes are usually different and cannot be set on the corresponding span. In such cases the attributes SHOULD be set on links. See [Batch receiving](#batch-receiving) for more information on correlation using links. Some messaging systems (e.g., Kafka, Azure EventGrid) allow publishing a single batch of messages to different topics. In such cases, the attributes in `messaging.destination` MAY be set on links. Instrumentations MAY set destination attributes on the span if all messages in the batch share the same destination. @@ -365,92 +417,83 @@ All attributes that are specific for a messaging system SHOULD be populated in ` ### Topic with multiple consumers -Given is a process P, that publishes a message to a topic T on messaging system MS, and two processes CA and CB, which both receive the message and process it. - -``` -Process P: | Span Prod1 | --- -Process CA: | Span CA1 | --- -Process CB: | Span CB1 | +Given is a publisher that publishes a message to a topic exchange "T" on RabbitMQ, and two consumers which both get the message delivered. + +```mermaid +flowchart LR; + subgraph PRODUCER + direction TB + P[Span Publish A] + end + subgraph CONSUMER1 + direction TB + R1[Span Deliver A 1] + end + subgraph CONSUMER2 + direction TB + R2[Span Deliver A 2] + end + P-. link .-R1; + P-. link .-R2; + + classDef normal fill:green + class P,R1,R2 normal + linkStyle 0,1 color:green,stroke:green ``` -| Field or Attribute | Span Prod1 | Span CA1 | Span CB1 | +| Field or Attribute | Span Publish A | Span Deliver A 1| Span Deliver A 2 | |-|-|-|-| -| Span name | `"T publish"` | `"T process"` | `"T process"` | -| Parent | | Span Prod1 | Span Prod1 | -| Links | | | | +| Span name | `T publish` | `T deliver` | `T deliver` | +| Parent | | | | +| Links | | `T publish` | `T publish` | | SpanKind | `PRODUCER` | `CONSUMER` | `CONSUMER` | | Status | `Ok` | `Ok` | `Ok` | | `server.address` | `"ms"` | `"ms"` | `"ms"` | | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | | `messaging.destination.name` | `"T"` | `"T"` | `"T"` | -| `messaging.operation` | | `"process"` | `"process"` | -| `messaging.message.id` | `"a1"` | `"a1"`| `"a1"` | +| `messaging.operation` | `"publish"` | `"deliver"` | `"deliver"` | +| `messaging.message.id` | `"a"` | `"a"`| `"a"` | ### Batch receiving -Given is a process P, that publishes two messages to a queue Q on messaging system MS, and a process C, which receives both of them in one batch (Span Recv1) and processes each message separately (Spans Proc1 and Proc2). - -Since a span can only have one parent and the propagated trace and span IDs are not known when the receiving span is started, the receiving span will have no parent and the processing spans are correlated with the producing spans using links. - +Given is a publisher that publishes two messages to a topic "Q" on Kafka, and a consumer which receives both messages in one batch. + +```mermaid +flowchart LR; + subgraph PRODUCER + direction TB + PA[Span Publish A] + PB[Span Publish B] + end + subgraph CONSUMER1 + direction TB + D1[Span Receive A B] + end + PA-. link .-D1; + PB-. link .-D1; + + classDef normal fill:green + class PA,PB,D1 normal + linkStyle 0,1 color:green,stroke:green ``` -Process P: | Span Prod1 | Span Prod2 | --- -Process C: | Span Recv1 | - | Span Proc1 | - | Span Proc2 | -``` - -| Field or Attribute | Span Prod1 | Span Prod2 | Span Recv1 | Span Proc1 | Span Proc2 | -|-|-|-|-|-|-| -| Span name | `"Q publish"` | `"Q publish"` | `"Q receive"` | `"Q process"` | `"Q process"` | -| Parent | | | | Span Recv1 | Span Recv1 | -| Links | | | | Span Prod1 | Span Prod2 | -| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | `CONSUMER` | `CONSUMER` | -| Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` | -| `server.address` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | -| `server.port` | `1234` | `1234` | `1234` | `1234` | `1234` | -| `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | -| `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | -| `messaging.operation` | | | `"receive"` | `"process"` | `"process"` | -| `messaging.message.id` | `"a1"` | `"a2"` | | `"a1"` | `"a2"` | -| `messaging.batch.message_count` | | | 2 | | | - -### Batch processing - -Given is a process P, that publishes two messages to a queue Q on messaging system MS, and a process C, which receives them separately in two different operations (Span Recv1 and Recv2) and processes both messages in one batch (Span Proc1). -Since each span can only have one parent, C3 should not choose a random parent out of C1 and C2, but rather rely on the implicitly selected parent as defined by the [tracing API spec](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md). -Depending on the implementation, the producing spans might still be available in the meta data of the messages and should be added to C3 as links. -The client library or application could also add the receiver span's SpanContext to the data structure it returns for each message. In this case, C3 could also add links to the receiver spans C1 and C2. - -The status of the batch processing span is selected by the application. Depending on the semantics of the operation. A span status `Ok` could, for example, be set only if all messages or if just at least one were properly processed. - -``` -Process P: | Span Prod1 | Span Prod2 | --- -Process C: | Span Recv1 | Span Recv2 | - | Span Proc1 | -``` - -| Field or Attribute | Span Prod1 | Span Prod2 | Span Recv1 | Span Recv2 | Span Proc1 | -|-|-|-|-|-|-| -| Span name | `"Q publish"` | `"Q publish"` | `"Q receive"` | `"Q receive"` | `"Q process"` | -| Parent | | | Span Prod1 | Span Prod2 | | -| Links | | | | | [Span Prod1, Span Prod2 ] | -| Link attributes | | | | | Span Prod1: `messaging.message.id`: `"a1"` | -| | | | | | Span Prod2: `messaging.message.id`: `"a2"` | -| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | `CONSUMER` | `CONSUMER` | -| Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` | -| `server.address` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | -| `server.port` | `1234` | `1234` | `1234` | `1234` | `1234` | -| `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | -| `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | -| `messaging.operation` | | | `"receive"` | `"receive"` | `"process"` | -| `messaging.message.id` | `"a1"` | `"a2"` | `"a1"` | `"a2"` | | -| `messaging.batch.message_count` | | | 1 | 1 | 2 | +| Field or Attribute | Span Publish A | Span Publish B | Span Receive A B | +|-|-|-|-| +| Span name | `Q publish` | `Q publish` | `Q receive` | +| Parent | | | | +| Links | | | Span Publish A, Span Publish B | +| Link attributes | | | Span Publish A: `messaging.message.id`: `"a1"` | +| | | | Span Publish B: `messaging.message.id`: `"a2"` | +| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | +| Status | `Ok` | `Ok` | `Ok` | +| `server.address` | `"ms"` | `"ms"` | `"ms"` | +| `server.port` | `1234` | `1234` | `1234` | +| `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | +| `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | +| `messaging.operation` | `"publish"` | `"publish"` | `"receive"` | +| `messaging.message.id` | `"a1"` | `"a2"` | | +| `messaging.batch.message_count` | | | 2 | ## Semantic Conventions for specific messaging technologies From 69d6d4fd67a4b9d87625d71fa907bdf4cbc01f68 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 1 Nov 2023 01:04:51 -0700 Subject: [PATCH 133/482] Change `network.protocol.name` from opt-in to conditionally required (#478) --- CHANGELOG.md | 2 + docs/http/http-metrics.md | 108 +++++++++++++++++++++----------------- docs/http/http-spans.md | 12 +++-- model/http-common.yaml | 3 +- 4 files changed, 71 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50adef6b59..5165944564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,8 @@ release. ([#459](https://github.com/open-telemetry/semantic-conventions/pull/459)) - Make `client.address` sampling relevant on HTTP server spans. ([#469](https://github.com/open-telemetry/semantic-conventions/pull/469)) +- Change `network.protocol.name` from opt-in to conditionally required. + ([#478](https://github.com/open-telemetry/semantic-conventions/pull/478)) ### Features diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 2f6ff557b5..d9ee1cc417 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -80,11 +80,11 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -123,19 +123,21 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If not `http` and `network.protocol.version` is set. + +**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -241,11 +243,11 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -284,19 +286,21 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If not `http` and `network.protocol.version` is set. + +**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -341,11 +345,11 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [7] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -384,19 +388,21 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[4]:** The value SHOULD be normalized to lowercase. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If not `http` and `network.protocol.version` is set. -**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. `error.type` 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. @@ -446,10 +452,10 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -486,11 +492,13 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** If not `http` and `network.protocol.version` is set. + +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. @@ -534,10 +542,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -574,11 +582,13 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** If not `http` and `network.protocol.version` is set. + +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. @@ -622,10 +632,10 @@ This metric is optional. | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [4] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `80`; `8080`; `443` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -662,11 +672,13 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[3]:** The value SHOULD be normalized to lowercase. -**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[4]:** If not `http` and `network.protocol.version` is set. + +**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[5]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 6e2ba2f685..0984ab3980 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -126,9 +126,9 @@ sections below. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Opt-In | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Conditionally Required: [7] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [8] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -174,9 +174,11 @@ The attribute value MUST consist of either multiple header values as an array of **[6]:** The value SHOULD be normalized to lowercase. -**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[7]:** If not `http` and `network.protocol.version` is set. -**[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. +**[8]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[9]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: diff --git a/model/http-common.yaml b/model/http-common.yaml index 748b39c60d..2187943dda 100644 --- a/model/http-common.yaml +++ b/model/http-common.yaml @@ -31,7 +31,8 @@ groups: If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - ref: network.protocol.name examples: ['http', 'spdy'] - requirement_level: opt_in + requirement_level: + conditionally_required: If not `http` and `network.protocol.version` is set. - ref: network.protocol.version examples: ['1.0', '1.1', '2', '3'] From 1eb70c4d74aa904a8c81c5ed10302af8bb3c1b70 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 1 Nov 2023 01:09:56 -0700 Subject: [PATCH 134/482] Remove outdated `http.request.header.host` guidance (#479) Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/http/http-spans.md | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5165944564..7ed68fab38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ release. ([#469](https://github.com/open-telemetry/semantic-conventions/pull/469)) - Change `network.protocol.name` from opt-in to conditionally required. ([#478](https://github.com/open-telemetry/semantic-conventions/pull/478)) +- Remove outdated `http.request.header.host` guidance + ([#479](https://github.com/open-telemetry/semantic-conventions/pull/479)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 0984ab3980..d3f9156c8a 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -256,8 +256,6 @@ Following attributes MUST be provided **at span creation time** (when provided a * [`url.full`](../attributes-registry/url.md) -Note that in some cases host and port identifiers in the `Host` header might be different from the `server.address` and `server.port`, in this case instrumentation MAY populate `Host` header on `http.request.header.host` attribute even if it's not enabled by user. - ### HTTP client span duration There are some minimal constraints that SHOULD be honored: @@ -380,8 +378,6 @@ Following attributes MUST be provided **at span creation time** (when provided a `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. -Note that in some cases host and port identifiers in the `Host` header might be different from the `server.address` and `server.port`, in this case instrumentation MAY populate `Host` header on `http.request.header.host` attribute even if it's not enabled by user. - ## Examples ### HTTP client-server example From 08c1d9f3408f180d07d3ad680e239361e228f9c0 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 2 Nov 2023 08:41:11 -0700 Subject: [PATCH 135/482] Change sampling relevant from MUST to SHOULD (and update build-tools version) (#486) --- CHANGELOG.md | 2 ++ Makefile | 2 +- docs/http/http-spans.md | 6 +++--- internal/tools/schema_check.sh | 2 +- model/README.md | 6 +++--- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ed68fab38..e8932ee330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ release. ([#478](https://github.com/open-telemetry/semantic-conventions/pull/478)) - Remove outdated `http.request.header.host` guidance ([#479](https://github.com/open-telemetry/semantic-conventions/pull/479)) +- Change sampling relevant from `MUST` to `SHOULD` + ([#486](https://github.com/open-telemetry/semantic-conventions/pull/486)) ### Features diff --git a/Makefile b/Makefile index c6d956424b..ca93385774 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! -SEMCONVGEN_VERSION=0.22.0 +SEMCONVGEN_VERSION=0.23.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index d3f9156c8a..42ccfb7375 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -180,7 +180,7 @@ The attribute value MUST consist of either multiple header values as an array of **[9]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. -Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: +The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`http.request.method`](../attributes-registry/http.md) @@ -249,7 +249,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. -Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: +The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`server.address`](../general/attributes.md) * [`server.port`](../general/attributes.md) @@ -366,7 +366,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[7]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. -Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions: +The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`client.address`](../general/attributes.md) * [`server.address`](../general/attributes.md) diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index 32c489d1a7..801fcee04f 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -6,7 +6,7 @@ set -e -BUILD_TOOL_SCHEMAS_VERSION=0.22.0 +BUILD_TOOL_SCHEMAS_VERSION=0.23.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") diff --git a/model/README.md b/model/README.md index 33f3cd3379..482c59ab14 100644 --- a/model/README.md +++ b/model/README.md @@ -14,12 +14,12 @@ Semantic conventions for the spec MUST adhere to the [attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-requirement-level.md), and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md) conventions. -Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions/syntax.md) +Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. A schema file for VS code is configured in the `/.vscode/settings.json` of this repository, enabling auto-completion and additional checks. Refer to -[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions/README.md) for what extension you need. +[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/README.md) for what extension you need. ## Generating markdown @@ -30,7 +30,7 @@ formatted Markdown tables for all semantic conventions in the specification. Run make table-generation ``` -For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.22.0/semantic-conventions) +For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions) in the OpenTelemetry build tools repository. Using this build tool, it is also possible to generate code for use in OpenTelemetry language projects. From c34ca409adc676ec0c122c094251acc193e4df4f Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Thu, 2 Nov 2023 17:05:54 +0100 Subject: [PATCH 136/482] [resource/host] Define host.mac semantic convention (#340) Co-authored-by: Alexander Wert Co-authored-by: Josh Suereth --- CHANGELOG.md | 2 ++ docs/resource/host.md | 3 +++ model/resource/host.yaml | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8932ee330..afcc9d481f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,8 @@ release. ([#267](https://github.com/open-telemetry/opentelemetry-specification/pull/267)) - Add opt-in `system.memory.limit` metric. ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) +- Add `host.mac` resource attribute convention. + ([#340](https://github.com/open-telemetry/semantic-conventions/pull/340)) ### Fixes diff --git a/docs/resource/host.md b/docs/resource/host.md index d074a30f6c..f7e2286af5 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -18,11 +18,14 @@ To report host metrics, the `system.*` namespace SHOULD be used. | `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | | `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). | `0.1` | Recommended | | `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | Opt-In | +| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | Opt-In | | `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | | `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | **[1]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. +**[2]:** MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + `host.arch` 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 | diff --git a/model/resource/host.yaml b/model/resource/host.yaml index 141ccd76bf..9b63976db5 100644 --- a/model/resource/host.yaml +++ b/model/resource/host.yaml @@ -79,6 +79,15 @@ groups: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. examples: ["192.168.1.140", "fe80::abc2:4a28:737a:609e"] + - id: mac + type: string[] + requirement_level: opt_in + brief: > + Available MAC addresses of the host, excluding loopback interfaces. + note: > + MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): + as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + examples: ['AC-DE-48-23-45-67', 'AC-DE-48-23-45-67-01-9F'] - id: host.cpu prefix: host.cpu From d6a478d8dcb073f5ec6fa014aa8e628800490894 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 2 Nov 2023 17:18:27 +0100 Subject: [PATCH 137/482] Moved `messaging.*` attributes to the registry (#444) Signed-off-by: Alexander Wert --- docs/attributes-registry/messaging.md | 85 +++++++++ docs/messaging/kafka.md | 12 +- docs/messaging/messaging-spans.md | 53 ++++-- docs/messaging/rabbitmq.md | 4 +- docs/messaging/rocketmq.md | 20 +-- model/registry/messaging.yaml | 208 ++++++++++++++++++++++ model/trace/messaging.yaml | 239 +++++--------------------- 7 files changed, 390 insertions(+), 231 deletions(-) create mode 100644 docs/attributes-registry/messaging.md create mode 100644 model/registry/messaging.yaml diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md new file mode 100644 index 0000000000..98dbb97aad --- /dev/null +++ b/docs/attributes-registry/messaging.md @@ -0,0 +1,85 @@ + + +# Messaging + +## Messaging Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | +| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | +| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | +| `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | +| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | +| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | +| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | +| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | +| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | +| `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [5] | `myKey` | +| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | +| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | +| `messaging.message.body.size` | int | The size of the message body in bytes. [6] | `1439` | +| `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [7] | `2738` | +| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | +| `messaging.operation` | string | A string identifying the kind of messaging operation. [8] | `publish` | +| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | +| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | +| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | +| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | +| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | +| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | +| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | +| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | +| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | +| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | +| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | + +**[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + +**[2]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + +**[3]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + +**[4]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If +the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. + +**[5]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. + +**[6]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[7]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +size should be used. + +**[8]:** If a custom value is used, it MUST be of low cardinality. + +`messaging.operation` 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 | +|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | +| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | + +`messaging.rocketmq.consumption_model` MUST be one of the following: + +| Value | Description | +|---|---| +| `clustering` | Clustering consumption model | +| `broadcasting` | Broadcasting consumption model | + +`messaging.rocketmq.message.type` MUST be one of the following: + +| Value | Description | +|---|---| +| `normal` | Normal message | +| `fifo` | FIFO message | +| `delay` | Delay message | +| `transaction` | Transaction message | + diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 9bfb1c2332..4bd6c4da57 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -24,14 +24,14 @@ described on this page. For Apache Kafka, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | Recommended | -| `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | Recommended | -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | -| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | Recommended | -| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | Conditionally Required: [2] | +| [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | Recommended | +| [`messaging.kafka.destination.partition`](../attributes-registry/messaging.md) | int | Partition the message is sent to. | `2` | Recommended | +| [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | +| [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | Recommended | +| [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | Conditionally Required: [2] | **[1]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 6ff2bc03a3..ec9c82526b 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -273,21 +273,21 @@ messages were received). For each message it accounts for, the "Deliver" or ## Messaging attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | Conditionally Required: [2] | -| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | -| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [3] | -| `messaging.destination.name` | string | The message destination name [4] | `MyQueue`; `MyTopic` | Conditionally Required: [5] | -| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [6] | `/customers/{customerId}` | Conditionally Required: [7] | -| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [8] | -| `messaging.message.body.size` | int | The size of the message body in bytes. [9] | `1439` | Recommended: [10] | -| `messaging.message.conversation_id` | string | The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [11] | -| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | -| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | -| `messaging.operation` | string | A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. [15] | `publish` | Required | -| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | +| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | Conditionally Required: [2] | +| [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | +| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [3] | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [4] | `MyQueue`; `MyTopic` | Conditionally Required: [5] | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [6] | `/customers/{customerId}` | Conditionally Required: [7] | +| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [8] | +| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [9] | `1439` | Recommended: [10] | +| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [11] | +| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | +| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | +| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [15] | `publish` | Required | +| [`messaging.system`](../attributes-registry/messaging.md) | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | @@ -347,9 +347,26 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Value | Description | |---|---| -| `publish` | publish | -| `receive` | receive | -| `process` | process | +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | +| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | Additionally `server.port` from the [network attributes][] is recommended. @@ -387,8 +404,8 @@ under the namespace `messaging.destination_publish.*` | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | Recommended | -| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | +| [`messaging.destination_publish.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | Recommended | +| [`messaging.destination_publish.name`](../attributes-registry/messaging.md) | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | **[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 61f37c15d5..1c762c4386 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -17,10 +17,10 @@ described on this page. In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. `messaging.destination.name` MUST be set to the name of the exchange. This will be an empty string if the default exchange is used. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | +| [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index fe6a7d3401..8f4bbca5fb 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -16,18 +16,18 @@ described on this page. Specific attributes for Apache RocketMQ are defined below. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | Required | -| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | Recommended | -| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | Conditionally Required: [1] | -| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | Conditionally Required: [2] | -| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | Conditionally Required: If the message type is FIFO. | -| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | Recommended | -| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | Recommended | -| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | Recommended | -| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | Required | +| [`messaging.rocketmq.client_group`](../attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | Required | +| [`messaging.rocketmq.consumption_model`](../attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering` | Recommended | +| [`messaging.rocketmq.message.delay_time_level`](../attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | Conditionally Required: [1] | +| [`messaging.rocketmq.message.delivery_timestamp`](../attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | Conditionally Required: [2] | +| [`messaging.rocketmq.message.group`](../attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | Conditionally Required: If the message type is FIFO. | +| [`messaging.rocketmq.message.keys`](../attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | Recommended | +| [`messaging.rocketmq.message.tag`](../attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | Recommended | +| [`messaging.rocketmq.message.type`](../attributes-registry/messaging.md) | string | Type of message. | `normal` | Recommended | +| [`messaging.rocketmq.namespace`](../attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | Required | **[1]:** If the message type is delay and delivery timestamp is not specified. diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml new file mode 100644 index 0000000000..4487cd14ca --- /dev/null +++ b/model/registry/messaging.yaml @@ -0,0 +1,208 @@ +groups: + - id: registry.messaging + prefix: messaging + type: attribute_group + brief: 'Attributes describing telemetry around messaging systems and messaging activities.' + attributes: + - id: batch.message_count + type: int + brief: The number of messages sent, received, or processed in the scope of the batching operation. + note: > + Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. + When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD + use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + examples: [0, 1, 2] + - id: client_id + type: string + brief: > + A unique identifier for the client that consumes or produces a message. + examples: ['client-5', 'myhost@8742@s8083jm'] + - id: destination.name + type: string + brief: 'The message destination name' + note: | + Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If + the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + examples: ['MyQueue', 'MyTopic'] + - id: destination.template + type: string + brief: Low cardinality representation of the messaging destination name + note: > + Destination names could be constructed from templates. + An example would be a destination name involving a user name or product id. + Although the destination name in this case is of high cardinality, + the underlying template is of low cardinality and can be effectively + used for grouping and aggregation. + examples: ['/customers/{customerId}'] + - id: destination.anonymous + type: boolean + brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' + - id: destination.temporary + type: boolean + brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' + - id: destination_publish.anonymous + type: boolean + brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' + - id: destination_publish.name + type: string + brief: 'The name of the original destination the message was published to' + note: | + The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If + the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. + examples: ['MyQueue', 'MyTopic'] + - id: kafka.consumer.group + type: string + brief: > + Name of the Kafka Consumer Group that is handling the message. + Only applies to consumers, not producers. + examples: 'my-group' + - id: kafka.destination.partition + type: int + brief: > + Partition the message is sent to. + examples: 2 + - id: kafka.message.key + type: string + brief: > + Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. + They differ from `messaging.message.id` in that they're not unique. + If the key is `null`, the attribute MUST NOT be set. + note: > + If the key type is not string, it's string representation has to be supplied for the attribute. + If the key has no unambiguous, canonical string form, don't include its value. + examples: 'myKey' + - id: kafka.message.offset + type: int + brief: > + The offset of a record in the corresponding Kafka partition. + examples: 42 + - id: kafka.message.tombstone + type: boolean + brief: 'A boolean that is true if the message is a tombstone.' + - id: message.conversation_id + type: string + brief: > + The conversation ID identifying the conversation to which the message belongs, + represented as a string. Sometimes called "Correlation ID". + examples: 'MyConversationId' + - id: message.envelope.size + type: int + brief: > + The size of the message body and metadata in bytes. + note: | + This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed + size should be used. + examples: 2738 + - id: message.id + type: string + brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' + examples: '452a7c7c7c7048c2f887f61572b18fc2' + - id: message.body.size + type: int + brief: > + The size of the message body in bytes. + note: | + This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed + body size should be used. + examples: 1439 + - id: operation + type: + allow_custom_values: true + members: + - id: publish + value: "publish" + brief: > + One or more messages are provided for publishing to an intermediary. + If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. + - id: create + value: "create" + brief: > + A message is created. + "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. + - id: receive + value: "receive" + brief: > + One or more messages are requested by a consumer. + This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. + - id: deliver + value: "deliver" + brief: > + One or more messages are passed to a consumer. + This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. + brief: > + A string identifying the kind of messaging operation. + note: If a custom value is used, it MUST be of low cardinality. + - id: rabbitmq.destination.routing_key + type: string + brief: > + RabbitMQ message routing key. + examples: 'myKey' + - id: rocketmq.client_group + type: string + brief: > + Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. + examples: 'myConsumerGroup' + - id: rocketmq.consumption_model + type: + allow_custom_values: false + members: + - id: clustering + value: 'clustering' + brief: 'Clustering consumption model' + - id: broadcasting + value: 'broadcasting' + brief: 'Broadcasting consumption model' + brief: > + Model of message consumption. This only applies to consumer spans. + - id: rocketmq.message.delay_time_level + type: int + brief: > + The delay time level for delay message, which determines the message delay time. + examples: 3 + - id: rocketmq.message.delivery_timestamp + type: int + brief: > + The timestamp in milliseconds that the delay message is expected to be delivered to consumer. + examples: 1665987217045 + - id: rocketmq.message.group + type: string + brief: > + It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. + examples: 'myMessageGroup' + - id: rocketmq.message.keys + type: string[] + brief: > + Key(s) of message, another way to mark message besides message id. + examples: ['keyA', 'keyB'] + - id: rocketmq.message.tag + type: string + brief: > + The secondary classifier of message besides topic. + examples: tagA + - id: rocketmq.message.type + type: + allow_custom_values: false + members: + - id: normal + value: 'normal' + brief: "Normal message" + - id: fifo + value: 'fifo' + brief: 'FIFO message' + - id: delay + value: 'delay' + brief: 'Delay message' + - id: transaction + value: 'transaction' + brief: 'Transaction message' + brief: > + Type of message. + - id: rocketmq.namespace + type: string + brief: > + Namespace of RocketMQ resources, resources in different namespaces are individual. + examples: 'myNamespace' + - id: system + type: string + brief: 'A string identifying the messaging system.' + examples: ['kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'] diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index ccad5e1289..c14b92dfa7 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -1,39 +1,15 @@ groups: - id: messaging.message - prefix: messaging type: attribute_group brief: 'Semantic convention describing per-message attributes populated on messaging spans or links.' attributes: - ref: messaging.destination.name - - id: message.id - type: string - brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' - examples: '452a7c7c7c7048c2f887f61572b18fc2' - - id: message.conversation_id - type: string - brief: > - The [conversation ID](#conversations) identifying the conversation to which the message belongs, - represented as a string. Sometimes called "Correlation ID". - examples: 'MyConversationId' - - id: message.envelope.size - type: int - brief: > - The size of the message body and metadata in bytes. - note: | - This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed - size should be used. - examples: 2738 - - id: message.body.size - type: int - brief: > - The size of the message body in bytes. - note: | - This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed - body size should be used. - examples: 1439 + - ref: messaging.message.id + - ref: messaging.message.conversation_id + - ref: messaging.message.envelope.size + - ref: messaging.message.body.size - id: messaging.destination - prefix: messaging.destination type: attribute_group brief: 'Semantic convention for attributes that describe messaging destination on broker' note: | @@ -46,29 +22,10 @@ groups: applies to all messages in the batch. In other cases, destination attributes may be set on links. attributes: - - id: name - type: string - brief: 'The message destination name' - note: | - Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If - the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. - examples: ['MyQueue', 'MyTopic'] - - id: template - type: string - brief: Low cardinality representation of the messaging destination name - note: > - Destination names could be constructed from templates. - An example would be a destination name involving a user name or product id. - Although the destination name in this case is of high cardinality, - the underlying template is of low cardinality and can be effectively - used for grouping and aggregation. - examples: ['/customers/{customerId}'] - - id: temporary - type: boolean - brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' - - id: anonymous - type: boolean - brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' + - ref: messaging.destination.name + - ref: messaging.destination.template + - ref: messaging.destination.temporary + - ref: messaging.destination.anonymous - id: messaging.destination_publish prefix: messaging.destination_publish @@ -87,61 +44,25 @@ groups: applies to all messages in the batch. In other cases, destination attributes may be set on links. attributes: - - id: name - type: string - brief: 'The name of the original destination the message was published to' - note: | - The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If - the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. - examples: ['MyQueue', 'MyTopic'] - - id: anonymous - type: boolean - brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' + - ref: messaging.destination_publish.name + - ref: messaging.destination_publish.anonymous - id: messaging - prefix: messaging type: span brief: > This document defines general attributes used in messaging systems. attributes: - - id: system - type: string + - ref: messaging.system requirement_level: required - brief: 'A string identifying the messaging system.' - examples: ['kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'] - - id: operation - type: - allow_custom_values: true - members: - - id: publish - value: "publish" - - id: receive - value: "receive" - - id: process - value: "process" + - ref: messaging.operation requirement_level: required - brief: > - A string identifying the kind of messaging operation as defined in the - [Operation names](#operation-names) section above. - note: If a custom value is used, it MUST be of low cardinality. - - id: batch.message_count - type: int - brief: The number of messages sent, received, or processed in the scope of the batching operation. + - ref: messaging.batch.message_count requirement_level: conditionally_required: If the span describes an operation on a batch of messages. - note: > - Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. - When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD - use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. - examples: [0, 1, 2] - - id: client_id - type: string + - ref: messaging.client_id requirement_level: recommended: If a client id is available - brief: > - A unique identifier for the client that consumes or produces a message. - examples: ['client-5', 'myhost@8742@s8083jm'] - ref: messaging.destination.name requirement_level: conditionally_required: If span describes operation on a single message or if the value applies to all messages in the batch. @@ -188,136 +109,64 @@ groups: - ref: network.protocol.version - id: messaging.rabbitmq - prefix: messaging.rabbitmq type: attribute_group extends: messaging brief: > Attributes for RabbitMQ attributes: - - id: destination.routing_key - type: string + - ref: messaging.rabbitmq.destination.routing_key requirement_level: conditionally_required: If not empty. - brief: > - RabbitMQ message routing key. - examples: 'myKey' + tag: tech-specific-rabbitmq - id: messaging.kafka - prefix: messaging.kafka type: attribute_group extends: messaging brief: > Attributes for Apache Kafka attributes: - - id: message.key - type: string - brief: > - Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. - They differ from `messaging.message.id` in that they're not unique. - If the key is `null`, the attribute MUST NOT be set. - note: > - If the key type is not string, it's string representation has to be supplied for the attribute. - If the key has no unambiguous, canonical string form, don't include its value. - examples: 'myKey' - - id: consumer.group - type: string - brief: > - Name of the Kafka Consumer Group that is handling the message. - Only applies to consumers, not producers. - examples: 'my-group' - - id: destination.partition - type: int - brief: > - Partition the message is sent to. - examples: 2 - - id: message.offset - type: int - brief: > - The offset of a record in the corresponding Kafka partition. - examples: 42 - - id: message.tombstone - type: boolean + - ref: messaging.kafka.message.key + tag: tech-specific-kafka + - ref: messaging.kafka.consumer.group + tag: tech-specific-kafka + - ref: messaging.kafka.destination.partition + tag: tech-specific-kafka + - ref: messaging.kafka.message.offset + tag: tech-specific-kafka + - ref: messaging.kafka.message.tombstone requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. - brief: 'A boolean that is true if the message is a tombstone.' + tag: tech-specific-kafka - id: messaging.rocketmq - prefix: messaging.rocketmq type: attribute_group extends: messaging brief: > Attributes for Apache RocketMQ attributes: - - id: namespace - type: string + - ref: messaging.rocketmq.namespace requirement_level: required - brief: > - Namespace of RocketMQ resources, resources in different namespaces are individual. - examples: 'myNamespace' - - id: client_group - type: string + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.client_group requirement_level: required - brief: > - Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. - examples: 'myConsumerGroup' - - id: message.delivery_timestamp - type: int + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.delivery_timestamp requirement_level: conditionally_required: If the message type is delay and delay time level is not specified. - brief: > - The timestamp in milliseconds that the delay message is expected to be delivered to consumer. - examples: 1665987217045 - - id: message.delay_time_level - type: int + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.delay_time_level requirement_level: conditionally_required: If the message type is delay and delivery timestamp is not specified. - brief: > - The delay time level for delay message, which determines the message delay time. - examples: 3 - - id: message.group - type: string + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.group requirement_level: conditionally_required: If the message type is FIFO. - brief: > - It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. - examples: 'myMessageGroup' - - id: message.type - type: - allow_custom_values: false - members: - - id: normal - value: 'normal' - brief: "Normal message" - - id: fifo - value: 'fifo' - brief: 'FIFO message' - - id: delay - value: 'delay' - brief: 'Delay message' - - id: transaction - value: 'transaction' - brief: 'Transaction message' - brief: > - Type of message. - - id: message.tag - type: string - brief: > - The secondary classifier of message besides topic. - examples: tagA - - id: message.keys - type: string[] - brief: > - Key(s) of message, another way to mark message besides message id. - examples: ['keyA', 'keyB'] - - id: consumption_model - type: - allow_custom_values: false - members: - - id: clustering - value: 'clustering' - brief: 'Clustering consumption model' - - id: broadcasting - value: 'broadcasting' - brief: 'Broadcasting consumption model' - brief: > - Model of message consumption. This only applies to consumer spans. + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.type + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.tag + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.message.keys + tag: tech-specific-rocketmq + - ref: messaging.rocketmq.consumption_model + tag: tech-specific-rocketmq From 0de415c57d9f8f8c6a5910034a7e137cd7d7c28a Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 2 Nov 2023 10:47:08 -0700 Subject: [PATCH 138/482] Make `user_agent.original` and `http.request.header.*` attributes sampling relevant on HTTP server spans (#467) --- CHANGELOG.md | 3 ++ docs/http/http-spans.md | 79 ++++++++++++++++++++++------------------- model/trace/http.yaml | 8 +++-- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afcc9d481f..8c37a4f289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,9 @@ release. ([#479](https://github.com/open-telemetry/semantic-conventions/pull/479)) - Change sampling relevant from `MUST` to `SHOULD` ([#486](https://github.com/open-telemetry/semantic-conventions/pull/486)) +- Make `user_agent.original` and `http.request.header.*` sampling relevant + on HTTP server spans. + ([#467](https://github.com/open-telemetry/semantic-conventions/pull/467)) ### Features diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 42ccfb7375..ac682e6b4c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -119,16 +119,15 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [2] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [4] | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [3] | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `http`; `spdy` | Conditionally Required: [7] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [8] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | Opt-In | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | Conditionally Required: [6] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) @@ -147,11 +146,7 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[2]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -166,19 +161,19 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[4]:** If and only if it's different than `http.request.method`. +**[3]:** If and only if it's different than `http.request.method`. -**[5]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[4]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. -**[6]:** The value SHOULD be normalized to lowercase. +**[5]:** The value SHOULD be normalized to lowercase. -**[7]:** If not `http` and `network.protocol.version` is set. +**[6]:** If not `http` and `network.protocol.version` is set. -**[8]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[9]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. +**[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): @@ -232,20 +227,25 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [1] | `3` | Recommended: if and only if request was retried. | -| [`server.address`](../general/attributes.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`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.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` | Required | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [2] | `3` | Recommended: if and only if request was retried. | +| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Required | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Opt-In | -**[1]:** 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). +**[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[2]:** 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). -**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[3]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[4]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. @@ -341,39 +341,46 @@ For an HTTP server span, `SpanKind` MUST be `Server`. |---|---|---|---|---| | [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | | [`client.port`](../general/attributes.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Opt-In | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [3] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [5] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | +| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [7] | `http`; `https` | Required | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. **[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. +**[3]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. -**[4]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[4]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. **[5]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[6]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + +**[7]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[7]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`client.address`](../general/attributes.md) +* [`http.request.header.`](../attributes-registry/http.md) * [`server.address`](../general/attributes.md) * [`server.port`](../general/attributes.md) * [`url.path`](../attributes-registry/url.md) * [`url.query`](../attributes-registry/url.md) * [`url.scheme`](../attributes-registry/url.md) +* [`user_agent.original`](../attributes-registry/user-agent.md) `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 7162eebf0e..1e5667ad4f 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -10,8 +10,6 @@ groups: - ref: http.request.method_original requirement_level: conditionally_required: If and only if it's different than `http.request.method`. - - ref: http.request.header - requirement_level: opt_in - ref: http.response.header requirement_level: opt_in - ref: http.request.method @@ -36,6 +34,8 @@ groups: - ref: http.request.resend_count requirement_level: recommended: if and only if request was retried. + - ref: http.request.header + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -54,6 +54,9 @@ groups: brief: 'Semantic Convention for HTTP Server' attributes: - ref: http.route + - ref: http.request.header + sampling_relevant: true + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -85,3 +88,4 @@ groups: - ref: url.scheme sampling_relevant: true - ref: user_agent.original + sampling_relevant: true From 09b0b64990ba664fe70c154fa47432ec29e15c47 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 3 Nov 2023 09:05:54 -0700 Subject: [PATCH 139/482] Mark HTTP semantic conventions as stable (#377) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 2 ++ Makefile | 4 ++-- docs/attributes-registry/http.md | 14 +++++++------- docs/attributes-registry/network.md | 16 ++++++++-------- docs/attributes-registry/url.md | 10 +++++----- docs/attributes-registry/user-agent.md | 2 +- docs/general/attributes.md | 8 ++++---- docs/http/README.md | 2 +- docs/http/http-metrics.md | 6 +++--- docs/http/http-spans.md | 2 +- model/client.yaml | 2 ++ model/error.yaml | 1 + model/registry/http.yaml | 7 +++++++ model/registry/network.yaml | 8 ++++++++ model/registry/url.yaml | 5 +++++ model/registry/user-agent.yaml | 1 + model/server.yaml | 2 ++ 17 files changed, 60 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c37a4f289..7505ad25f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,8 @@ release. ([#409](https://github.com/open-telemetry/semantic-conventions/pull/409)) - Add `host.mac` resource attribute convention. ([#340](https://github.com/open-telemetry/semantic-conventions/pull/340)) +- Mark HTTP semantic conventions as stable. + ([#377](https://github.com/open-telemetry/semantic-conventions/pull/377)) ### Fixes diff --git a/Makefile b/Makefile index ca93385774..acbb7f7de7 100644 --- a/Makefile +++ b/Makefile @@ -90,13 +90,13 @@ yamllint: .PHONY: table-generation table-generation: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-use-badges --md-stable # Check if current markdown tables differ from the ones that would be generated from YAML definitions .PHONY: table-check table-check: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check --md-use-badges --md-stable .PHONY: schema-check schema-check: diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 04d52c8a25..ee711c7e4a 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -9,14 +9,14 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `http.request.body.size` | 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` | -| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | -| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | -| `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | +| `http.request.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | +| `http.request.method` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request method. [2] | `GET`; `POST`; `HEAD` | +| `http.request.method_original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | +| `http.request.resend_count` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | | `http.response.body.size` | 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` | -| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | -| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | -| `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | +| `http.response.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | +| `http.response.status_code` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | +| `http.route` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | **[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 3e6cb078c7..77f00acedd 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -16,14 +16,14 @@ These attributes may be used for any network related operation. | `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | | `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | | `network.connection.type` | string | The internet connection type. | `wifi` | -| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | -| `network.local.port` | int | Local port number of the network connection. | `65123` | -| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | -| `network.peer.port` | int | Peer port number of the network connection. | `65123` | -| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | -| `network.protocol.version` | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | -| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | -| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | +| `network.local.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | +| `network.local.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local port number of the network connection. | `65123` | +| `network.peer.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | +| `network.peer.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer port number of the network connection. | `65123` | +| `network.protocol.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | +| `network.protocol.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | +| `network.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | +| `network.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index f361f46e8b..5b1aa7c0d8 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -8,11 +8,11 @@ linkTitle: URL | Attribute | Type | Description | Examples | |---|---|---|---| -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | -| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | +| `url.fragment` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | +| `url.full` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | +| `url.path` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | +| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | +| `url.scheme` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md index d60e19697f..589f722f87 100644 --- a/docs/attributes-registry/user-agent.md +++ b/docs/attributes-registry/user-agent.md @@ -8,5 +8,5 @@ | Attribute | Type | Description | Examples | |---|---|---|---| -| `user_agent.original` | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | +| `user_agent.original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 5f2e6a3280..3a57817222 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -69,8 +69,8 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `server.address` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | Recommended | +| `server.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `server.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server port number. [2] | `80`; `8080`; `443` | Recommended | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -106,8 +106,8 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `client.port` | int | Client port number. [2] | `65123` | Recommended | +| `client.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| `client.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client port number. [2] | `65123` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/http/README.md b/docs/http/README.md index 1c27a324f4..c76f1367cb 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -7,7 +7,7 @@ path_base_for_github_subdir: # Semantic Conventions for HTTP -**Status**: [Experimental, Feature-freeze][DocumentStatus] +**Status**: [Mixed][DocumentStatus] This document defines semantic conventions for HTTP spans, metrics and logs. They can be used for http and https schemes diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index d9ee1cc417..5ed9adae76 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -4,7 +4,7 @@ linkTitle: Metrics # Semantic Conventions for HTTP Metrics -**Status**: [Experimental, partial feature-freeze][DocumentStatus] +**Status**: [Mixed][DocumentStatus] The conventions described in this section are HTTP specific. When HTTP operations occur, metric events about those operations will be generated and reported to provide insight into the @@ -57,7 +57,7 @@ operations. By adding HTTP attributes to metric events it allows for finely tune ### Metric: `http.server.request.duration` -**Status**: [Experimental, Feature-freeze][DocumentStatus] +**Status**: [Stable][DocumentStatus] This metric is required. @@ -430,7 +430,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin ### Metric: `http.client.request.duration` -**Status**: [Experimental, Feature-freeze][DocumentStatus] +**Status**: [Stable][DocumentStatus] This metric is required. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index ac682e6b4c..04bd5042eb 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -4,7 +4,7 @@ linkTitle: Spans # Semantic Conventions for HTTP Spans -**Status**: [Experimental, Feature-freeze][DocumentStatus] +**Status**: [Stable][DocumentStatus] This document defines semantic conventions for HTTP client and server Spans. They can be used for http and https schemes diff --git a/model/client.yaml b/model/client.yaml index 0e133f0e4c..bd214a1708 100644 --- a/model/client.yaml +++ b/model/client.yaml @@ -11,6 +11,7 @@ groups: This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. attributes: - id: address + stability: stable type: string brief: "Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > @@ -18,6 +19,7 @@ groups: the client address behind any intermediaries, for example proxies, if it's available. examples: ['client.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port + stability: stable type: int brief: Client port number. examples: [65123] diff --git a/model/error.yaml b/model/error.yaml index a86b33408a..1a40f32b0a 100644 --- a/model/error.yaml +++ b/model/error.yaml @@ -7,6 +7,7 @@ groups: report an error. attributes: - id: type + stability: stable brief: 'Describes a class of error the operation ended with.' type: allow_custom_values: true diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 57a7de3ce7..2cb8e8b894 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -13,6 +13,7 @@ groups: examples: 3495 stability: experimental # this should not be marked stable with other HTTP attributes - id: request.header + stability: stable type: template[string[]] brief: > HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. @@ -28,6 +29,7 @@ groups: the HTTP library provides access to headers. examples: ['http.request.header.content-type=["application/json"]', 'http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]'] - id: request.method + stability: stable type: allow_custom_values: true members: @@ -79,10 +81,12 @@ groups: Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - id: request.method_original + stability: stable type: string brief: Original HTTP method sent by the client in the request line. examples: ["GeT", "ACL", "foo"] - id: request.resend_count + stability: stable type: int brief: > The ordinal number of request resending attempt (for any reason, including redirects). @@ -100,6 +104,7 @@ groups: examples: 3495 stability: experimental # this should not be marked stable with other HTTP attributes - id: response.header + stability: stable type: template[string[]] brief: > HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. @@ -114,10 +119,12 @@ groups: the HTTP library provides access to headers. examples: ['http.response.header.content-type=["application/json"]', 'http.response.header.my-custom-header=["abc", "def"]'] - id: response.status_code + stability: stable type: int brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' examples: [200] - id: route + stability: stable type: string brief: > The matched route, that is, the path template in the format used by the respective server framework. diff --git a/model/registry/network.yaml b/model/registry/network.yaml index b5ecb1efb8..27b072a08c 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -107,27 +107,33 @@ groups: brief: 'The internet connection type.' examples: 'wifi' - id: local.address + stability: stable type: string brief: Local address of the network connection - IP address or Unix domain socket name. examples: ['10.1.2.80', '/tmp/my.sock'] - id: local.port + stability: stable type: int brief: Local port number of the network connection. examples: [65123] - id: peer.address + stability: stable type: string brief: Peer address of the network connection - IP address or Unix domain socket name. examples: ['10.1.2.80', '/tmp/my.sock'] - id: peer.port + stability: stable type: int brief: Peer port number of the network connection. examples: [65123] - id: protocol.name + stability: stable type: string brief: '[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.' note: The value SHOULD be normalized to lowercase. examples: ['amqp', 'http', 'mqtt'] - id: protocol.version + stability: stable type: string brief: Version of the protocol specified in `network.protocol.name`. examples: '3.1.1' @@ -136,6 +142,7 @@ groups: different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - id: transport + stability: stable type: allow_custom_values: true members: @@ -162,6 +169,7 @@ groups: different processes could be listening on TCP port 12345 and UDP port 12345. examples: ['tcp', 'udp'] - id: type + stability: stable type: allow_custom_values: true members: diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 0e0d202720..985ca9123f 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -5,10 +5,12 @@ groups: prefix: url attributes: - id: scheme + stability: stable type: string brief: 'The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.' examples: ["https", "ftp", "telnet"] - id: full + stability: stable type: string brief: Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) note: > @@ -22,15 +24,18 @@ groups: and SHOULD NOT be validated or modified except for sanitizing purposes. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] - id: path + stability: stable type: string brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' examples: ['/search'] - id: query + stability: stable type: string brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' examples: ["q=OpenTelemetry"] note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - id: fragment + stability: stable type: string brief: 'The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component' examples: ["SemConv"] diff --git a/model/registry/user-agent.yaml b/model/registry/user-agent.yaml index 2b93ac114d..0fbc5c9f2a 100644 --- a/model/registry/user-agent.yaml +++ b/model/registry/user-agent.yaml @@ -5,6 +5,7 @@ groups: brief: "Describes user-agent attributes." attributes: - id: original + stability: stable 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. diff --git a/model/server.yaml b/model/server.yaml index eecdc7c8db..f47174dda2 100644 --- a/model/server.yaml +++ b/model/server.yaml @@ -11,6 +11,7 @@ groups: This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. attributes: - id: address + stability: stable type: string brief: "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > @@ -18,6 +19,7 @@ groups: the server address behind any intermediaries, for example proxies, if it's available. examples: ['example.com', '10.1.2.80', '/tmp/my.sock'] - id: port + stability: stable type: int brief: Server port number. note: > From da1dbb567f0f0c866dde79a7564a58ab8019b1cf Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 3 Nov 2023 12:55:57 -0400 Subject: [PATCH 140/482] Staging the 1.23.0 release. (#489) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 11 ++ schema-next.yaml | 1 + schemas/1.23.0 | 293 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 schemas/1.23.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7505ad25f7..262cc39b5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ release. ### Breaking +### Features + +### Fixes + +## v1.23.0 (2023-11-03) + +This release marks the first where the core of HTTP semantic conventions have +stabilized. + +### Breaking + - BREAKING: Rename http.resend_count to http.request.resend_count. ([#374](https://github.com/open-telemetry/semantic-conventions/pull/374)) - BREAKING: Change `network.protocol.name` from recommended to opt-in in HTTP semconv. diff --git a/schema-next.yaml b/schema-next.yaml index 4c3647ce4d..4f618de046 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,7 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + 1.23.0: metrics: changes: # https://github.com/open-telemetry/semantic-conventions/pull/20 diff --git a/schemas/1.23.0 b/schemas/1.23.0 new file mode 100644 index 0000000000..a6e29937d0 --- /dev/null +++ b/schemas/1.23.0 @@ -0,0 +1,293 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.23.0 +versions: + 1.23.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + thread.daemon: jvm.thread.daemon + apply_to_metrics: + - jvm.thread.count + 1.22.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size + # https://github.com/open-telemetry/opentelemetry-specification/pull/374 + - rename_attributes: + attribute_map: + http.resend_count: http.request.resend_count + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit + process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.usage + - jvm.buffer.limit + - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version + 1.21.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3336 + - rename_attributes: + attribute_map: + messaging.kafka.client_id: messaging.client_id + messaging.rocketmq.client_id: messaging.client_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3402 + - rename_attributes: + attribute_map: + # net.peer.(name|port) attributes were usually populated on client side + # so they should be usually translated to server.(address|port) + # net.host.* attributes were only populated on server side + net.host.name: server.address + net.host.port: server.port + # was only populated on client side + net.sock.peer.name: server.socket.domain + # net.sock.peer.(addr|port) mapping is not possible + # since they applied to both client and server side + # were only populated on server side + net.sock.host.addr: server.socket.address + net.sock.host.port: server.socket.port + http.client_ip: client.address + # https://github.com/open-telemetry/opentelemetry-specification/pull/3426 + - rename_attributes: + attribute_map: + net.protocol.name: network.protocol.name + net.protocol.version: network.protocol.version + net.host.connection.type: network.connection.type + net.host.connection.subtype: network.connection.subtype + net.host.carrier.name: network.carrier.name + net.host.carrier.mcc: network.carrier.mcc + net.host.carrier.mnc: network.carrier.mnc + net.host.carrier.icc: network.carrier.icc + # https://github.com/open-telemetry/opentelemetry-specification/pull/3355 + - rename_attributes: + attribute_map: + http.method: http.request.method + http.status_code: http.response.status_code + http.scheme: url.scheme + http.url: url.full + http.request_content_length: http.request.body.size + http.response_content_length: http.response.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/53 + - rename_metrics: + process.runtime.jvm.cpu.utilization: process.runtime.jvm.cpu.recent_utilization + 1.20.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3272 + - rename_attributes: + attribute_map: + net.app.protocol.name: net.protocol.name + net.app.protocol.version: net.protocol.version + 1.19.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3209 + - rename_attributes: + attribute_map: + faas.execution: faas.invocation_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3188 + - rename_attributes: + attribute_map: + faas.id: cloud.resource_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + http.user_agent: user_agent.original + resources: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + browser.user_agent: user_agent.original + 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: From 39af37d0935f7e9030cddade5b0e16a9c4ea135c Mon Sep 17 00:00:00 2001 From: Ben Blackmore Date: Tue, 7 Nov 2023 13:54:51 +0100 Subject: [PATCH 141/482] docs: explain deployment.environment impact on service identity (#481) Co-authored-by: Alexander Wert Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 1 + docs/resource/deployment-environment.md | 10 +++++++++- model/resource/deployment_environment.yaml | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 262cc39b5a..5a1368259f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ stabilized. - Change the precedence between `:authority` and `Host` headers when populating `server.address` and `server.port` attributes. ([#455](https://github.com/open-telemetry/semantic-conventions/pull/455)) +- Explain `deployment.environment` impact on service identity. ([#481](https://github.com/open-telemetry/semantic-conventions/pull/481)) ## v1.22.0 (2023-10-12) diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index e9ff217754..faba4a47d9 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -9,7 +9,15 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). | `staging`; `production` | Recommended | +| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | Recommended | + +**[1]:** `deployment.environment` does not affect the uniqueness constraints defined through +the `service.namespace`, `service.name` and `service.instance.id` resource attributes. +This implies that resources carrying the following attribute combinations MUST be +considered to be identifying the same service: + +* `service.name=frontend`, `deployment.environment=production` +* `service.name=frontend`, `deployment.environment=staging`. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/resource/deployment_environment.yaml b/model/resource/deployment_environment.yaml index 9109f6f7cb..7ada3f9798 100644 --- a/model/resource/deployment_environment.yaml +++ b/model/resource/deployment_environment.yaml @@ -10,4 +10,12 @@ groups: brief: > Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). + note: | + `deployment.environment` does not affect the uniqueness constraints defined through + the `service.namespace`, `service.name` and `service.instance.id` resource attributes. + This implies that resources carrying the following attribute combinations MUST be + considered to be identifying the same service: + + * `service.name=frontend`, `deployment.environment=production` + * `service.name=frontend`, `deployment.environment=staging`. examples: ['staging', 'production'] From 65a3cc743f71ee202242ca4e984c5f8bb56e187d Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 7 Nov 2023 10:38:11 -0700 Subject: [PATCH 142/482] change Erlang managed thread attribute to be the Erlang process (#491) Co-authored-by: Joao Grassi --- docs/general/attributes.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 3a57817222..59ec7e5527 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -364,14 +364,14 @@ a thread that started a span. Examples of where `thread.id` and `thread.name` can be extracted from: -| Language or platform | `thread.id` | `thread.name` | -|-----------------------|----------------------------------------|------------------------------------| -| JVM | `Thread.currentThread().getId()` | `Thread.currentThread().getName()` | -| .NET | `Thread.CurrentThread.ManagedThreadId` | `Thread.CurrentThread.Name` | -| Python | `threading.current_thread().ident` | `threading.current_thread().name` | -| Ruby | `Thread.current.object_id` | `Thread.current.name` | -| C++ | `std::this_thread::get_id()` | | -| Erlang | `erlang:system_info(scheduler_id)` | | +| Language or platform | `thread.id` | `thread.name` | +|-----------------------|----------------------------------------|------------------------------------------------| +| JVM | `Thread.currentThread().getId()` | `Thread.currentThread().getName()` | +| .NET | `Thread.CurrentThread.ManagedThreadId` | `Thread.CurrentThread.Name` | +| Python | `threading.current_thread().ident` | `threading.current_thread().name` | +| Ruby | `Thread.current.object_id` | `Thread.current.name` | +| C++ | `std::this_thread::get_id()` | | +| Erlang | `erlang:self()` | `erlang:process_info(self(), registered_name)` | ## Source Code Attributes From e3da931d08a0f76af34afea2183d31ba081d8887 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 9 Nov 2023 08:17:32 -0600 Subject: [PATCH 143/482] Add `code.stacktrace` attribute (#435) Signed-off-by: Alexander Wert --- CHANGELOG.md | 3 +++ docs/attributes-registry/code.md | 1 + docs/general/attributes.md | 1 + model/general.yaml | 2 ++ model/registry/code.yaml | 8 ++++++++ 5 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a1368259f..136e4ed089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ release. ### Features +- Add `code.stacktrace` attribute + ([#435](https://github.com/open-telemetry/semantic-conventions/pull/435)) + ### Fixes ## v1.23.0 (2023-11-03) diff --git a/docs/attributes-registry/code.md b/docs/attributes-registry/code.md index a337e239ed..651caa99f5 100644 --- a/docs/attributes-registry/code.md +++ b/docs/attributes-registry/code.md @@ -15,4 +15,5 @@ These attributes allow to report this unit of code and therefore to provide more | `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | | `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | | `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | +| `code.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | \ No newline at end of file diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 59ec7e5527..b18317a4f3 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -389,6 +389,7 @@ about the span. | [`code.function`](../attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | | [`code.lineno`](../attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | Recommended | | [`code.namespace`](../attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | +| [`code.stacktrace`](../attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Opt-In | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/general.yaml b/model/general.yaml index cfcce21cef..a4fcb77c6c 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -53,3 +53,5 @@ groups: - ref: code.filepath - ref: code.lineno - ref: code.column + - ref: code.stacktrace + requirement_level: opt_in diff --git a/model/registry/code.yaml b/model/registry/code.yaml index 373a4bc6c3..d5afceeaed 100644 --- a/model/registry/code.yaml +++ b/model/registry/code.yaml @@ -31,3 +31,11 @@ groups: brief: > The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. examples: 16 + - id: stacktrace + type: string + brief: > + A stacktrace as a string in the natural representation for the language runtime. + The representation is to be determined and documented by each language SIG. + examples: 'at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n + at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n + at com.example.GenerateTrace.main(GenerateTrace.java:5)' From 6a9acefdbf73b96070d97c4398ab3227d834a992 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 9 Nov 2023 10:19:03 -0600 Subject: [PATCH 144/482] Moved client, server, source, destination attributes to the registry (#391) Signed-off-by: Alexander Wert --- docs/attributes-registry/README.md | 4 ++++ docs/attributes-registry/client.md | 23 ++++++++++++++++++++ docs/attributes-registry/destination.md | 21 +++++++++++++++++++ docs/attributes-registry/server.md | 23 ++++++++++++++++++++ docs/attributes-registry/source.md | 21 +++++++++++++++++++ docs/database/database-spans.md | 4 ++-- docs/database/elasticsearch.md | 4 ++-- docs/general/attributes.md | 24 ++++++++++----------- docs/http/http-metrics.md | 28 ++++++++++++------------- docs/http/http-spans.md | 22 +++++++++---------- docs/messaging/messaging-spans.md | 2 +- docs/rpc/rpc-metrics.md | 4 ++-- docs/rpc/rpc-spans.md | 8 +++---- model/general.yaml | 28 +++++++++++++++++++++++++ model/{ => registry}/client.yaml | 0 model/{ => registry}/destination.yaml | 3 ++- model/{ => registry}/server.yaml | 0 model/{ => registry}/source.yaml | 3 ++- 18 files changed, 172 insertions(+), 50 deletions(-) create mode 100644 docs/attributes-registry/client.md create mode 100644 docs/attributes-registry/destination.md create mode 100644 docs/attributes-registry/server.md create mode 100644 docs/attributes-registry/source.md rename model/{ => registry}/client.yaml (100%) rename model/{ => registry}/destination.yaml (90%) rename model/{ => registry}/server.yaml (100%) rename model/{ => registry}/source.yaml (90%) diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index fdff795789..f5f56b533f 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,13 +27,17 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Client](client.md) * [Cloud](cloud.md) * [Code](code.md) * [Container](container.md) +* [Destination](destination.md) * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) * [RPC](rpc.md) +* [Server](server.md) +* [Source](source.md) * [Thread](thread.md) * [URL](url.md) * [User agent](user-agent.md) diff --git a/docs/attributes-registry/client.md b/docs/attributes-registry/client.md new file mode 100644 index 0000000000..9ed3875a83 --- /dev/null +++ b/docs/attributes-registry/client.md @@ -0,0 +1,23 @@ + + +# Client Attributes + +These attributes may be used to describe the client in a connection-based network interaction +where there is one side that initiates the connection (the client is the side that initiates the connection). +This covers all TCP network interactions since TCP is connection-based and one side initiates the +connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the +protocol / API does not expose a clear notion of client and server). +This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `client.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| `client.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client port number. [2] | `65123` | + +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. + +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. + diff --git a/docs/attributes-registry/destination.md b/docs/attributes-registry/destination.md new file mode 100644 index 0000000000..db83cb53b0 --- /dev/null +++ b/docs/attributes-registry/destination.md @@ -0,0 +1,21 @@ + + +# Destination Attributes + +These attributes may be used to describe the receiver of a network exchange/packet. These should be used +when there is no client/server relationship between the two sides, or when that relationship is unknown. +This covers low-level network interactions (e.g. packet tracing) where you don't know if +there was a connection or which side initiated it. +This also covers unidirectional UDP flows and peer-to-peer communication where the +"user-facing" surface of the protocol / API does not expose a clear notion of client and server. + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| `destination.port` | int | Destination port number | `3389`; `2888` | + +**[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. + diff --git a/docs/attributes-registry/server.md b/docs/attributes-registry/server.md new file mode 100644 index 0000000000..a1189591a1 --- /dev/null +++ b/docs/attributes-registry/server.md @@ -0,0 +1,23 @@ + + +# Server Attributes + +These attributes may be used to describe the server in a connection-based network interaction +where there is one side that initiates the connection (the client is the side that initiates the connection). +This covers all TCP network interactions since TCP is connection-based and one side initiates the +connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the +protocol / API does not expose a clear notion of client and server). +This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `server.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| `server.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server port number. [2] | `80`; `8080`; `443` | + +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + \ No newline at end of file diff --git a/docs/attributes-registry/source.md b/docs/attributes-registry/source.md new file mode 100644 index 0000000000..c239896bf1 --- /dev/null +++ b/docs/attributes-registry/source.md @@ -0,0 +1,21 @@ + + +# Source Attributes + +These attributes may be used to describe the sender of a network exchange/packet. These should be used +when there is no client/server relationship between the two sides, or when that relationship is unknown. +This covers low-level network interactions (e.g. packet tracing) where you don't know if +there was a connection or which side initiated it. +This also covers unidirectional UDP flows and peer-to-peer communication where the +"user-facing" surface of the protocol / API does not expose a clear notion of client and server. + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| `source.port` | int | Source port number | `3389`; `2888` | + +**[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. + \ No newline at end of file diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 92678e42c5..1d3f6471f9 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -71,8 +71,8 @@ Some database systems may allow a connection to switch to a different `db.user`, | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 1d82327cee..0dc1a722fa 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -32,8 +32,8 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. diff --git a/docs/general/attributes.md b/docs/general/attributes.md index b18317a4f3..e9f9dddad7 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -66,11 +66,11 @@ identify the transport, then setting [`network.transport`](#other-network-attrib Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed if they do not cause breaking changes to HTTP semantic conventions. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `server.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `server.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server port number. [2] | `80`; `8080`; `443` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | Recommended | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -103,11 +103,11 @@ For Unix domain socket, `server.address` attribute represents remote endpoint ad Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed if they do not cause breaking changes to HTTP semantic conventions. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `client.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `client.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client port number. [2] | `65123` | Recommended | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | Recommended | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. @@ -125,11 +125,11 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t #### Source - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `source.port` | int | Source port number | `3389`; `2888` | Recommended | +| [`source.address`](../attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`source.port`](../attributes-registry/source.md) | int | Source port number | `3389`; `2888` | Recommended | **[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. @@ -138,11 +138,11 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t Destination fields capture details about the receiver of a network exchange/packet. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| `destination.port` | int | Destination port number | `3389`; `2888` | Recommended | +| [`destination.address`](../attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`destination.port`](../attributes-registry/destination.md) | int | Destination port number | `3389`; `2888` | Recommended | **[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 5ed9adae76..2eee6cc7ee 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -82,8 +82,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -177,8 +177,8 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. @@ -245,8 +245,8 @@ This metric is optional. | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -347,8 +347,8 @@ This metric is optional. | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | **[1]:** If the request fails with an error before response status code was sent or received, @@ -454,8 +454,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -544,8 +544,8 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -634,8 +634,8 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 04bd5042eb..cd1553265c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -229,8 +229,8 @@ For an HTTP client span, `SpanKind` MUST be `Client`. |---|---|---|---|---| | [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | | [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [2] | `3` | Recommended: if and only if request was retried. | -| [`server.address`](../general/attributes.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Required | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Required | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Opt-In | @@ -251,8 +251,8 @@ The attribute value MUST consist of either multiple header values as an array of The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* [`server.address`](../general/attributes.md) -* [`server.port`](../general/attributes.md) +* [`server.address`](../attributes-registry/server.md) +* [`server.port`](../attributes-registry/server.md) * [`url.full`](../attributes-registry/url.md) @@ -339,14 +339,14 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../general/attributes.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Opt-In | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | +| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Opt-In | | [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [3] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | -| [`server.address`](../general/attributes.md) | string | Name of the local HTTP server that received the request. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | | [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | @@ -373,10 +373,10 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* [`client.address`](../general/attributes.md) +* [`client.address`](../attributes-registry/client.md) * [`http.request.header.`](../attributes-registry/http.md) -* [`server.address`](../general/attributes.md) -* [`server.port`](../general/attributes.md) +* [`server.address`](../attributes-registry/server.md) +* [`server.port`](../attributes-registry/server.md) * [`url.path`](../attributes-registry/url.md) * [`url.query`](../attributes-registry/url.md) * [`url.scheme`](../attributes-registry/url.md) diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index ec9c82526b..29097e37b4 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -294,7 +294,7 @@ messages were received). For each message it accounts for, the "Deliver" or | [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../general/attributes.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 4821b500e7..5e28b81bdc 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -225,8 +225,8 @@ measurements. | [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index e65c6844ed..7e50888583 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -90,8 +90,8 @@ Examples of span names: | [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | | [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | | [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../general/attributes.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../general/attributes.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | +| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | **[1]:** The value SHOULD be normalized to lowercase. @@ -166,8 +166,8 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`client.address`](../general/attributes.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`client.port`](../general/attributes.md) | int | Client port number. [2] | `65123` | Recommended | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | diff --git a/model/general.yaml b/model/general.yaml index a4fcb77c6c..e3bad3d46a 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -1,4 +1,32 @@ groups: + - id: general.client + type: attribute_group + brief: > + General client attributes. + attributes: + - ref: client.address + - ref: client.port + - id: general.server + type: attribute_group + brief: > + General server attributes. + attributes: + - ref: server.address + - ref: server.port + - id: general.source + type: attribute_group + brief: > + General source attributes. + attributes: + - ref: source.address + - ref: source.port + - id: general.destination + type: attribute_group + brief: > + General destination attributes. + attributes: + - ref: destination.address + - ref: destination.port - id: peer prefix: peer type: span diff --git a/model/client.yaml b/model/registry/client.yaml similarity index 100% rename from model/client.yaml rename to model/registry/client.yaml diff --git a/model/destination.yaml b/model/registry/destination.yaml similarity index 90% rename from model/destination.yaml rename to model/registry/destination.yaml index 30d155ce56..595a1c67f9 100644 --- a/model/destination.yaml +++ b/model/registry/destination.yaml @@ -2,7 +2,8 @@ groups: - id: destination prefix: destination type: attribute_group - brief: These attributes may be used to describe the receiver of a network exchange/packet. These should be used + brief: > + These attributes may be used to describe the receiver of a network exchange/packet. These should be used when there is no client/server relationship between the two sides, or when that relationship is unknown. This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. diff --git a/model/server.yaml b/model/registry/server.yaml similarity index 100% rename from model/server.yaml rename to model/registry/server.yaml diff --git a/model/source.yaml b/model/registry/source.yaml similarity index 90% rename from model/source.yaml rename to model/registry/source.yaml index c142eaffec..263a491cab 100644 --- a/model/source.yaml +++ b/model/registry/source.yaml @@ -2,7 +2,8 @@ groups: - id: source prefix: source type: attribute_group - brief: These attributes may be used to describe the sender of a network exchange/packet. These should be used + brief: > + These attributes may be used to describe the sender of a network exchange/packet. These should be used when there is no client/server relationship between the two sides, or when that relationship is unknown. This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. From a1b924ca85c091365ef2e3d1cf6029816508a5a6 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:53:46 +0100 Subject: [PATCH 145/482] move process to registry (#502) Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/process.md | 19 +++++++++ docs/resource/process.md | 26 ++++++------ model/registry/process.yaml | 60 ++++++++++++++++++++++++++++ model/resource/process.yaml | 61 ++++------------------------- 5 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 docs/attributes-registry/process.md create mode 100644 model/registry/process.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index f5f56b533f..12114a5a36 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -35,6 +35,7 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) +* [Process](process.md) * [RPC](rpc.md) * [Server](server.md) * [Source](source.md) diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md new file mode 100644 index 0000000000..5f70408a5e --- /dev/null +++ b/docs/attributes-registry/process.md @@ -0,0 +1,19 @@ + + +# Process + +## Process Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | +| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | +| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | +| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | +| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | +| `process.owner` | string | The username of the user that owns the process. | `root` | +| `process.parent_pid` | int | Parent Process identifier (PID). | `111` | +| `process.pid` | int | Process identifier (PID). | `1234` | + diff --git a/docs/resource/process.md b/docs/resource/process.md index 737c4aca68..e2c77194e9 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -27,22 +27,22 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | Conditionally Required: See alternative attributes below. | -| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | Conditionally Required: See alternative attributes below. | -| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | Conditionally Required: See alternative attributes below. | -| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | -| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | -| `process.owner` | string | The username of the user that owns the process. | `root` | Recommended | -| `process.parent_pid` | int | Parent Process identifier (PID). | `111` | Recommended | -| `process.pid` | int | Process identifier (PID). | `1234` | Recommended | +| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | Conditionally Required: See alternative attributes below. | +| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | Conditionally Required: See alternative attributes below. | +| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | Conditionally Required: See alternative attributes below. | +| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | +| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | +| [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | Recommended | +| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PID). | `111` | Recommended | +| [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | Recommended | **Additional attribute requirements:** At least one of the following sets of attributes is required: -* `process.executable.name` -* `process.executable.path` -* `process.command` -* `process.command_line` -* `process.command_args` +* [`process.executable.name`](../attributes-registry/process.md) +* [`process.executable.path`](../attributes-registry/process.md) +* [`process.command`](../attributes-registry/process.md) +* [`process.command_line`](../attributes-registry/process.md) +* [`process.command_args`](../attributes-registry/process.md) Between `process.command_args` and `process.command_line`, usually `process.command_args` should be preferred. diff --git a/model/registry/process.yaml b/model/registry/process.yaml new file mode 100644 index 0000000000..894d09899e --- /dev/null +++ b/model/registry/process.yaml @@ -0,0 +1,60 @@ +groups: + - id: registry.process + prefix: process + type: attribute_group + brief: > + An operating system process. + attributes: + - id: pid + type: int + brief: > + Process identifier (PID). + examples: [1234] + - id: parent_pid + type: int + brief: > + Parent Process identifier (PID). + examples: [111] + - id: executable.name + type: string + brief: > + The name of the process executable. On Linux based systems, can be set + to the `Name` in `proc/[pid]/status`. On Windows, can be set to the + base name of `GetProcessImageFileNameW`. + examples: ['otelcol'] + - id: executable.path + type: string + brief: > + The full path to the process executable. On Linux based systems, can + be set to the target of `proc/[pid]/exe`. On Windows, can be set to the + result of `GetProcessImageFileNameW`. + examples: ['/usr/bin/cmd/otelcol'] + - id: command + type: string + brief: > + The command used to launch the process (i.e. the command name). On Linux + based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. + On Windows, can be set to the first parameter extracted from `GetCommandLineW`. + examples: ['cmd/otelcol'] + - id: command_line + type: string + brief: > + The full command used to launch the process as a single string representing + the full command. On Windows, can be set to the result of `GetCommandLineW`. + Do not set this if you have to assemble it just for monitoring; use + `process.command_args` instead. + examples: ['C:\cmd\otecol --config="my directory\config.yaml"'] + - id: command_args + type: string[] + brief: > + All the command arguments (including the command/executable itself) as + received by the process. On Linux-based systems (and some other Unixoid + systems supporting procfs), can be set according to the list of + null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based + executables, this would be the full argv vector passed to `main`. + examples: ['cmd/otecol', '--config=config.yaml'] + - id: owner + type: string + brief: > + The username of the user that owns the process. + examples: 'root' diff --git a/model/resource/process.yaml b/model/resource/process.yaml index d7d3b25b56..54b141cc6d 100644 --- a/model/resource/process.yaml +++ b/model/resource/process.yaml @@ -5,69 +5,24 @@ groups: brief: > An operating system process. attributes: - - id: pid - type: int - brief: > - Process identifier (PID). - examples: [1234] - - id: parent_pid - type: int - brief: > - Parent Process identifier (PID). - examples: [111] - - id: executable.name - type: string + - ref: process.pid + - ref: process.parent_pid + - ref: process.executable.name requirement_level: conditionally_required: See alternative attributes below. - brief: > - The name of the process executable. On Linux based systems, can be set - to the `Name` in `proc/[pid]/status`. On Windows, can be set to the - base name of `GetProcessImageFileNameW`. - examples: ['otelcol'] - - id: executable.path - type: string + - ref: process.executable.path requirement_level: conditionally_required: See alternative attributes below. - brief: > - The full path to the process executable. On Linux based systems, can - be set to the target of `proc/[pid]/exe`. On Windows, can be set to the - result of `GetProcessImageFileNameW`. - examples: ['/usr/bin/cmd/otelcol'] - - id: command - type: string + - ref: process.command requirement_level: conditionally_required: See alternative attributes below. - brief: > - The command used to launch the process (i.e. the command name). On Linux - based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. - On Windows, can be set to the first parameter extracted from `GetCommandLineW`. - examples: ['cmd/otelcol'] - - id: command_line - type: string + - ref: process.command_line requirement_level: conditionally_required: See alternative attributes below. - brief: > - The full command used to launch the process as a single string representing - the full command. On Windows, can be set to the result of `GetCommandLineW`. - Do not set this if you have to assemble it just for monitoring; use - `process.command_args` instead. - examples: ['C:\cmd\otecol --config="my directory\config.yaml"'] - - id: command_args - type: string[] + - ref: process.command_args requirement_level: conditionally_required: See alternative attributes below. - brief: > - All the command arguments (including the command/executable itself) as - received by the process. On Linux-based systems (and some other Unixoid - systems supporting procfs), can be set according to the list of - null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based - executables, this would be the full argv vector passed to `main`. - examples: ['cmd/otecol', '--config=config.yaml'] - - id: owner - type: string - brief: > - The username of the user that owns the process. - examples: 'root' + - ref: process.owner constraints: - any_of: - process.executable.name From 3a8220c677e82d25df9c5217c19b58f5557a62fc Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:02:40 +0100 Subject: [PATCH 146/482] move device to the registry (#497) Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/device.md | 23 +++++++++++++++ docs/resource/device.md | 12 ++++---- model/registry/device.yaml | 46 ++++++++++++++++++++++++++++++ model/resource/device.yaml | 38 +++--------------------- 5 files changed, 80 insertions(+), 40 deletions(-) create mode 100644 docs/attributes-registry/device.md create mode 100644 model/registry/device.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 12114a5a36..9755685ee1 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -32,6 +32,7 @@ Currently, the following namespaces exist: * [Code](code.md) * [Container](container.md) * [Destination](destination.md) +* [Device](device.md) * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) diff --git a/docs/attributes-registry/device.md b/docs/attributes-registry/device.md new file mode 100644 index 0000000000..3c1f06c4ea --- /dev/null +++ b/docs/attributes-registry/device.md @@ -0,0 +1,23 @@ + + +# Device + +## Device Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | +| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | +| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | +| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | + +**[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. + +**[2]:** The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. + +**[3]:** It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. + +**[4]:** It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. + diff --git a/docs/resource/device.md b/docs/resource/device.md index cfbaf9d82d..57bd6dea97 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -9,18 +9,18 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | Recommended | -| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | Recommended | -| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | Recommended | -| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | Recommended | +| [`device.id`](../attributes-registry/device.md) | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | Recommended | +| [`device.manufacturer`](../attributes-registry/device.md) | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | Recommended | +| [`device.model.identifier`](../attributes-registry/device.md) | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | Recommended | +| [`device.model.name`](../attributes-registry/device.md) | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | Recommended | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. **[2]:** The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. -**[3]:** It's recommended this value represents a machine readable version of the model identifier rather than the market or consumer-friendly name of the device. +**[3]:** It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. -**[4]:** It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. +**[4]:** It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/device.yaml b/model/registry/device.yaml new file mode 100644 index 0000000000..c109981f11 --- /dev/null +++ b/model/registry/device.yaml @@ -0,0 +1,46 @@ +groups: + - id: registry.device + prefix: device + type: attribute_group + brief: > + Describes device attributes. + attributes: + - id: id + type: string + brief: > + A unique identifier representing the device + note: > + The device identifier MUST only be defined using the values outlined below. This value is not an advertising + identifier and MUST NOT be used as such. + On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). + On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique + UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) + on best practices and exact implementation details. + Caution should be taken when storing personal data or anything which can identify a user. GDPR and + data protection laws may apply, ensure you do your own due diligence. + examples: ['2ab2916d-a51f-4ac8-80ee-45ac31a28092'] + - id: manufacturer + type: string + brief: > + The name of the device manufacturer + note: > + The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). + iOS apps SHOULD hardcode the value `Apple`. + examples: ['Apple', 'Samsung'] + - id: model.identifier + type: string + brief: > + The model identifier for the device + note: > + It's recommended this value represents a machine-readable version of + the model identifier rather than the market or consumer-friendly name + of the device. + examples: ['iPhone3,4', 'SM-G920F'] + - id: model.name + type: string + brief: > + The marketing name for the device model + note: > + It's recommended this value represents a human-readable version of the + device model rather than a machine-readable alternative. + examples: ['iPhone 6s Plus', 'Samsung Galaxy S6'] diff --git a/model/resource/device.yaml b/model/resource/device.yaml index 3df0a4d6a8..8fab02a8e4 100644 --- a/model/resource/device.yaml +++ b/model/resource/device.yaml @@ -5,37 +5,7 @@ groups: brief: > The device on which the process represented by this resource is running. attributes: - - id: id - type: string - brief: 'A unique identifier representing the device' - note: > - The device identifier MUST only be defined using the values outlined below. This value is not an advertising - identifier and MUST NOT be used as such. - On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). - On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique - UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) - on best practices and exact implementation details. - Caution should be taken when storing personal data or anything which can identify a user. GDPR and - data protection laws may apply, ensure you do your own due diligence. - examples: ['2ab2916d-a51f-4ac8-80ee-45ac31a28092'] - - id: model.identifier - type: string - brief: 'The model identifier for the device' - note: > - It's recommended this value represents a machine readable version of - the model identifier rather than the market or consumer-friendly name - of the device. - examples: ['iPhone3,4', 'SM-G920F'] - - id: model.name - type: string - brief: 'The marketing name for the device model' - note: > - It's recommended this value represents a human readable version of the - device model rather than a machine readable alternative. - examples: ['iPhone 6s Plus', 'Samsung Galaxy S6'] - - id: manufacturer - type: string - brief: 'The name of the device manufacturer' - note: > - The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. - examples: ['Apple', 'Samsung'] + - ref: device.id + - ref: device.manufacturer + - ref: device.model.identifier + - ref: device.model.name From e2952cf5a2b2e6b0a02ff3141d45706703b5a8e7 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:15:12 +0100 Subject: [PATCH 147/482] Move error namespace to the registry (#500) Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/error.md | 34 ++++++++++++++++++++++++++++++ docs/http/http-metrics.md | 12 +++++------ docs/http/http-spans.md | 2 +- model/{ => registry}/error.yaml | 16 ++++++++------ 5 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 docs/attributes-registry/error.md rename model/{ => registry}/error.yaml (69%) diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 9755685ee1..e2c02a077f 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -33,6 +33,7 @@ Currently, the following namespaces exist: * [Container](container.md) * [Destination](destination.md) * [Device](device.md) +* [Error](error.md) * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) diff --git a/docs/attributes-registry/error.md b/docs/attributes-registry/error.md new file mode 100644 index 0000000000..21e0d2c67d --- /dev/null +++ b/docs/attributes-registry/error.md @@ -0,0 +1,34 @@ + + +# Error + +## Error Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `error.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | + +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + \ No newline at end of file diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 2eee6cc7ee..f9cde0544c 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -76,7 +76,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -239,7 +239,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -341,7 +341,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | @@ -449,7 +449,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | @@ -539,7 +539,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | @@ -629,7 +629,7 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index cd1553265c..a991bf0984 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -118,7 +118,7 @@ sections below. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [3] | | [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | diff --git a/model/error.yaml b/model/registry/error.yaml similarity index 69% rename from model/error.yaml rename to model/registry/error.yaml index 1a40f32b0a..683012e361 100644 --- a/model/error.yaml +++ b/model/registry/error.yaml @@ -1,20 +1,21 @@ groups: - - id: error + - id: registry.error type: attribute_group prefix: error brief: > - This document defines the shared attributes used to - report an error. + This document defines the shared attributes used to report an error. attributes: - id: type stability: stable - brief: 'Describes a class of error the operation ended with.' + brief: > + Describes a class of error the operation ended with. type: allow_custom_values: true members: - id: other value: "_OTHER" - brief: "A fallback error value to be used when the instrumentation doesn't define a custom value." + brief: > + A fallback error value to be used when the instrumentation doesn't define a custom value. examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] note: | The `error.type` SHOULD be predictable and SHOULD have low cardinality. @@ -29,5 +30,6 @@ groups: If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to: - * Use a domain-specific attribute - * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + + * Use a domain-specific attribute + * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. From cfdcc9ee821667ca68124ae85acf98901a28a326 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Nov 2023 01:10:09 -0800 Subject: [PATCH 148/482] Add `http.flavor` and `http.user_agent` to list of deprecated attributes (#503) Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/attributes-registry/http.md | 13 +++++++++++++ model/registry/deprecated/http.yaml | 30 +++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 136e4ed089..aaedfc0100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ release. - Add `code.stacktrace` attribute ([#435](https://github.com/open-telemetry/semantic-conventions/pull/435)) +- Add `http.flavor` and `http.user_agent` to list of deprecated attributes + ([#503](https://github.com/open-telemetry/semantic-conventions/pull/503)) ### Fixes diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index ee711c7e4a..06c8568be4 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -67,6 +67,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin | Attribute | Type | Description | Examples | |---|---|---|---| +| `http.flavor` | string | Deprecated, use `network.procol.name` instead. | `1.0` | | `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | | `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | | `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | @@ -74,4 +75,16 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin | `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | | `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | | `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | +| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | + +`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/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index de45180bbd..dcd1b411a4 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -39,3 +39,33 @@ groups: brief: 'Deprecated, use `http.response.header.content-length` instead.' stability: deprecated examples: 3495 + - id: flavor + type: + 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: 'Deprecated, use `network.procol.name` instead.' + stability: deprecated + - id: user_agent + type: string + brief: 'Deprecated, use `user_agent.original` instead.' + examples: ['CERN-LineMode/2.15 libwww/2.17b3', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] + stability: deprecated From 55a6575a8ff01af4db9a6b8023640f7b5e4402ec Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Nov 2023 23:47:44 -0800 Subject: [PATCH 149/482] Update `jvm.gc.duration` histogram buckets to `[ 0.01, 0.1, 1, 10 ]` (#317) --- CHANGELOG.md | 3 +++ docs/runtime/jvm-metrics.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaedfc0100..60a2c8c822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ release. ### Breaking +- Update `jvm.gc.duration` histogram buckets to `[ 0.01, 0.1, 1, 10 ]` + ([#317](https://github.com/open-telemetry/semantic-conventions/pull/317)) + ### Features - Add `code.stacktrace` attribute diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index f36246c653..4e7825c857 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -163,7 +163,7 @@ This metric is obtained by subscribing to This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) -of `[]` (single bucket histogram capturing count, sum, min, max). +of `[ 0.01, 0.1, 1, 10 ]`. | Name | Instrument Type | Unit (UCUM) | Description | From f6fec98892f1b7a1e92b2cfff0812c40f6195c1e Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Mon, 13 Nov 2023 12:23:30 +0100 Subject: [PATCH 150/482] [model/resource] Change `host.cpu.model.family` and `host.cpu.model.id` to be strings (#499) Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/host.md | 4 ++-- model/resource/host.yaml | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60a2c8c822..f2657cb0ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ release. - Update `jvm.gc.duration` histogram buckets to `[ 0.01, 0.1, 1, 10 ]` ([#317](https://github.com/open-telemetry/semantic-conventions/pull/317)) +- BREAKING: Change type of `host.cpu.model.id` and `host.cpu.model.family` to string. + ([#495](https://github.com/open-telemetry/semantic-conventions/issues/495)) ### Features diff --git a/docs/resource/host.md b/docs/resource/host.md index f7e2286af5..3bfedb3715 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -46,8 +46,8 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | -| `host.cpu.family` | int | Numeric value specifying the family or generation of the CPU. | `6` | Opt-In | -| `host.cpu.model.id` | int | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6` | Opt-In | +| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | Opt-In | +| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | Opt-In | | `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | | `host.cpu.stepping` | int | Stepping or core revisions. | `1` | Opt-In | | `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | diff --git a/model/resource/host.yaml b/model/resource/host.yaml index 9b63976db5..9665d09c58 100644 --- a/model/resource/host.yaml +++ b/model/resource/host.yaml @@ -106,17 +106,17 @@ groups: examples: [ 'GenuineIntel' ] - id: family requirement_level: opt_in - type: int + type: string brief: > - Numeric value specifying the family or generation of the CPU. - examples: [ 6 ] + Family or generation of the CPU. + examples: [ '6', 'PA-RISC 1.1e' ] - id: model.id requirement_level: opt_in - type: int + type: string brief: > Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. - examples: [ 6 ] + examples: [ '6', '9000/778/B180L' ] - id: model.name requirement_level: opt_in type: string From 659f03c71ec4551be90bd6e230c2fcbf0e944e74 Mon Sep 17 00:00:00 2001 From: Severin Neumann Date: Mon, 13 Nov 2023 15:29:04 +0100 Subject: [PATCH 151/482] Add Semantic conventions for TLS/SSL encrypted communication (#21) Signed-off-by: svrnm Co-authored-by: Liudmila Molkova Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/tls.md | 49 +++++++++ model/registry/tls.yaml | 165 +++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 docs/attributes-registry/tls.md create mode 100644 model/registry/tls.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index f2657cb0ce..44baae1131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ release. ([#435](https://github.com/open-telemetry/semantic-conventions/pull/435)) - Add `http.flavor` and `http.user_agent` to list of deprecated attributes ([#503](https://github.com/open-telemetry/semantic-conventions/pull/503)) +- Add Semantic conventions for TLS/SSL encrypted communication. + ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) ### Fixes diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index e2c02a077f..2599410225 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -42,6 +42,7 @@ Currently, the following namespaces exist: * [Server](server.md) * [Source](source.md) * [Thread](thread.md) +* [TLS](tls.md) * [URL](url.md) * [User agent](user-agent.md) diff --git a/docs/attributes-registry/tls.md b/docs/attributes-registry/tls.md new file mode 100644 index 0000000000..f774c31a26 --- /dev/null +++ b/docs/attributes-registry/tls.md @@ -0,0 +1,49 @@ + + +# TLS + +## TLS Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `tls.cipher` | string | String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. [1] | `TLS_RSA_WITH_3DES_EDE_CBC_SHA`; `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | +| `tls.client.certificate` | string | PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. | `MII...` | +| `tls.client.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | +| `tls.client.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | +| `tls.client.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | +| `tls.client.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | +| `tls.client.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | +| `tls.client.ja3` | string | A hash that identifies clients based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | +| `tls.client.not_after` | string | Date/Time indicating when client certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | +| `tls.client.not_before` | string | Date/Time indicating when client certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | +| `tls.client.server_name` | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | +| `tls.client.subject` | string | Distinguished name of subject of the x.509 certificate presented by the client. | `CN=myclient, OU=Documentation Team, DC=example, DC=com` | +| `tls.client.supported_ciphers` | string[] | Array of ciphers offered by the client during the client hello. | `["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."]` | +| `tls.curve` | string | String indicating the curve used for the given cipher, when applicable | `secp256r1` | +| `tls.established` | boolean | Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. | `True` | +| `tls.next_protocol` | string | String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. | `http/1.1` | +| `tls.protocol.name` | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl` | +| `tls.protocol.version` | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | +| `tls.resumed` | boolean | Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. | `True` | +| `tls.server.certificate` | string | PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. | `MII...` | +| `tls.server.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | +| `tls.server.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | +| `tls.server.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | +| `tls.server.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | +| `tls.server.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | +| `tls.server.ja3s` | string | A hash that identifies servers based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | +| `tls.server.not_after` | string | Date/Time indicating when server certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | +| `tls.server.not_before` | string | Date/Time indicating when server certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | +| `tls.server.subject` | string | Distinguished name of subject of the x.509 certificate presented by the server. | `CN=myserver, OU=Documentation Team, DC=example, DC=com` | + +**[1]:** The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). + +`tls.protocol.name` 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 | +|---|---| +| `ssl` | ssl | +| `tls` | tls | + \ No newline at end of file diff --git a/model/registry/tls.yaml b/model/registry/tls.yaml new file mode 100644 index 0000000000..421479d18a --- /dev/null +++ b/model/registry/tls.yaml @@ -0,0 +1,165 @@ +groups: + - id: registry.tls + prefix: tls + type: attribute_group + brief: "This document defines semantic convention attributes in the TLS namespace." + attributes: + - id: cipher + brief: > + String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. + type: string + note: > + The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the + [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). + examples: + [ + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + ] + - id: client.certificate + type: string + brief: > + PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. + examples: ["MII..."] + - id: client.certificate_chain + type: string[] + brief: > + Array of PEM-encoded certificates that make up the certificate chain offered by the client. + This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. + examples: ["MII...", "MI..."] + - id: client.hash.md5 + type: string + brief: > + Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: ["0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"] + - id: client.hash.sha1 + type: string + brief: > + Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: ["9E393D93138888D288266C2D915214D1D1CCEB2A"] + - id: client.hash.sha256 + type: string + brief: > + Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: + ["0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"] + - id: client.issuer + type: string + brief: "Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client." + examples: + ["CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"] + - id: client.ja3 + type: string + brief: "A hash that identifies clients based on how they perform an SSL/TLS handshake." + examples: ["d4e5b18d6b55c71272893221c96ba240"] + - id: client.not_after + type: string + brief: "Date/Time indicating when client certificate is no longer considered valid." + examples: ["2021-01-01T00:00:00.000Z"] + - id: client.not_before + type: string + brief: "Date/Time indicating when client certificate is first considered valid." + examples: ["1970-01-01T00:00:00.000Z"] + - id: client.server_name + type: string + brief: "Also called an SNI, this tells the server which hostname to which the client is attempting to connect to." + examples: ["opentelemetry.io"] + - id: client.subject + type: string + brief: "Distinguished name of subject of the x.509 certificate presented by the client." + examples: ["CN=myclient, OU=Documentation Team, DC=example, DC=com"] + - id: client.supported_ciphers + type: string[] + brief: Array of ciphers offered by the client during the client hello. + examples: + [ + '"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."', + ] + - id: curve + brief: "String indicating the curve used for the given cipher, when applicable" + type: string + examples: ["secp256r1"] + - id: established + brief: "Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel." + type: boolean + examples: [true] + - id: next_protocol + brief: > + String indicating the protocol being tunneled. + Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), + this string should be lower case. + type: string + examples: ["http/1.1"] + - id: protocol.name + brief: > + Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) + type: + allow_custom_values: true + members: + - id: ssl + value: ssl + - id: tls + value: tls + - id: protocol.version + brief: > + Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) + type: string + examples: ["1.2", "3"] + - id: resumed + brief: "Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation." + type: boolean + examples: [true] + - id: server.certificate + type: string + brief: > + PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. + examples: ["MII..."] + - id: server.certificate_chain + type: string[] + brief: > + Array of PEM-encoded certificates that make up the certificate chain offered by the server. + This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. + examples: ["MII...", "MI..."] + - id: server.hash.md5 + type: string + brief: > + Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: ["0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"] + - id: server.hash.sha1 + type: string + brief: > + Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: ["9E393D93138888D288266C2D915214D1D1CCEB2A"] + - id: server.hash.sha256 + type: string + brief: > + Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. + For consistency with other hash values, this value should be formatted as an uppercase hash. + examples: + ["0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"] + - id: server.issuer + type: string + brief: "Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client." + examples: + ["CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"] + - id: server.ja3s + type: string + brief: "A hash that identifies servers based on how they perform an SSL/TLS handshake." + examples: ["d4e5b18d6b55c71272893221c96ba240"] + - id: server.not_after + type: string + brief: "Date/Time indicating when server certificate is no longer considered valid." + examples: ["2021-01-01T00:00:00.000Z"] + - id: server.not_before + type: string + brief: "Date/Time indicating when server certificate is first considered valid." + examples: ["1970-01-01T00:00:00.000Z"] + - id: server.subject + type: string + brief: "Distinguished name of subject of the x.509 certificate presented by the server." + examples: ["CN=myserver, OU=Documentation Team, DC=example, DC=com"] From 200d20f899466de9e8443def4138c8505f684897 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:16:37 +0100 Subject: [PATCH 152/482] Move host to the registry (#498) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/host.md | 44 ++++++++++ docs/resource/host.md | 32 +++---- model/registry/host.yaml | 122 +++++++++++++++++++++++++++ model/resource/host.yaml | 130 ++++------------------------- 5 files changed, 198 insertions(+), 131 deletions(-) create mode 100644 docs/attributes-registry/host.md create mode 100644 model/registry/host.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 2599410225..64a20d6acf 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -34,6 +34,7 @@ Currently, the following namespaces exist: * [Destination](destination.md) * [Device](device.md) * [Error](error.md) +* [Host](host.md) * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) diff --git a/docs/attributes-registry/host.md b/docs/attributes-registry/host.md new file mode 100644 index 0000000000..005700c2cc --- /dev/null +++ b/docs/attributes-registry/host.md @@ -0,0 +1,44 @@ + +# Host + +## Host Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | +| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | +| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | +| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | +| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | +| `host.cpu.stepping` | int | Stepping or core revisions. | `1` | +| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | +| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | +| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | +| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | +| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | +| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [2] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | +| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [3] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | +| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | +| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | + +**[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. + +**[2]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. + +**[3]:** MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + +`host.arch` 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 | +|---|---| +| `amd64` | AMD64 | +| `arm32` | ARM32 | +| `arm64` | ARM64 | +| `ia64` | Itanium | +| `ppc32` | 32-bit PowerPC | +| `ppc64` | 64-bit PowerPC | +| `s390x` | IBM z/Architecture | +| `x86` | 32-bit x86 | + \ No newline at end of file diff --git a/docs/resource/host.md b/docs/resource/host.md index 3bfedb3715..a11c735b86 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -9,18 +9,18 @@ The `host.*` namespace SHOULD be exclusively used to capture resource attributes. To report host metrics, the `system.*` namespace SHOULD be used. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | Recommended | -| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | Recommended | -| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | Recommended | -| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | -| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). | `0.1` | Recommended | -| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | Opt-In | -| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | Opt-In | -| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | -| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | +| [`host.arch`](../attributes-registry/host.md) | string | The CPU architecture the host system is running on. | `amd64` | Recommended | +| [`host.id`](../attributes-registry/host.md) | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | Recommended | +| [`host.image.id`](../attributes-registry/host.md) | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | Recommended | +| [`host.image.name`](../attributes-registry/host.md) | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | +| [`host.image.version`](../attributes-registry/host.md) | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | Recommended | +| [`host.ip`](../attributes-registry/host.md) | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | Opt-In | +| [`host.mac`](../attributes-registry/host.md) | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | Opt-In | +| [`host.name`](../attributes-registry/host.md) | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | +| [`host.type`](../attributes-registry/host.md) | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | **[1]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. @@ -45,12 +45,12 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | -| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | Opt-In | -| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | Opt-In | -| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | -| `host.cpu.stepping` | int | Stepping or core revisions. | `1` | Opt-In | -| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | +| [`host.cpu.cache.l2.size`](../attributes-registry/host.md) | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | +| [`host.cpu.family`](../attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | Opt-In | +| [`host.cpu.model.id`](../attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | Opt-In | +| [`host.cpu.model.name`](../attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | +| [`host.cpu.stepping`](../attributes-registry/host.md) | int | Stepping or core revisions. | `1` | Opt-In | +| [`host.cpu.vendor.id`](../attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. diff --git a/model/registry/host.yaml b/model/registry/host.yaml new file mode 100644 index 0000000000..fed665548e --- /dev/null +++ b/model/registry/host.yaml @@ -0,0 +1,122 @@ +groups: + - id: registry.host + prefix: host + type: attribute_group + brief: > + A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. + attributes: + - id: id + type: string + brief: > + Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. + For non-containerized systems, this should be the `machine-id`. See the table below for + the sources to use to determine the `machine-id` based on operating system. + examples: ['fdbf79e8af94cb7f9e8df36789187052'] + - id: name + type: string + brief: > + Name of the host. On Unix systems, it may contain what the hostname + command returns, or the fully qualified hostname, or another name + specified by the user. + examples: ['opentelemetry-test'] + - id: type + type: string + brief: > + Type of host. For Cloud, this must be the machine type. + examples: ['n1-standard-1'] + - id: arch + type: + allow_custom_values: true + members: + - id: amd64 + value: 'amd64' + brief: "AMD64" + - id: arm32 + value: 'arm32' + brief: "ARM32" + - id: arm64 + value: 'arm64' + brief: "ARM64" + - id: ia64 + value: 'ia64' + brief: "Itanium" + - id: ppc32 + value: 'ppc32' + brief: "32-bit PowerPC" + - id: ppc64 + value: 'ppc64' + brief: "64-bit PowerPC" + - id: s390x + value: 's390x' + brief: "IBM z/Architecture" + - id: x86 + value: 'x86' + brief: "32-bit x86" + brief: > + The CPU architecture the host system is running on. + - id: image.name + type: string + brief: > + Name of the VM image or OS install the host was instantiated from. + examples: ['infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'] + - id: image.id + type: string + brief: > + VM image ID or host OS image ID. For Cloud, this value is from the provider. + examples: ['ami-07b06b442921831e5'] + - id: image.version + type: string + brief: > + The version string of the VM image or host OS as defined in + [Version Attributes](/docs/resource/README.md#version-attributes). + examples: ['0.1'] + - id: ip + type: string[] + brief: > + Available IP addresses of the host, excluding loopback interfaces. + note: > + IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses + MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. + examples: ["192.168.1.140", "fe80::abc2:4a28:737a:609e"] + - id: mac + type: string[] + brief: > + Available MAC addresses of the host, excluding loopback interfaces. + note: > + MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): + as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + examples: ['AC-DE-48-23-45-67', 'AC-DE-48-23-45-67-01-9F'] + - id: cpu.vendor.id + type: string + brief: > + Processor manufacturer identifier. A maximum 12-character string. + note: > + [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. + Writing these to memory in this order results in a 12-character string. + examples: [ 'GenuineIntel' ] + - id: cpu.family + type: string + brief: > + Family or generation of the CPU. + examples: [ '6', 'PA-RISC 1.1e' ] + - id: cpu.model.id + type: string + brief: > + Model identifier. It provides more granular information about the CPU, distinguishing it from + other CPUs within the same family. + examples: [ '6', '9000/778/B180L' ] + - id: cpu.model.name + type: string + brief: > + Model designation of the processor. + examples: [ '11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz' ] + - id: cpu.stepping + type: int + brief: > + Stepping or core revisions. + examples: [ 1 ] + - id: cpu.cache.l2.size + type: int + brief: > + The amount of level 2 memory cache available to the processor (in Bytes). + examples: [ 12288000 ] diff --git a/model/resource/host.yaml b/model/resource/host.yaml index 9665d09c58..b90b90dcf7 100644 --- a/model/resource/host.yaml +++ b/model/resource/host.yaml @@ -5,89 +5,17 @@ groups: brief: > A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. attributes: - - id: id - type: string - brief: > - Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. - For non-containerized systems, this should be the `machine-id`. See the table below for - the sources to use to determine the `machine-id` based on operating system. - examples: ['fdbf79e8af94cb7f9e8df36789187052'] - - id: name - type: string - brief: > - Name of the host. On Unix systems, it may contain what the hostname - command returns, or the fully qualified hostname, or another name - specified by the user. - examples: ['opentelemetry-test'] - - id: type - type: string - brief: > - Type of host. For Cloud, this must be the machine type. - examples: ['n1-standard-1'] - - id: arch - type: - allow_custom_values: true - members: - - id: amd64 - value: 'amd64' - brief: "AMD64" - - id: arm32 - value: 'arm32' - brief: "ARM32" - - id: arm64 - value: 'arm64' - brief: "ARM64" - - id: ia64 - value: 'ia64' - brief: "Itanium" - - id: ppc32 - value: 'ppc32' - brief: "32-bit PowerPC" - - id: ppc64 - value: 'ppc64' - brief: "64-bit PowerPC" - - id: s390x - value: 's390x' - brief: "IBM z/Architecture" - - id: x86 - value: 'x86' - brief: "32-bit x86" - brief: > - The CPU architecture the host system is running on. - - id: image.name - type: string - brief: > - Name of the VM image or OS install the host was instantiated from. - examples: ['infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'] - - id: image.id - type: string - brief: > - VM image ID or host OS image ID. For Cloud, this value is from the provider. - examples: ['ami-07b06b442921831e5'] - - id: image.version - type: string - brief: > - The version string of the VM image or host OS as defined in - [Version Attributes](README.md#version-attributes). - examples: ['0.1'] - - id: ip - type: string[] + - ref: host.id + - ref: host.name + - ref: host.type + - ref: host.arch + - ref: host.image.name + - ref: host.image.id + - ref: host.image.version + - ref: host.ip requirement_level: opt_in - brief: > - Available IP addresses of the host, excluding loopback interfaces. - note: > - IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses - MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. - examples: ["192.168.1.140", "fe80::abc2:4a28:737a:609e"] - - id: mac - type: string[] + - ref: host.mac requirement_level: opt_in - brief: > - Available MAC addresses of the host, excluding loopback interfaces. - note: > - MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): - as hyphen-separated octets in uppercase hexadecimal form from most to least significant. - examples: ['AC-DE-48-23-45-67', 'AC-DE-48-23-45-67-01-9F'] - id: host.cpu prefix: host.cpu @@ -95,43 +23,15 @@ groups: brief: > A host's CPU information attributes: - - id: vendor.id + - ref: host.cpu.vendor.id requirement_level: opt_in - type: string - brief: > - Processor manufacturer identifier. A maximum 12-character string. - note: > - [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. - Writing these to memory in this order results in a 12-character string. - examples: [ 'GenuineIntel' ] - - id: family + - ref: host.cpu.family requirement_level: opt_in - type: string - brief: > - Family or generation of the CPU. - examples: [ '6', 'PA-RISC 1.1e' ] - - id: model.id + - ref: host.cpu.model.id requirement_level: opt_in - type: string - brief: > - Model identifier. It provides more granular information about the CPU, distinguishing it from - other CPUs within the same family. - examples: [ '6', '9000/778/B180L' ] - - id: model.name + - ref: host.cpu.model.name requirement_level: opt_in - type: string - brief: > - Model designation of the processor. - examples: [ '11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz' ] - - id: stepping + - ref: host.cpu.stepping requirement_level: opt_in - type: int - brief: > - Stepping or core revisions. - examples: [ 1 ] - - id: cache.l2.size + - ref: host.cpu.cache.l2.size requirement_level: opt_in - type: int - brief: > - The amount of level 2 memory cache available to the processor (in Bytes). - examples: [ 12288000 ] From 68457cbe7a748b95a4946ce9cbd09ca0fdb8997c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 13 Nov 2023 07:21:01 -0800 Subject: [PATCH 153/482] Fix typo (#507) Co-authored-by: Joao Grassi --- docs/attributes-registry/http.md | 2 +- model/registry/deprecated/http.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 06c8568be4..2f9481a64c 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -67,7 +67,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin | Attribute | Type | Description | Examples | |---|---|---|---| -| `http.flavor` | string | Deprecated, use `network.procol.name` instead. | `1.0` | +| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0` | | `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | | `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | | `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | diff --git a/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index dcd1b411a4..9150328629 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -61,7 +61,7 @@ groups: - id: quic value: 'QUIC' brief: 'QUIC protocol.' - brief: 'Deprecated, use `network.procol.name` instead.' + brief: 'Deprecated, use `network.protocol.name` instead.' stability: deprecated - id: user_agent type: string From d9c24b436e996ef42314556cd7830873c8305fba Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:43:28 +0100 Subject: [PATCH 154/482] move OS to registry (#501) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/os.md | 32 ++++++++++++++ docs/resource/os.md | 12 +++--- model/registry/os.yaml | 69 ++++++++++++++++++++++++++++++ model/resource/os.yaml | 63 +++------------------------ 5 files changed, 113 insertions(+), 64 deletions(-) create mode 100644 docs/attributes-registry/os.md create mode 100644 model/registry/os.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 64a20d6acf..be97468451 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -38,6 +38,7 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [Network](network.md) * [OCI](oci.md) +* [OS](os.md) * [Process](process.md) * [RPC](rpc.md) * [Server](server.md) diff --git a/docs/attributes-registry/os.md b/docs/attributes-registry/os.md new file mode 100644 index 0000000000..a813298f98 --- /dev/null +++ b/docs/attributes-registry/os.md @@ -0,0 +1,32 @@ + +# OS + +## Operating System Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | +| `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | +| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | +| `os.type` | string | The operating system type. | `windows` | +| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | + +`os.type` 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 | +|---|---| +| `windows` | Microsoft Windows | +| `linux` | Linux | +| `darwin` | Apple Darwin | +| `freebsd` | FreeBSD | +| `netbsd` | NetBSD | +| `openbsd` | OpenBSD | +| `dragonflybsd` | DragonFly BSD | +| `hpux` | HP-UX (Hewlett Packard Unix) | +| `aix` | AIX (Advanced Interactive eXecutive) | +| `solaris` | SunOS, Oracle Solaris | +| `z_os` | IBM z/OS | + \ No newline at end of file diff --git a/docs/resource/os.md b/docs/resource/os.md index 542b61ad2a..4b681018d9 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -8,14 +8,14 @@ In case of virtualized environments, this is the operating system as it is observed by the process, i.e., the virtualized guest rather than the underlying host. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | -| `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | Recommended | -| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | Recommended | -| `os.type` | string | The operating system type. | `windows` | Required | -| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | Recommended | +| [`os.build_id`](../attributes-registry/os.md) | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | +| [`os.description`](../attributes-registry/os.md) | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | Recommended | +| [`os.name`](../attributes-registry/os.md) | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | Recommended | +| [`os.type`](../attributes-registry/os.md) | string | The operating system type. | `windows` | Required | +| [`os.version`](../attributes-registry/os.md) | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | Recommended | `os.type` 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. diff --git a/model/registry/os.yaml b/model/registry/os.yaml new file mode 100644 index 0000000000..af8dbfcd2a --- /dev/null +++ b/model/registry/os.yaml @@ -0,0 +1,69 @@ +groups: + - id: registry.os + prefix: os + type: attribute_group + brief: > + The operating system (OS) on which the process represented by this resource is running. + note: > + In case of virtualized environments, this is the operating system as it is observed by + the process, i.e., the virtualized guest rather than the underlying host. + attributes: + - id: type + type: + allow_custom_values: true + members: + - id: windows + value: 'windows' + brief: "Microsoft Windows" + - id: linux + value: 'linux' + brief: "Linux" + - id: darwin + value: 'darwin' + brief: "Apple Darwin" + - id: freebsd + value: 'freebsd' + brief: "FreeBSD" + - id: netbsd + value: 'netbsd' + brief: "NetBSD" + - id: openbsd + value: 'openbsd' + brief: "OpenBSD" + - id: dragonflybsd + value: 'dragonflybsd' + brief: "DragonFly BSD" + - id: hpux + value: 'hpux' + brief: "HP-UX (Hewlett Packard Unix)" + - id: aix + value: 'aix' + brief: "AIX (Advanced Interactive eXecutive)" + - id: solaris + value: 'solaris' + brief: "SunOS, Oracle Solaris" + - id: z_os + value: 'z_os' + brief: "IBM z/OS" + brief: > + The operating system type. + - id: description + type: string + brief: > + Human readable (not intended to be parsed) OS version information, + like e.g. reported by `ver` or `lsb_release -a` commands. + examples: ['Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'] + - id: name + type: string + brief: 'Human readable operating system name.' + examples: ['iOS', 'Android', 'Ubuntu'] + - id: version + type: string + brief: > + The version string of the operating system as defined in + [Version Attributes](/docs/resource/README.md#version-attributes). + examples: ['14.2.1', '18.04.1'] + - id: build_id + type: string + brief: 'Unique identifier for a particular build or compilation of the operating system.' + examples: ['TQ3C.230805.001.B2', '20E247', '22621'] diff --git a/model/resource/os.yaml b/model/resource/os.yaml index 78636f8461..772fdde3a0 100644 --- a/model/resource/os.yaml +++ b/model/resource/os.yaml @@ -8,62 +8,9 @@ groups: In case of virtualized environments, this is the operating system as it is observed by the process, i.e., the virtualized guest rather than the underlying host. attributes: - - id: type - type: - allow_custom_values: true - members: - - id: windows - value: 'windows' - brief: "Microsoft Windows" - - id: linux - value: 'linux' - brief: "Linux" - - id: darwin - value: 'darwin' - brief: "Apple Darwin" - - id: freebsd - value: 'freebsd' - brief: "FreeBSD" - - id: netbsd - value: 'netbsd' - brief: "NetBSD" - - id: openbsd - value: 'openbsd' - brief: "OpenBSD" - - id: dragonflybsd - value: 'dragonflybsd' - brief: "DragonFly BSD" - - id: hpux - value: 'hpux' - brief: "HP-UX (Hewlett Packard Unix)" - - id: aix - value: 'aix' - brief: "AIX (Advanced Interactive eXecutive)" - - id: solaris - value: 'solaris' - brief: "SunOS, Oracle Solaris" - - id: z_os - value: 'z_os' - brief: "IBM z/OS" + - ref: os.type requirement_level: required - brief: 'The operating system type.' - - id: description - type: string - brief: > - Human readable (not intended to be parsed) OS version information, - like e.g. reported by `ver` or `lsb_release -a` commands. - examples: ['Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'] - - id: name - type: string - brief: 'Human readable operating system name.' - examples: ['iOS', 'Android', 'Ubuntu'] - - id: version - type: string - brief: > - The version string of the operating system as defined in - [Version Attributes](/docs/resource/README.md#version-attributes). - examples: ['14.2.1', '18.04.1'] - - id: build_id - type: string - brief: 'Unique identifier for a particular build or compilation of the operating system.' - examples: ['TQ3C.230805.001.B2', '20E247', '22621'] + - ref: os.description + - ref: os.name + - ref: os.version + - ref: os.build_id From 30ea09f5c45718d93e30bb96ad53ada2a6003b13 Mon Sep 17 00:00:00 2001 From: Anna Levenberg Date: Mon, 13 Nov 2023 11:53:26 -0500 Subject: [PATCH 155/482] docs(messaging): add gcp_pubsub as a messaging system (#490) Co-authored-by: Johannes Tax Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/attributes-registry/messaging.md | 2 +- docs/messaging/README.md | 1 + docs/messaging/gcp-pubsub.md | 13 +++++++++++++ docs/messaging/messaging-spans.md | 2 +- model/registry/messaging.yaml | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 docs/messaging/gcp-pubsub.md diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 98dbb97aad..27bbae84c4 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -36,7 +36,7 @@ | `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | | `messaging.rocketmq.message.type` | string | Type of message. | `normal` | | `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | -| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | +| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq` | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. diff --git a/docs/messaging/README.md b/docs/messaging/README.md index 3d0a28ea6e..39b488e05e 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -20,5 +20,6 @@ Technology specific semantic conventions are defined for the following messaging * [Kafka](kafka.md): Semantic Conventions for *Apache Kafka*. * [RabbitMQ](rabbitmq.md): Semantic Conventions for *RabbitMQ*. * [RocketMQ](rocketmq.md): Semantic Conventions for *Apache RocketMQ*. +* [Google Cloud Pub/Sub](gcp-pubsub.md): Semantic Conventions for *Google Cloud Pub/Sub*. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md new file mode 100644 index 0000000000..848f144fc3 --- /dev/null +++ b/docs/messaging/gcp-pubsub.md @@ -0,0 +1,13 @@ + + +# Semantic Conventions for Google Cloud Pub/Sub + +**Status**: [Experimental][DocumentStatus] + +The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) extend and override the [Messaging Semantic Conventions](README.md) that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. + +`messaging.system` MUST be set to `"gcp_pubsub"`. + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 29097e37b4..fa95e8c3b2 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -287,7 +287,7 @@ messages were received). For each message it accounts for, the "Deliver" or | [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | | [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | | [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [15] | `publish` | Required | -| [`messaging.system`](../attributes-registry/messaging.md) | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq`; `AmazonSQS` | Required | +| [`messaging.system`](../attributes-registry/messaging.md) | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 4487cd14ca..f7dd6257ab 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -205,4 +205,4 @@ groups: - id: system type: string brief: 'A string identifying the messaging system.' - examples: ['kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'] + examples: ['kafka', 'rabbitmq', 'rocketmq', 'activemq'] From 4f89cd7848749156f530857f5960777d1ea62812 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 14 Nov 2023 05:26:14 -0600 Subject: [PATCH 156/482] [.github/CODEOWNERS] Add semconv container/k8s approvers (#510) Signed-off-by: ChrsMark Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Alexander Wert --- .github/CODEOWNERS | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8210e3eff6..b1af3939c0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -45,4 +45,17 @@ /docs/mobile/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-mobile-approvers /model/logs/mobile* @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-mobile-approvers -# TODO - Add semconv area experts +# K8s semantic conventions approvers +/docs/resource/k8s.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers +/docs/attributes-registry/k8s.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers +/model/resource/k8s.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers +/model/registry/k8s.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers + +# Container semantic conventions approvers +/docs/resource/container.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +/docs/attributes-registry/container.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +/docs/attributes-registry/oci.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +/model/resource/container.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +/model/registry/container.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +/model/registry/oci.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers + From d30d7fc021fd61a500c2ebf58da97146893f0b48 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 14 Nov 2023 06:39:49 -0600 Subject: [PATCH 157/482] Fix process registry (#515) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/attributes-registry/process.md | 3 +++ docs/resource/process.md | 6 +++--- model/registry/process.yaml | 18 ++++++++++++++++++ model/resource/process.yaml | 21 +++------------------ 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 5f70408a5e..edef9364bd 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -16,4 +16,7 @@ | `process.owner` | string | The username of the user that owns the process. | `root` | | `process.parent_pid` | int | Parent Process identifier (PID). | `111` | | `process.pid` | int | Process identifier (PID). | `1234` | +| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | +| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | +| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | diff --git a/docs/resource/process.md b/docs/resource/process.md index e2c77194e9..b3817f34df 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -62,9 +62,9 @@ In that case it MUST be interpreted as if it was `process.command_args`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | Recommended | -| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | Recommended | -| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | Recommended | +| [`process.runtime.description`](../attributes-registry/process.md) | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | Recommended | +| [`process.runtime.name`](../attributes-registry/process.md) | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | Recommended | +| [`process.runtime.version`](../attributes-registry/process.md) | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | Recommended | How to set these attributes for particular runtime kinds is described in the following subsections. diff --git a/model/registry/process.yaml b/model/registry/process.yaml index 894d09899e..f85a94f56b 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -58,3 +58,21 @@ groups: brief: > The username of the user that owns the process. examples: 'root' + - id: runtime.name + type: string + brief: > + The name of the runtime of this process. For compiled native binaries, + this SHOULD be the name of the compiler. + examples: ['OpenJDK Runtime Environment'] + - id: runtime.version + type: string + brief: > + The version of the runtime of this process, as returned by the runtime + without modification. + examples: '14.0.2' + - id: runtime.description + type: string + brief: > + An additional description about the runtime of the process, for example + a specific vendor customization of the runtime environment. + examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' diff --git a/model/resource/process.yaml b/model/resource/process.yaml index 54b141cc6d..61223d61ce 100644 --- a/model/resource/process.yaml +++ b/model/resource/process.yaml @@ -37,21 +37,6 @@ groups: brief: > The single (language) runtime instance which is monitored. attributes: - - id: name - type: string - brief: > - The name of the runtime of this process. For compiled native binaries, - this SHOULD be the name of the compiler. - examples: ['OpenJDK Runtime Environment'] - - id: version - type: string - brief: > - The version of the runtime of this process, as returned by the runtime - without modification. - examples: '14.0.2' - - id: description - type: string - brief: > - An additional description about the runtime of the process, for example - a specific vendor customization of the runtime environment. - examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' + - ref: process.runtime.name + - ref: process.runtime.version + - ref: process.runtime.description From 711776a05949a7d1db313b253552f9b7464aa4de Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 15 Nov 2023 02:23:46 -0600 Subject: [PATCH 158/482] Move k8s atrributes to the registry (#506) Signed-off-by: ChrsMark Co-authored-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/k8s.md | 52 ++++++++++ docs/resource/k8s.md | 42 ++++---- model/registry/k8s.yaml | 140 ++++++++++++++++++++++++++ model/resource/k8s.yaml | 154 ++++------------------------- 5 files changed, 235 insertions(+), 154 deletions(-) create mode 100644 docs/attributes-registry/k8s.md create mode 100644 model/registry/k8s.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index be97468451..40c63bf9f5 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -36,6 +36,7 @@ Currently, the following namespaces exist: * [Error](error.md) * [Host](host.md) * [HTTP](http.md) +* [K8s](k8s.md) * [Network](network.md) * [OCI](oci.md) * [OS](os.md) diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md new file mode 100644 index 0000000000..5778085ae8 --- /dev/null +++ b/docs/attributes-registry/k8s.md @@ -0,0 +1,52 @@ +# Kubernetes + +## Kubernetes Resource Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | +| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | +| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | Recommended | +| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | Recommended | +| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | Recommended | +| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | Recommended | +| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | Recommended | +| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | Recommended | +| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | Recommended | +| `k8s.node.name` | string | The name of the Node. | `node-1` | Recommended | +| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | +| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | +| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | +| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | Recommended | +| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | + +**[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever +added, we will recommend collecting the `k8s.cluster.uid` through the +official APIs. In the meantime, we are able to use the `uid` of the +`kube-system` namespace as a proxy for cluster ID. Read on for the +rationale. + +Every object created in a K8s cluster is assigned a distinct UID. The +`kube-system` namespace is used by Kubernetes itself and will exist +for the lifetime of the cluster. Using the `uid` of the `kube-system` +namespace is a reasonable proxy for the K8s ClusterID as it will only +change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are +UUIDs as standardized by +[ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). +Which states: + +> If generated according to one of the mechanisms defined in Rec. + ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + different from all other UUIDs generated before 3603 A.D., or is + extremely likely to be different (depending on the mechanism chosen). + +Therefore, UIDs between clusters should be extremely unlikely to +conflict. + diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index 5692ce3132..2c68757953 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -24,8 +24,8 @@ Kubernetes object, but "name" is usually more user friendly so can be also set. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | -| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | +| [`k8s.cluster.name`](../attributes-registry/k8s.md) | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | +| [`k8s.cluster.uid`](../attributes-registry/k8s.md) | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the @@ -60,8 +60,8 @@ conflict. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.node.name` | string | The name of the Node. | `node-1` | Recommended | -| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | +| [`k8s.node.name`](../attributes-registry/k8s.md) | string | The name of the Node. | `node-1` | Recommended | +| [`k8s.node.uid`](../attributes-registry/k8s.md) | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | ## Namespace @@ -76,7 +76,7 @@ a namespace, but not across namespaces. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | Recommended | +| [`k8s.namespace.name`](../attributes-registry/k8s.md) | string | The name of the namespace that the pod is running in. | `default` | Recommended | ## Pod @@ -91,8 +91,8 @@ containers on your cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | -| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | +| [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Container @@ -111,8 +111,8 @@ to a running container. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | Recommended | -| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | Recommended | +| [`k8s.container.name`](../attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | Recommended | +| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | Recommended | ## ReplicaSet @@ -127,8 +127,8 @@ any given time. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | -| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.replicaset.name`](../attributes-registry/k8s.md) | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | +| [`k8s.replicaset.uid`](../attributes-registry/k8s.md) | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Deployment @@ -144,8 +144,8 @@ distributed among the nodes of a cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | Recommended | -| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.deployment.name`](../attributes-registry/k8s.md) | string | The name of the Deployment. | `opentelemetry` | Recommended | +| [`k8s.deployment.uid`](../attributes-registry/k8s.md) | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## StatefulSet @@ -160,8 +160,8 @@ about the ordering and uniqueness of these Pods. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | Recommended | -| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.statefulset.name`](../attributes-registry/k8s.md) | string | The name of the StatefulSet. | `opentelemetry` | Recommended | +| [`k8s.statefulset.uid`](../attributes-registry/k8s.md) | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## DaemonSet @@ -175,8 +175,8 @@ A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | Recommended | -| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.daemonset.name`](../attributes-registry/k8s.md) | string | The name of the DaemonSet. | `opentelemetry` | Recommended | +| [`k8s.daemonset.uid`](../attributes-registry/k8s.md) | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## Job @@ -191,8 +191,8 @@ successfully terminate. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | Recommended | -| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.job.name`](../attributes-registry/k8s.md) | string | The name of the Job. | `opentelemetry` | Recommended | +| [`k8s.job.uid`](../attributes-registry/k8s.md) | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | ## CronJob @@ -206,8 +206,8 @@ A CronJob creates Jobs on a repeating schedule. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | Recommended | -| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| [`k8s.cronjob.name`](../attributes-registry/k8s.md) | string | The name of the CronJob. | `opentelemetry` | Recommended | +| [`k8s.cronjob.uid`](../attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml new file mode 100644 index 0000000000..c42744cb21 --- /dev/null +++ b/model/registry/k8s.yaml @@ -0,0 +1,140 @@ +groups: + - id: registry.k8s + prefix: k8s + type: resource + brief: > + Kubernetes resource attributes. + attributes: + - id: cluster.name + type: string + brief: > + The name of the cluster. + examples: ['opentelemetry-cluster'] + - id: cluster.uid + type: string + brief: > + A pseudo-ID for the cluster, set to the UID of the `kube-system` + namespace. + note: | + K8s doesn't have support for obtaining a cluster ID. If this is ever + added, we will recommend collecting the `k8s.cluster.uid` through the + official APIs. In the meantime, we are able to use the `uid` of the + `kube-system` namespace as a proxy for cluster ID. Read on for the + rationale. + + Every object created in a K8s cluster is assigned a distinct UID. The + `kube-system` namespace is used by Kubernetes itself and will exist + for the lifetime of the cluster. Using the `uid` of the `kube-system` + namespace is a reasonable proxy for the K8s ClusterID as it will only + change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are + UUIDs as standardized by + [ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). + Which states: + + > If generated according to one of the mechanisms defined in Rec. + ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + different from all other UUIDs generated before 3603 A.D., or is + extremely likely to be different (depending on the mechanism chosen). + + Therefore, UIDs between clusters should be extremely unlikely to + conflict. + examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - id: node.name + type: string + brief: > + The name of the Node. + examples: ['node-1'] + - id: node.uid + type: string + brief: > + The UID of the Node. + examples: ['1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'] + - id: namespace.name + type: string + brief: > + The name of the namespace that the pod is running in. + examples: ['default'] + - id: pod.uid + type: string + brief: > + The UID of the Pod. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: pod.name + type: string + brief: > + The name of the Pod. + examples: ['opentelemetry-pod-autoconf'] + - id: container.name + type: string + brief: > + The name of the Container from Pod specification, must be unique + within a Pod. Container runtime usually uses different globally unique + name (`container.name`). + examples: ['redis'] + - id: container.restart_count + type: int + brief: > + Number of times the container was restarted. This attribute can be + used to identify a particular container (running or stopped) within a + container spec. + examples: [0, 2] + - id: replicaset.uid + type: string + brief: > + The UID of the ReplicaSet. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: replicaset.name + type: string + brief: > + The name of the ReplicaSet. + examples: ['opentelemetry'] + - id: deployment.uid + type: string + brief: > + The UID of the Deployment. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: deployment.name + type: string + brief: > + The name of the Deployment. + examples: ['opentelemetry'] + - id: statefulset.uid + type: string + brief: > + The UID of the StatefulSet. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: statefulset.name + type: string + brief: > + The name of the StatefulSet. + examples: ['opentelemetry'] + - id: daemonset.uid + type: string + brief: > + The UID of the DaemonSet. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: daemonset.name + type: string + brief: > + The name of the DaemonSet. + examples: ['opentelemetry'] + - id: job.uid + type: string + brief: > + The UID of the Job. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: job.name + type: string + brief: > + The name of the Job. + examples: ['opentelemetry'] + - id: cronjob.uid + type: string + brief: > + The UID of the CronJob. + examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] + - id: cronjob.name + type: string + brief: > + The name of the CronJob. + examples: ['opentelemetry'] diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index ac353625ea..20947c8a93 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -5,40 +5,8 @@ groups: brief: > A Kubernetes Cluster. attributes: - - id: name - type: string - brief: > - The name of the cluster. - examples: ['opentelemetry-cluster'] - - id: uid - type: string - brief: > - A pseudo-ID for the cluster, set to the UID of the `kube-system` - namespace. - note: | - K8s doesn't have support for obtaining a cluster ID. If this is ever - added, we will recommend collecting the `k8s.cluster.uid` through the - official APIs. In the meantime, we are able to use the `uid` of the - `kube-system` namespace as a proxy for cluster ID. Read on for the - rationale. - - Every object created in a K8s cluster is assigned a distinct UID. The - `kube-system` namespace is used by Kubernetes itself and will exist - for the lifetime of the cluster. Using the `uid` of the `kube-system` - namespace is a reasonable proxy for the K8s ClusterID as it will only - change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are - UUIDs as standardized by - [ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). - Which states: - - > If generated according to one of the mechanisms defined in Rec. - ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be - different from all other UUIDs generated before 3603 A.D., or is - extremely likely to be different (depending on the mechanism chosen). - - Therefore, UIDs between clusters should be extremely unlikely to - conflict. - examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - ref: k8s.cluster.name + - ref: k8s.cluster.uid - id: k8s.node prefix: k8s.node @@ -46,16 +14,8 @@ groups: brief: > A Kubernetes Node object. attributes: - - id: name - type: string - brief: > - The name of the Node. - examples: ['node-1'] - - id: uid - type: string - brief: > - The UID of the Node. - examples: ['1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'] + - ref: k8s.node.name + - ref: k8s.node.uid - id: k8s.namespace prefix: k8s.namespace @@ -63,11 +23,7 @@ groups: brief: > A Kubernetes Namespace. attributes: - - id: name - type: string - brief: > - The name of the namespace that the pod is running in. - examples: ['default'] + - ref: k8s.namespace.name - id: k8s.pod prefix: k8s.pod @@ -75,16 +31,8 @@ groups: brief: > A Kubernetes Pod object. attributes: - - id: uid - type: string - brief: > - The UID of the Pod. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the Pod. - examples: ['opentelemetry-pod-autoconf'] + - ref: k8s.pod.uid + - ref: k8s.pod.name - id: k8s.container prefix: k8s.container @@ -92,20 +40,8 @@ groups: brief: > A container in a [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates). attributes: - - id: name - type: string - brief: > - The name of the Container from Pod specification, must be unique - within a Pod. Container runtime usually uses different globally unique - name (`container.name`). - examples: ['redis'] - - id: restart_count - type: int - brief: > - Number of times the container was restarted. This attribute can be - used to identify a particular container (running or stopped) within a - container spec. - examples: [0, 2] + - ref: k8s.container.name + - ref: k8s.container.restart_count - id: k8s.replicaset prefix: k8s.replicaset @@ -113,16 +49,8 @@ groups: brief: > A Kubernetes ReplicaSet object. attributes: - - id: uid - type: string - brief: > - The UID of the ReplicaSet. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the ReplicaSet. - examples: ['opentelemetry'] + - ref: k8s.replicaset.uid + - ref: k8s.replicaset.name - id: k8s.deployment prefix: k8s.deployment @@ -130,16 +58,8 @@ groups: brief: > A Kubernetes Deployment object. attributes: - - id: uid - type: string - brief: > - The UID of the Deployment. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the Deployment. - examples: ['opentelemetry'] + - ref: k8s.deployment.uid + - ref: k8s.deployment.name - id: k8s.statefulset prefix: k8s.statefulset @@ -147,16 +67,8 @@ groups: brief: > A Kubernetes StatefulSet object. attributes: - - id: uid - type: string - brief: > - The UID of the StatefulSet. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the StatefulSet. - examples: ['opentelemetry'] + - ref: k8s.statefulset.uid + - ref: k8s.statefulset.name - id: k8s.daemonset prefix: k8s.daemonset @@ -164,16 +76,8 @@ groups: brief: > A Kubernetes DaemonSet object. attributes: - - id: uid - type: string - brief: > - The UID of the DaemonSet. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the DaemonSet. - examples: ['opentelemetry'] + - ref: k8s.daemonset.uid + - ref: k8s.daemonset.name - id: k8s.job prefix: k8s.job @@ -181,16 +85,8 @@ groups: brief: > A Kubernetes Job object. attributes: - - id: uid - type: string - brief: > - The UID of the Job. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the Job. - examples: ['opentelemetry'] + - ref: k8s.job.uid + - ref: k8s.job.name - id: k8s.cronjob prefix: k8s.cronjob @@ -198,13 +94,5 @@ groups: brief: > A Kubernetes CronJob object. attributes: - - id: uid - type: string - brief: > - The UID of the CronJob. - examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - - id: name - type: string - brief: > - The name of the CronJob. - examples: ['opentelemetry'] + - ref: k8s.cronjob.uid + - ref: k8s.cronjob.name From a4c60f7464eb84d581819b9d0181d9c0433f471b Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Wed, 15 Nov 2023 13:30:29 +0100 Subject: [PATCH 159/482] Updated CODEOWNERS for http-approvers (#516) Co-authored-by: Joao Grassi --- .github/CODEOWNERS | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b1af3939c0..72eac076ba 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -34,6 +34,21 @@ # HTTP semantic conventions approvers /model/metrics/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers /model/trace/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/http.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/server.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/client.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/network.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/error.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/url.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/model/registry/user-agent.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/http/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/http.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/server.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/client.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/network.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/error.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/url.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers +/docs/attribute-registry/user-agent.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers # System semantic conventions approvers /docs/system/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers From 971383f4a59878fe28a4c4c5213ed0eabd67a9d0 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 16 Nov 2023 13:41:39 +0100 Subject: [PATCH 160/482] Changed `messaging.system` attribute type to an open enum (#517) Signed-off-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/attributes-registry/messaging.md | 17 +++++++++++- docs/messaging/messaging-spans.md | 17 +++++++++++- model/registry/messaging.yaml | 38 ++++++++++++++++++++++++--- 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44baae1131..21cbd4c1bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ release. ([#317](https://github.com/open-telemetry/semantic-conventions/pull/317)) - BREAKING: Change type of `host.cpu.model.id` and `host.cpu.model.family` to string. ([#495](https://github.com/open-telemetry/semantic-conventions/issues/495)) +- Changed `messaging.system` attribute type to an open enum + ([#517](https://github.com/open-telemetry/semantic-conventions/pull/517)) ### Features diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 27bbae84c4..fe5523c85d 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -36,7 +36,7 @@ | `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | | `messaging.rocketmq.message.type` | string | Type of message. | `normal` | | `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | -| `messaging.system` | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq` | +| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -82,4 +82,19 @@ size should be used. | `fifo` | FIFO message | | `delay` | Delay message | | `transaction` | Transaction message | + +`messaging.system` 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 | +|---|---| +| `activemq` | Apache ActiveMQ | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | +| `azure_eventgrid` | Azure Event Grid | +| `azure_eventhubs` | Azure Event Hubs | +| `azure_servicebus` | Azure Service Bus | +| `gcp_pubsub` | Google Cloud Pub/Sub | +| `jms` | Java Message Service | +| `kafka` | Apache Kafka | +| `rabbitmq` | RabbitMQ | +| `rocketmq` | Apache RocketMQ | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index fa95e8c3b2..19cfbc43e1 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -287,7 +287,7 @@ messages were received). For each message it accounts for, the "Deliver" or | [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | | [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | | [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [15] | `publish` | Required | -| [`messaging.system`](../attributes-registry/messaging.md) | string | A string identifying the messaging system. | `kafka`; `rabbitmq`; `rocketmq`; `activemq` | Required | +| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | @@ -352,6 +352,21 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | | `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +`messaging.system` 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 | +|---|---| +| `activemq` | Apache ActiveMQ | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | +| `azure_eventgrid` | Azure Event Grid | +| `azure_eventhubs` | Azure Event Hubs | +| `azure_servicebus` | Azure Service Bus | +| `gcp_pubsub` | Google Cloud Pub/Sub | +| `jms` | Java Message Service | +| `kafka` | Apache Kafka | +| `rabbitmq` | RabbitMQ | +| `rocketmq` | Apache RocketMQ | + `network.transport` 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 | diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index f7dd6257ab..64dc6fe5a0 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -203,6 +203,38 @@ groups: Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' - id: system - type: string - brief: 'A string identifying the messaging system.' - examples: ['kafka', 'rabbitmq', 'rocketmq', 'activemq'] + brief: > + An identifier for the messaging system being used. See below for a list of well-known identifiers. + type: + allow_custom_values: true + members: + - id: activemq + value: 'activemq' + brief: 'Apache ActiveMQ' + - id: aws_sqs + value: 'aws_sqs' + brief: 'Amazon Simple Queue Service (SQS)' + - id: azure_eventgrid + value: 'azure_eventgrid' + brief: 'Azure Event Grid' + - id: azure_eventhubs + value: 'azure_eventhubs' + brief: 'Azure Event Hubs' + - id: azure_servicebus + value: 'azure_servicebus' + brief: 'Azure Service Bus' + - id: gcp_pubsub + value: 'gcp_pubsub' + brief: 'Google Cloud Pub/Sub' + - id: jms + value: 'jms' + brief: 'Java Message Service' + - id: kafka + value: 'kafka' + brief: 'Apache Kafka' + - id: rabbitmq + value: 'rabbitmq' + brief: 'RabbitMQ' + - id: rocketmq + value: 'rocketmq' + brief: 'Apache RocketMQ' From 2817a7fa5b5d230f70314fdf425e1c468163f1e0 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 16 Nov 2023 17:53:14 +0100 Subject: [PATCH 161/482] Temp fix for separation of resource and semantic attributes (#524) Signed-off-by: Alexander Wert Co-authored-by: Josh Suereth --- model/registry/cloud.yaml | 2 +- model/registry/container.yaml | 2 +- model/registry/device.yaml | 2 +- model/registry/host.yaml | 2 +- model/registry/oci.yaml | 2 +- model/registry/os.yaml | 2 +- model/registry/process.yaml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml index 695bf64719..2c669052e8 100644 --- a/model/registry/cloud.yaml +++ b/model/registry/cloud.yaml @@ -1,7 +1,7 @@ groups: - id: registry.cloud prefix: cloud - type: attribute_group + type: resource brief: > A cloud environment (e.g. GCP, Azure, AWS). attributes: diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 6909fe4ecb..0755d078af 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -1,7 +1,7 @@ groups: - id: registry.container prefix: container - type: attribute_group + type: resource brief: > A container instance. attributes: diff --git a/model/registry/device.yaml b/model/registry/device.yaml index c109981f11..6eaf8e3b5e 100644 --- a/model/registry/device.yaml +++ b/model/registry/device.yaml @@ -1,7 +1,7 @@ groups: - id: registry.device prefix: device - type: attribute_group + type: resource brief: > Describes device attributes. attributes: diff --git a/model/registry/host.yaml b/model/registry/host.yaml index fed665548e..3deb5f5707 100644 --- a/model/registry/host.yaml +++ b/model/registry/host.yaml @@ -1,7 +1,7 @@ groups: - id: registry.host prefix: host - type: attribute_group + type: resource brief: > A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. attributes: diff --git a/model/registry/oci.yaml b/model/registry/oci.yaml index 24e0cb93f2..45e2838796 100644 --- a/model/registry/oci.yaml +++ b/model/registry/oci.yaml @@ -1,7 +1,7 @@ groups: - id: registry.oci.manifest prefix: oci.manifest - type: attribute_group + type: resource brief: > An OCI image manifest. attributes: diff --git a/model/registry/os.yaml b/model/registry/os.yaml index af8dbfcd2a..5b699b1faf 100644 --- a/model/registry/os.yaml +++ b/model/registry/os.yaml @@ -1,7 +1,7 @@ groups: - id: registry.os prefix: os - type: attribute_group + type: resource brief: > The operating system (OS) on which the process represented by this resource is running. note: > diff --git a/model/registry/process.yaml b/model/registry/process.yaml index f85a94f56b..dd26c09b77 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -1,7 +1,7 @@ groups: - id: registry.process prefix: process - type: attribute_group + type: resource brief: > An operating system process. attributes: From 56071a86427836bf725470663611a7200ff23341 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 22 Jul 2020 11:30:11 -0700 Subject: [PATCH 162/482] Centralize attributes definition (#722) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Centralize attributes definition Signed-off-by: Bogdan Drutu * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/overview.md Co-authored-by: Christian Neumüller Co-authored-by: Christian Neumüller --- specification/common/common.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 specification/common/common.md diff --git a/specification/common/common.md b/specification/common/common.md new file mode 100644 index 0000000000..b8d99a5eef --- /dev/null +++ b/specification/common/common.md @@ -0,0 +1,29 @@ +# Common specification concepts + +

+ +Table of Contents + + +- [Attributes](#attribute) + +
+ +## Attributes + +Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have the following properties: + +- The attribute key, which MUST be a non-`null` and non-empty string. +- The attribute value, which is either: + - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. + - An array of primitive type values. The array MUST be homogeneous, + i.e. it MUST NOT contain values of different types. For protocols that do + not natively support array values such values SHOULD be represented as JSON strings. + +`null` values within arrays MUST be preserved as-is (i.e., passed on to span +processors / exporters as `null`). If exporters do not support exporting `null` +values, they MAY replace those values by 0, `false`, or empty strings. +This is required for map/dictionary structures represented as two arrays with +indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, +both containing an array of strings to represent a mapping +`header_keys[i] -> header_values[i]`). From c82cc039d7d4ab2908034fa49be2c9e76814185b Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jul 2020 10:51:44 -0700 Subject: [PATCH 163/482] DocFX sanity check (#742) --- specification/common/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index b8d99a5eef..b55f47c1bb 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -5,7 +5,7 @@ Table of Contents -- [Attributes](#attribute) +- [Attributes](#attributes) From 19fced8d4f5051ca50110ba87aae32a7eb92391f Mon Sep 17 00:00:00 2001 From: Giovanni Liva Date: Thu, 13 Aug 2020 19:10:46 +0200 Subject: [PATCH 164/482] Consistency between Span and Resource attributes (#777) * Consistency between Span and Resource attributes * Address feedback * Wording --- specification/common/common.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index b55f47c1bb..681721fb11 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -20,6 +20,15 @@ Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have i.e. it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. +Attributes SHOULD preserve the order in which they're set. + +Attribute values expressing a numerical value of zero, an empty string, or an +empty array are considered meaningful and MUST be stored and passed on to +processors / exporters. Attribute values of `null` are considered to be not set +and get discarded as if that `Attribute` has never been created. +As an exception to this, if overwriting of values is supported, this results in +removing the attribute. + `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. From 795086a9a596b54ffc4e280d6dae91abc382b4c4 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 17 Aug 2020 12:40:17 -0400 Subject: [PATCH 165/482] Add conventions for attribute names (#807) * Add conventions for attribute names Resolves: https://github.com/open-telemetry/opentelemetry-specification/issues/726 * Address PR comments * Re-word company/application specific attribute recommendations --- specification/common/common.md | 88 +++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index 681721fb11..62637d5ec9 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -6,7 +6,7 @@ Table of Contents - [Attributes](#attributes) - + - [Attribute Naming](#attribute-naming) ## Attributes @@ -36,3 +36,89 @@ This is required for map/dictionary structures represented as two arrays with indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). + +### Attribute Naming + +Attribute name (also known as the "attribute key") MUST be a valid Unicode +sequence. + +Attribute names SHOULD follow these rules: + +- Use namespacing to avoid name clashes. Delimit the namespaces using a dot + character. For example `service.version` denotes the service version where + `service` is the namespace and `version` is an attribute in that namespace. + +- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside + top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute + inside `telemetry.sdk` namespace. + +- For each multi-word dot-delimited component of the attribute name separate the + words by underscores (i.e. use snake_case). For example `http.status_code` + denotes the status code in the http namespace. + +- Attribute names SHOULD NOT coincide with namespaces. For example if + `service.instance.id` is an attribute name then it is no longer valid to have + an attribute named `service.instance` because `service.instance` is already a + namespace. Because of this rule be careful when choosing attribute names: + every existing attribute name prohibits existence of an equally named + namespace in the future, and vice versa: any existing namespace prohibits + existence of an equally named attribute in the future. + +#### Recommendations for OpenTelemetry Authors + +- All attribute names that are part of OpenTelemetry semantic conventions + SHOULD be part of a namespace. + +- When coming up with a new convention make sure to check existing namespaces + for + [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), + [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), + and + [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) + to see if the new attributes fits. + +- When a new namespace is necessary consider whether it should be a top-level + namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). + +- Semantic conventions MUST limit attribute names to printable Basic Latin + characters (more precisely to + [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) + subset of Unicode code points). It is recommended to further limit attribute + names to the following Unicode code points: Latin alphabet, Numeric, + Underscore, Dot (as namespace delimiter). + +#### Recommendations for Application Developers + +As an application developer when you need to record an attribute first consult +existing semantic conventions for +[Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), +[Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), +and +[Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). +If appropriate attribute name does not exists you will need to come up with a +new name. To do that consider a few options: + +- The attribute is specific to your company and may be possibly used outside the + company as well. To avoid name clashes with attributes introduced by other + companies (in a distributed system that uses applications from multiple + vendors) it is recommended to prefix the attribute name by your company's + reverse domain name, e.g. `com.acme.shopname`. + +- The attribute is specific to your application that will be used internally + only. If you already have an internal company process that helps you to ensure + no name clashes happen then feel free to follow it. Otherwise it is + recommended to prefix the attribute name by your application name, provided + that the application name is reasonably unique within your organization (e.g. + `myuniquemapapp.longitude` is likely fine). Make sure the application name + does not clash with an existing semantic convention namespace. + +- The attribute may be generally applicable to applications in the industry. In + that case consider submitting a proposal to this specification to add a new + attribute to the semantic conventions, if necessary also to add a new + namespace for the attribute. + +It is recommended to limit attribute names to printable Basic Latin characters +(more precisely to +[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) +subset of Unicode code points). + From 2096cb3ec5061046df8f98148af1c4ddab645a2b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 19 Aug 2020 13:49:28 -0400 Subject: [PATCH 166/482] Extend attribute naming rules to metric labels (#821) * Extend attribute naming rules to metric labels We earlier defined naming rules for attributes, however we do not have similar rules for metric labels. This commit extends the exact same set of rules to metric labels. This was brought up in this comment https://github.com/open-telemetry/opentelemetry-specification/pull/807#discussion_r471550053 * Address PR comments --- specification/common/common.md | 95 +++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 62637d5ec9..7cedad5f3f 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -6,7 +6,7 @@ Table of Contents - [Attributes](#attributes) - - [Attribute Naming](#attribute-naming) + - [Attribute and Label Naming](#attribute-and-label-naming) ## Attributes @@ -37,12 +37,22 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -### Attribute Naming +## Attribute and Label Naming -Attribute name (also known as the "attribute key") MUST be a valid Unicode -sequence. +_This section applies to Resource, Span and Log attribute names (also known as +the "attribute keys") and to keys of Metric labels. For brevity within this +section when we use the term "name" without an adjective it is implied to mean +"attribute name or metric label key"._ -Attribute names SHOULD follow these rules: +Every name MUST be a valid Unicode sequence. + +_Note: we merely require that the names are represented as Unicode sequences. +This specification does not define how exactly the Unicode sequences are +encoded. The encoding can vary from one programming language to another and from +one wire format to another. Use the idiomatic way to represent Unicode in the +particular programming language or wire format._ + +Names SHOULD follow these rules: - Use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example `service.version` denotes the service version where @@ -56,68 +66,67 @@ Attribute names SHOULD follow these rules: words by underscores (i.e. use snake_case). For example `http.status_code` denotes the status code in the http namespace. -- Attribute names SHOULD NOT coincide with namespaces. For example if +- Names SHOULD NOT coincide with namespaces. For example if `service.instance.id` is an attribute name then it is no longer valid to have an attribute named `service.instance` because `service.instance` is already a - namespace. Because of this rule be careful when choosing attribute names: - every existing attribute name prohibits existence of an equally named - namespace in the future, and vice versa: any existing namespace prohibits - existence of an equally named attribute in the future. + namespace. Because of this rule be careful when choosing names: every existing + name prohibits existence of an equally named namespace in the future, and vice + versa: any existing namespace prohibits existence of an equally named + attribute or label key in the future. -#### Recommendations for OpenTelemetry Authors +### Recommendations for OpenTelemetry Authors -- All attribute names that are part of OpenTelemetry semantic conventions - SHOULD be part of a namespace. +- All names that are part of OpenTelemetry semantic conventions SHOULD be part + of a namespace. -- When coming up with a new convention make sure to check existing namespaces - for +- When coming up with a new semantic convention make sure to check existing + namespaces for [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), and [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) - to see if the new attributes fits. + to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). -- Semantic conventions MUST limit attribute names to printable Basic Latin - characters (more precisely to +- Semantic conventions MUST limit names to printable Basic Latin characters + (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) - subset of Unicode code points). It is recommended to further limit attribute - names to the following Unicode code points: Latin alphabet, Numeric, - Underscore, Dot (as namespace delimiter). + subset of Unicode code points). It is recommended to further limit names to + the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot + (as namespace delimiter). -#### Recommendations for Application Developers +### Recommendations for Application Developers -As an application developer when you need to record an attribute first consult -existing semantic conventions for +As an application developer when you need to record an attribute or a label +first consult existing semantic conventions for [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), and [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). -If appropriate attribute name does not exists you will need to come up with a -new name. To do that consider a few options: - -- The attribute is specific to your company and may be possibly used outside the - company as well. To avoid name clashes with attributes introduced by other - companies (in a distributed system that uses applications from multiple - vendors) it is recommended to prefix the attribute name by your company's - reverse domain name, e.g. `com.acme.shopname`. - -- The attribute is specific to your application that will be used internally - only. If you already have an internal company process that helps you to ensure - no name clashes happen then feel free to follow it. Otherwise it is - recommended to prefix the attribute name by your application name, provided - that the application name is reasonably unique within your organization (e.g. +If an appropriate name does not exists you will need to come up with a new name. +To do that consider a few options: + +- The name is specific to your company and may be possibly used outside the + company as well. To avoid clashes with names introduced by other companies (in + a distributed system that uses applications from multiple vendors) it is + recommended to prefix the new name by your company's reverse domain name, e.g. + `com.acme.shopname`. + +- The name is specific to your application that will be used internally only. If + you already have an internal company process that helps you to ensure no name + clashes happen then feel free to follow it. Otherwise it is recommended to + prefix the attribute name or label key by your application name, provided that + the application name is reasonably unique within your organization (e.g. `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. -- The attribute may be generally applicable to applications in the industry. In - that case consider submitting a proposal to this specification to add a new - attribute to the semantic conventions, if necessary also to add a new - namespace for the attribute. +- The name may be generally applicable to applications in the industry. In that + case consider submitting a proposal to this specification to add a new name to + the semantic conventions, and if necessary also to add a new namespace. -It is recommended to limit attribute names to printable Basic Latin characters +It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). From 52061e2f521387e447bb7b1cfaf5d6c10a60a41d Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 19 Aug 2020 14:43:05 -0700 Subject: [PATCH 167/482] Fix lint check in makefile, fix errors (#837) Signed-off-by: Bogdan Drutu --- specification/common/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index 7cedad5f3f..f6a917b4cf 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,6 +7,7 @@ Table of Contents - [Attributes](#attributes) - [Attribute and Label Naming](#attribute-and-label-naming) + ## Attributes @@ -130,4 +131,3 @@ It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). - From a59a1b218c6d26ab3832a01bcf1cd4fc1246dcf3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 24 Aug 2020 13:14:37 -0400 Subject: [PATCH 168/482] Require that names and namespaces are one global space across all semantic convention areas (#832) * Require that names and namespaces are one global space across all semantic convention areas We have semantic conventions for Resources, Spans and Metrics (in the future also Logs are expected). It was not clear if the attribute names across all convention areas should be globally unique. This commit asserts that conventions are one space, they are not independent spaces with their own namespaces each. We prohibit using the same Span or Resource attribute name or metric label name but give them slightly different meanings or value sets. Resolves: https://github.com/open-telemetry/opentelemetry-specification/issues/815 * Address PR comments Co-authored-by: Bogdan Drutu --- specification/common/common.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index f6a917b4cf..44f5ccf2f5 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -91,6 +91,15 @@ Names SHOULD follow these rules: - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). +- Semantic conventions exist for four areas: for Resource, Span and Log + attribute names as well as Metric label keys. In addition, for spans we have + two more areas: Event and Link attribute names. Identical namespaces or names + in all these areas MUST have identical meanings. For example the `http.method` + span attribute name denotes exactly the same concept as the `http.method` + metric label, has the same data type and the same set of possible values (in + both cases it records the value of the HTTP protocol's request method as a + string). + - Semantic conventions MUST limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) From aa5effe43c77f58c2e0226f6d3456f8f6e06c7c2 Mon Sep 17 00:00:00 2001 From: Armin Ruech Date: Fri, 25 Sep 2020 11:49:15 +0200 Subject: [PATCH 169/482] Define `null` as an invalid value for attributes and declare attempts to set `null` as undefined behavior (#992) --- specification/common/common.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 44f5ccf2f5..974cf51821 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -25,10 +25,10 @@ Attributes SHOULD preserve the order in which they're set. Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to -processors / exporters. Attribute values of `null` are considered to be not set -and get discarded as if that `Attribute` has never been created. -As an exception to this, if overwriting of values is supported, this results in -removing the attribute. +processors / exporters. + +Attribute values of `null` are not valid and attempting to set a `null` value is +undefined behavior. `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` From 2d55f5436f93d88908ebbad5144dc2a74228d291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 4 Nov 2020 21:29:48 +0100 Subject: [PATCH 170/482] Fix absolute links to spec (#1192) * Remove absolute links where possible. * Work around semantic conventions. * Docfx. * Fix YAML. * More docfx. --- specification/common/common.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 974cf51821..0352f819ab 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -82,10 +82,10 @@ Names SHOULD follow these rules: - When coming up with a new semantic convention make sure to check existing namespaces for - [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), - [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), + [Resources](../resource/semantic_conventions/README.md), + [Spans](../trace/semantic_conventions/README.md), and - [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) + [Metrics](../metrics/semantic_conventions/README.md) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level @@ -111,10 +111,10 @@ Names SHOULD follow these rules: As an application developer when you need to record an attribute or a label first consult existing semantic conventions for -[Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), -[Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), +[Resources](../resource/semantic_conventions/README.md), +[Spans](../trace/semantic_conventions/README.md), and -[Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). +[Metrics](../metrics/semantic_conventions/README.md). If an appropriate name does not exists you will need to come up with a new name. To do that consider a few options: From 550a2b904b4580180e37bd4ef711f48ba66c74ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 10 Nov 2020 17:05:58 +0100 Subject: [PATCH 171/482] Remove ordering reqirement for attributes. (#1212) * Remove ordering for attributes. * Fill in CHANGELOG link --- specification/common/common.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 0352f819ab..fca4b007a1 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -21,8 +21,6 @@ Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have i.e. it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. -Attributes SHOULD preserve the order in which they're set. - Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. From 01e5a6d827d2ba18b26410a1de6386b4d56e2a50 Mon Sep 17 00:00:00 2001 From: Przemek Maciolek <58699843+pmm-sumo@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:19:52 +0100 Subject: [PATCH 172/482] Include attribute name pluralization guidelines (#1115) (#1140) --- specification/common/common.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index fca4b007a1..3a759e09e0 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,6 +7,9 @@ Table of Contents - [Attributes](#attributes) - [Attribute and Label Naming](#attribute-and-label-naming) + - [Name Pluralization Guidelines](#name-pluralization-guidelines) + - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) + - [Recommendations for Application Developers](#recommendations-for-application-developers) @@ -72,6 +75,19 @@ Names SHOULD follow these rules: name prohibits existence of an equally named namespace in the future, and vice versa: any existing namespace prohibits existence of an equally named attribute or label key in the future. + +### Name Pluralization guidelines + +- When an attribute represents a single entity, the attribute name SHOULD be singular. + Examples: `host.name`, `db.user`, `container.id`. + +- When attribute can represent multiple entities, the attribute name SHOULD be pluralized + and the value type SHOULD be an array. E.g. `process.command_args` might include multiple + values: the executable name and command arguments. + +- When an attribute represents a measurement, + [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + SHOULD be followed for the attribute name. ### Recommendations for OpenTelemetry Authors From fb0804ed305920e65ddc56807865c9ae95eb7a44 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:51:16 -0500 Subject: [PATCH 173/482] Add guidance on when to use and not use nested namespaces (#1197) This topic has come up at least 3 times now. I believe a clarification is warranted. The clarification is aligned with previous recommendations: https://github.com/open-telemetry/opentelemetry-specification/pull/789#issuecomment-675506855 https://github.com/open-telemetry/opentelemetry-specification/pull/882#issuecomment-690945900 https://github.com/open-telemetry/opentelemetry-specification/pull/1194#issuecomment-722431982 --- specification/common/common.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 3a759e09e0..15d25304c4 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -63,6 +63,10 @@ Names SHOULD follow these rules: - Namespaces can be nested. For example `telemetry.sdk` is a namespace inside top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute inside `telemetry.sdk` namespace. + Note: the fact that an entity is located within another entity is typically + not a sufficient reason for forming nested namespaces. The purpose of a + namespace is to avoid name clashes, not to indicate entity hierarchies. This + purpose should primarily drive the decision about forming nested namespaces. - For each multi-word dot-delimited component of the attribute name separate the words by underscores (i.e. use snake_case). For example `http.status_code` From 1cbb4af73d55710bba5905e2e725ed17b18ac3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 11 Nov 2020 02:15:41 +0100 Subject: [PATCH 174/482] Nulls SHOULD NOT be allowed in arrays. (#1214) * Nulls SHOULD NOT be allowed in arrays. * Fill in CHANGELOG link Co-authored-by: Armin Ruech --- specification/common/common.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 15d25304c4..f1526b9518 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -31,6 +31,9 @@ processors / exporters. Attribute values of `null` are not valid and attempting to set a `null` value is undefined behavior. +`null` values SHOULD NOT be allowed in arrays. However, if it is impossible to +make sure that no `null` values are accepted +(e.g. in languages that do not have appropriate compile-time type checking), `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. From e8587bacc85f1ab7dca1de7defe2a8eca3e13777 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 17 Nov 2020 16:41:56 -0500 Subject: [PATCH 175/482] Declare freeze of Trace API Specification 1.0 (#1121) * Declare freeze of Trace Specification 1.0 We want to freeze Trace specification 1.0 so that we no longer accept substantial changes (unless a fundamental problem is found in the spec). Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/1120 --- .../common/attribute-and-label-naming.md | 130 ++++++++++++++++++ specification/common/common.md | 126 +---------------- 2 files changed, 133 insertions(+), 123 deletions(-) create mode 100644 specification/common/attribute-and-label-naming.md diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md new file mode 100644 index 0000000000..d84eab4c62 --- /dev/null +++ b/specification/common/attribute-and-label-naming.md @@ -0,0 +1,130 @@ +# Attribute and Label Naming + +
+ +Table of Contents + + +- [Name Pluralization Guidelines](#name-pluralization-guidelines) +- [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) +- [Recommendations for Application Developers](#recommendations-for-application-developers) + +
+ +_This section applies to Resource, Span and Log attribute names (also known as +the "attribute keys") and to keys of Metric labels. For brevity within this +section when we use the term "name" without an adjective it is implied to mean +"attribute name or metric label key"._ + +Every name MUST be a valid Unicode sequence. + +_Note: we merely require that the names are represented as Unicode sequences. +This specification does not define how exactly the Unicode sequences are +encoded. The encoding can vary from one programming language to another and from +one wire format to another. Use the idiomatic way to represent Unicode in the +particular programming language or wire format._ + +Names SHOULD follow these rules: + +- Use namespacing to avoid name clashes. Delimit the namespaces using a dot + character. For example `service.version` denotes the service version where + `service` is the namespace and `version` is an attribute in that namespace. + +- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside + top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute + inside `telemetry.sdk` namespace. + Note: the fact that an entity is located within another entity is typically + not a sufficient reason for forming nested namespaces. The purpose of a + namespace is to avoid name clashes, not to indicate entity hierarchies. This + purpose should primarily drive the decision about forming nested namespaces. + +- For each multi-word dot-delimited component of the attribute name separate the + words by underscores (i.e. use snake_case). For example `http.status_code` + denotes the status code in the http namespace. + +- Names SHOULD NOT coincide with namespaces. For example if + `service.instance.id` is an attribute name then it is no longer valid to have + an attribute named `service.instance` because `service.instance` is already a + namespace. Because of this rule be careful when choosing names: every existing + name prohibits existence of an equally named namespace in the future, and vice + versa: any existing namespace prohibits existence of an equally named + attribute or label key in the future. + +## Name Pluralization guidelines + +- When an attribute represents a single entity, the attribute name SHOULD be singular. + Examples: `host.name`, `db.user`, `container.id`. + +- When attribute can represent multiple entities, the attribute name SHOULD be pluralized + and the value type SHOULD be an array. E.g. `process.command_args` might include multiple + values: the executable name and command arguments. + +- When an attribute represents a measurement, + [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + SHOULD be followed for the attribute name. + +## Recommendations for OpenTelemetry Authors + +- All names that are part of OpenTelemetry semantic conventions SHOULD be part + of a namespace. + +- When coming up with a new semantic convention make sure to check existing + namespaces for + [Resources](../resource/semantic_conventions/README.md), + [Spans](../trace/semantic_conventions/README.md), + and + [Metrics](../metrics/semantic_conventions/README.md) + to see if the new name fits. + +- When a new namespace is necessary consider whether it should be a top-level + namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). + +- Semantic conventions exist for four areas: for Resource, Span and Log + attribute names as well as Metric label keys. In addition, for spans we have + two more areas: Event and Link attribute names. Identical namespaces or names + in all these areas MUST have identical meanings. For example the `http.method` + span attribute name denotes exactly the same concept as the `http.method` + metric label, has the same data type and the same set of possible values (in + both cases it records the value of the HTTP protocol's request method as a + string). + +- Semantic conventions MUST limit names to printable Basic Latin characters + (more precisely to + [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) + subset of Unicode code points). It is recommended to further limit names to + the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot + (as namespace delimiter). + +## Recommendations for Application Developers + +As an application developer when you need to record an attribute or a label +first consult existing semantic conventions for +[Resources](../resource/semantic_conventions/README.md), +[Spans](../trace/semantic_conventions/README.md), +and +[Metrics](../metrics/semantic_conventions/README.md). +If an appropriate name does not exists you will need to come up with a new name. +To do that consider a few options: + +- The name is specific to your company and may be possibly used outside the + company as well. To avoid clashes with names introduced by other companies (in + a distributed system that uses applications from multiple vendors) it is + recommended to prefix the new name by your company's reverse domain name, e.g. + `com.acme.shopname`. + +- The name is specific to your application that will be used internally only. If + you already have an internal company process that helps you to ensure no name + clashes happen then feel free to follow it. Otherwise it is recommended to + prefix the attribute name or label key by your application name, provided that + the application name is reasonably unique within your organization (e.g. + `myuniquemapapp.longitude` is likely fine). Make sure the application name + does not clash with an existing semantic convention namespace. + +- The name may be generally applicable to applications in the industry. In that + case consider submitting a proposal to this specification to add a new name to + the semantic conventions, and if necessary also to add a new namespace. + +It is recommended to limit names to printable Basic Latin characters +(more precisely to +[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) +subset of Unicode code points). diff --git a/specification/common/common.md b/specification/common/common.md index f1526b9518..51ce946c48 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -1,15 +1,13 @@ # Common specification concepts +**Status**: [Feature-freeze](../document-status.md). +
Table of Contents - [Attributes](#attributes) - - [Attribute and Label Naming](#attribute-and-label-naming) - - [Name Pluralization Guidelines](#name-pluralization-guidelines) - - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - - [Recommendations for Application Developers](#recommendations-for-application-developers)
@@ -42,122 +40,4 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -## Attribute and Label Naming - -_This section applies to Resource, Span and Log attribute names (also known as -the "attribute keys") and to keys of Metric labels. For brevity within this -section when we use the term "name" without an adjective it is implied to mean -"attribute name or metric label key"._ - -Every name MUST be a valid Unicode sequence. - -_Note: we merely require that the names are represented as Unicode sequences. -This specification does not define how exactly the Unicode sequences are -encoded. The encoding can vary from one programming language to another and from -one wire format to another. Use the idiomatic way to represent Unicode in the -particular programming language or wire format._ - -Names SHOULD follow these rules: - -- Use namespacing to avoid name clashes. Delimit the namespaces using a dot - character. For example `service.version` denotes the service version where - `service` is the namespace and `version` is an attribute in that namespace. - -- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside - top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute - inside `telemetry.sdk` namespace. - Note: the fact that an entity is located within another entity is typically - not a sufficient reason for forming nested namespaces. The purpose of a - namespace is to avoid name clashes, not to indicate entity hierarchies. This - purpose should primarily drive the decision about forming nested namespaces. - -- For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.status_code` - denotes the status code in the http namespace. - -- Names SHOULD NOT coincide with namespaces. For example if - `service.instance.id` is an attribute name then it is no longer valid to have - an attribute named `service.instance` because `service.instance` is already a - namespace. Because of this rule be careful when choosing names: every existing - name prohibits existence of an equally named namespace in the future, and vice - versa: any existing namespace prohibits existence of an equally named - attribute or label key in the future. - -### Name Pluralization guidelines - -- When an attribute represents a single entity, the attribute name SHOULD be singular. - Examples: `host.name`, `db.user`, `container.id`. - -- When attribute can represent multiple entities, the attribute name SHOULD be pluralized - and the value type SHOULD be an array. E.g. `process.command_args` might include multiple - values: the executable name and command arguments. - -- When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) - SHOULD be followed for the attribute name. - -### Recommendations for OpenTelemetry Authors - -- All names that are part of OpenTelemetry semantic conventions SHOULD be part - of a namespace. - -- When coming up with a new semantic convention make sure to check existing - namespaces for - [Resources](../resource/semantic_conventions/README.md), - [Spans](../trace/semantic_conventions/README.md), - and - [Metrics](../metrics/semantic_conventions/README.md) - to see if the new name fits. - -- When a new namespace is necessary consider whether it should be a top-level - namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). - -- Semantic conventions exist for four areas: for Resource, Span and Log - attribute names as well as Metric label keys. In addition, for spans we have - two more areas: Event and Link attribute names. Identical namespaces or names - in all these areas MUST have identical meanings. For example the `http.method` - span attribute name denotes exactly the same concept as the `http.method` - metric label, has the same data type and the same set of possible values (in - both cases it records the value of the HTTP protocol's request method as a - string). - -- Semantic conventions MUST limit names to printable Basic Latin characters - (more precisely to - [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) - subset of Unicode code points). It is recommended to further limit names to - the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot - (as namespace delimiter). - -### Recommendations for Application Developers - -As an application developer when you need to record an attribute or a label -first consult existing semantic conventions for -[Resources](../resource/semantic_conventions/README.md), -[Spans](../trace/semantic_conventions/README.md), -and -[Metrics](../metrics/semantic_conventions/README.md). -If an appropriate name does not exists you will need to come up with a new name. -To do that consider a few options: - -- The name is specific to your company and may be possibly used outside the - company as well. To avoid clashes with names introduced by other companies (in - a distributed system that uses applications from multiple vendors) it is - recommended to prefix the new name by your company's reverse domain name, e.g. - `com.acme.shopname`. - -- The name is specific to your application that will be used internally only. If - you already have an internal company process that helps you to ensure no name - clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name or label key by your application name, provided that - the application name is reasonably unique within your organization (e.g. - `myuniquemapapp.longitude` is likely fine). Make sure the application name - does not clash with an existing semantic convention namespace. - -- The name may be generally applicable to applications in the industry. In that - case consider submitting a proposal to this specification to add a new name to - the semantic conventions, and if necessary also to add a new namespace. - -It is recommended to limit names to printable Basic Latin characters -(more precisely to -[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) -subset of Unicode code points). +See [Attribute and Label Naming](attribute-and-label-naming.md) for naming guidelines. From 7a3f37d933250f54fed68a7c61563db7832bdc68 Mon Sep 17 00:00:00 2001 From: Ted Young Date: Thu, 4 Feb 2021 06:06:46 -0800 Subject: [PATCH 176/482] Add lifecycle statuses to all documents (#1385) --- specification/common/attribute-and-label-naming.md | 2 ++ specification/common/common.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md index d84eab4c62..0a9e3356e8 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-and-label-naming.md @@ -1,5 +1,7 @@ # Attribute and Label Naming +**Status**: [Experimental](../document-status.md) +
Table of Contents diff --git a/specification/common/common.md b/specification/common/common.md index 51ce946c48..203a25b912 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -1,6 +1,6 @@ # Common specification concepts -**Status**: [Feature-freeze](../document-status.md). +**Status**: [Stable, Feature-freeze](../document-status.md)
From 71df386e08283f0b4e76d3ceae2e4f3bfdcc2cdd Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 28 Apr 2021 10:38:46 -0400 Subject: [PATCH 177/482] Clarify usage of "otel." attribute namespace (#1640) I noticed developers adding their own attributes to this namespace without going through the specification. We need to regulate this namespace through the specification, just like we do it for other semantic conventions. --- specification/common/attribute-and-label-naming.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md index 0a9e3356e8..6ebe80ed2f 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-and-label-naming.md @@ -130,3 +130,17 @@ It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). + +## otel.* Namespace + +Attribute and label names that start with `otel.` are reserved to be defined by +OpenTelemetry specification. These are typically used to express OpenTelemetry +concepts in formats that don't have a corresponding concept. + +For example, the `otel.library.name` attribute is used to record the +instrumentation library name, which is an OpenTelemetry concept that is natively +represented in OTLP, but does not have an equivalent in other telemetry formats +and protocols. + +Any additions to the `otel.*` namespace MUST be approved as part of +OpenTelemetry specification. From dcf74c311addc4aedaa46d08df5f56e0b2df006b Mon Sep 17 00:00:00 2001 From: Jakub Malinowski Date: Thu, 1 Jul 2021 00:11:54 +0200 Subject: [PATCH 178/482] Rename Metrics labels to attributes (#1775) --- ...nd-label-naming.md => attribute-naming.md} | 36 +++++++++---------- specification/common/common.md | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) rename specification/common/{attribute-and-label-naming.md => attribute-naming.md} (84%) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-naming.md similarity index 84% rename from specification/common/attribute-and-label-naming.md rename to specification/common/attribute-naming.md index 6ebe80ed2f..6599f6b239 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-naming.md @@ -1,4 +1,4 @@ -# Attribute and Label Naming +# Attribute Naming **Status**: [Experimental](../document-status.md) @@ -13,10 +13,9 @@ Table of Contents
-_This section applies to Resource, Span and Log attribute names (also known as -the "attribute keys") and to keys of Metric labels. For brevity within this -section when we use the term "name" without an adjective it is implied to mean -"attribute name or metric label key"._ +_This section applies to Resource, Span, Log, and Metric attribute names (also +known as the "attribute keys"). For brevity within this section when we use the +term "name" without an adjective it is implied to mean "attribute name"._ Every name MUST be a valid Unicode sequence. @@ -50,8 +49,8 @@ Names SHOULD follow these rules: namespace. Because of this rule be careful when choosing names: every existing name prohibits existence of an equally named namespace in the future, and vice versa: any existing namespace prohibits existence of an equally named - attribute or label key in the future. - + attribute key in the future. + ## Name Pluralization guidelines - When an attribute represents a single entity, the attribute name SHOULD be singular. @@ -81,14 +80,13 @@ Names SHOULD follow these rules: - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). -- Semantic conventions exist for four areas: for Resource, Span and Log - attribute names as well as Metric label keys. In addition, for spans we have - two more areas: Event and Link attribute names. Identical namespaces or names - in all these areas MUST have identical meanings. For example the `http.method` - span attribute name denotes exactly the same concept as the `http.method` - metric label, has the same data type and the same set of possible values (in - both cases it records the value of the HTTP protocol's request method as a - string). +- Semantic conventions exist for four areas: for Resource, Span, Log, and Metric + attribute names. In addition, for spans we have two more areas: Event and Link + attribute names. Identical namespaces or names in all these areas MUST have + identical meanings. For example the `http.method` span attribute name denotes + exactly the same concept as the `http.method` metric attribute, has the same + data type and the same set of possible values (in both cases it records the + value of the HTTP protocol's request method as a string). - Semantic conventions MUST limit names to printable Basic Latin characters (more precisely to @@ -99,8 +97,8 @@ Names SHOULD follow these rules: ## Recommendations for Application Developers -As an application developer when you need to record an attribute or a label -first consult existing semantic conventions for +As an application developer when you need to record an attribute first consult +existing semantic conventions for [Resources](../resource/semantic_conventions/README.md), [Spans](../trace/semantic_conventions/README.md), and @@ -117,7 +115,7 @@ To do that consider a few options: - The name is specific to your application that will be used internally only. If you already have an internal company process that helps you to ensure no name clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name or label key by your application name, provided that + prefix the attribute name by your application name, provided that the application name is reasonably unique within your organization (e.g. `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. @@ -133,7 +131,7 @@ subset of Unicode code points). ## otel.* Namespace -Attribute and label names that start with `otel.` are reserved to be defined by +Attribute names that start with `otel.` are reserved to be defined by OpenTelemetry specification. These are typically used to express OpenTelemetry concepts in formats that don't have a corresponding concept. diff --git a/specification/common/common.md b/specification/common/common.md index 203a25b912..1b34c4f9f8 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -40,4 +40,4 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -See [Attribute and Label Naming](attribute-and-label-naming.md) for naming guidelines. +See [Attribute Naming](attribute-naming.md) for naming guidelines. From 2ecdb1f1a2a195442368d56f74cbb05c143e28e9 Mon Sep 17 00:00:00 2001 From: Jakub Malinowski Date: Wed, 4 Aug 2021 00:26:10 +0200 Subject: [PATCH 179/482] Add an option to limit length of values of attributes and metric values (#1130) --- specification/common/common.md | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 1b34c4f9f8..6cb26c12f9 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -8,6 +8,8 @@ Table of Contents
- [Attributes](#attributes) + - [Attribute Limits](#attribute-limits) + - [Exempt Entities](#exempt-entities)
@@ -41,3 +43,52 @@ both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). See [Attribute Naming](attribute-naming.md) for naming guidelines. + +### Attribute Limits + +Execution of erroneous code can result in unintended attributes. If there are no +limits placed on attributes, they can quickly exhaust available memory, resulting +in crashes that are difficult to recover from safely. + +By default an SDK SHOULD apply truncation as per the list of +[configurable parameters](#attribute-limits-configuration) below. + +If an SDK provides a way to: + +- set an attribute value length limit such that for each + attribute value: + - if it is a string, if it exceeds that limit (counting any character in it as + 1), SDKs MUST truncate that value, so that its length is at most equal + to the limit, + - if it is an array of strings, then apply the above rule to each of the + values separately, + - otherwise a value MUST NOT be truncated; +- set a limit of unique attribute keys such that: + - for each unique attributes key, addition of which would result in exceeding + the limit, SDK MUST discard that key/value pair. + +There MAY be a log emitted to indicate to the user that an attribute was +truncated or discarded. To prevent excessive logging, the log MUST NOT be +emitted more than once per record on which an attribute is set. + +If the SDK implements the limits above, it MUST provide a way to change these +limits programmatically. Names of the configuration options SHOULD be the same as +in the list below. + +An SDK MAY implement model-specific limits, for example +`SpanAttributeCountLimit`. If both a general and a model-specific limit are +implemented, then the SDK MUST first attempt to use the model-specific limit, if +it isn't set and doesn't have a default, then the SDK MUST attempt to use the +general limit. + + +**Configurable parameters:** + +* `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; +* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; + +#### Exempt Entities + +Attributes, which belong to Metrics, are exempt from the limits described above +at this time, as discussed in +[Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). From 8c6e0dd69c8c6f55b4f47d18c27923274e2fff74 Mon Sep 17 00:00:00 2001 From: Owais Lone Date: Tue, 14 Sep 2021 16:40:45 +0530 Subject: [PATCH 180/482] Prefer global limit over model-specific default (#1893) --- specification/common/common.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 6cb26c12f9..c3f434aa89 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -78,8 +78,9 @@ in the list below. An SDK MAY implement model-specific limits, for example `SpanAttributeCountLimit`. If both a general and a model-specific limit are implemented, then the SDK MUST first attempt to use the model-specific limit, if -it isn't set and doesn't have a default, then the SDK MUST attempt to use the -general limit. +it isn't set, then the SDK MUST attempt to use the general limit. If neither are +defined, then the SDK MUST try to use the model-specific limit default value, +followed by the global limit default value. **Configurable parameters:** From 8d35d0c0fd8959db009b51beeccff763a6ae40f1 Mon Sep 17 00:00:00 2001 From: Owais Lone Date: Thu, 23 Sep 2021 05:19:00 +0530 Subject: [PATCH 181/482] Exempt resources from attribute limits (#1892) Resources are not susceptible to scenarios where excessive attributes can be recorded unlike Spans. Resources are also immutable and it can be hard for some SDKs to apply the limits at source at the time the attributes are added to a resource. Furthermore, limits and Resources both are generally defined and passed on to a TracerProvider which forces a TracerProvider to either mutate the resource or generate a new one with duplicate attributes in order to apply the limits to it. Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- specification/common/common.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index c3f434aa89..b0779ad652 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -90,6 +90,14 @@ followed by the global limit default value. #### Exempt Entities +Resource attributes SHOULD be exempt from the limits described above as resources +are not susceptible to the scenarios (auto-instrumentation) that result in +excessive attributes count or size. Resources are also sent only once per batch +instead of per span so it is relatively cheaper to have more/larger attributes +on them. Resources are also immutable by design and they are generally passed +down to TracerProvider along with limits. This makes it awkward to implement +attribute limits for Resources. + Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). From 5c85918533f6cdd84cc4d6a67ee1f3fc8e498254 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 16 Nov 2021 10:05:01 -0500 Subject: [PATCH 182/482] Provide a normative definition of Attribute (singular) rather than Attributes (plural) (#2123) * Provide a normative definition of Attribute (singular) - Providing a normative definition of **attribute** (singular) - Other copyedits /cc @austinlparker @tedsuo * Move anchor to make markdown checker happy --- specification/common/common.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index b0779ad652..19d3d87eb7 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,21 +7,23 @@ Table of Contents -- [Attributes](#attributes) +- [Attribute](#attribute) - [Attribute Limits](#attribute-limits) - [Exempt Entities](#exempt-entities) -## Attributes +## Attribute -Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have the following properties: + -- The attribute key, which MUST be a non-`null` and non-empty string. -- The attribute value, which is either: +An `Attribute` is a key-value pair, which MUST have the following properties: + +- The attribute key MUST be a non-`null` and non-empty string. +- The attribute value is either: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, - i.e. it MUST NOT contain values of different types. For protocols that do + i.e., it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. Attribute values expressing a numerical value of zero, an empty string, or an @@ -64,7 +66,7 @@ If an SDK provides a way to: values separately, - otherwise a value MUST NOT be truncated; - set a limit of unique attribute keys such that: - - for each unique attributes key, addition of which would result in exceeding + - for each unique attribute key, addition of which would result in exceeding the limit, SDK MUST discard that key/value pair. There MAY be a log emitted to indicate to the user that an attribute was From 537b07fcd61d8b15f55e2c1dcf3b713aae653126 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 24 Nov 2021 09:57:38 -0500 Subject: [PATCH 183/482] Ensure all ToCs are generated using markdown-toc (#2146) --- specification/common/attribute-naming.md | 11 +++++++---- specification/common/common.md | 12 +++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 6599f6b239..1cf593b9f7 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -3,13 +3,16 @@ **Status**: [Experimental](../document-status.md)
- -Table of Contents - +Table of Contents -- [Name Pluralization Guidelines](#name-pluralization-guidelines) + + +- [Name Pluralization guidelines](#name-pluralization-guidelines) - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - [Recommendations for Application Developers](#recommendations-for-application-developers) +- [otel.* Namespace](#otel-namespace) + +
diff --git a/specification/common/common.md b/specification/common/common.md index 19d3d87eb7..3e5f170456 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -3,13 +3,15 @@ **Status**: [Stable, Feature-freeze](../document-status.md)
- -Table of Contents - +Table of Contents + + - [Attribute](#attribute) - - [Attribute Limits](#attribute-limits) - - [Exempt Entities](#exempt-entities) + * [Attribute Limits](#attribute-limits) + + [Exempt Entities](#exempt-entities) + +
From 14280a41ae0c750bcb710f5004cd7fbf4671a7d3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 13 Dec 2021 13:04:41 -0500 Subject: [PATCH 184/482] Prohibit usage of retired names in semantic conventions (#2191) * Prohibit usage of retired names in semantic conventions This change adds a prohibition clause that requires that no old metric or attribute name is used for a new attribute. This is important to ensure reversibility of schema transformation (converting from a new version to an old version of schema). Without this restriction the following is possible: Schema version 1. Attribute A exists. Schema version 2. Attribute A is renamed to B. Appropriate schema file is created. Schema version 3. Attribute A is introduced (a completely different new attribute). Now attempting to go from Version 3 to version 1 is impossible since it requires renaming B to A (for the change in version 2), but a different attribute A already exists. * Fix based on comments * Add changelog entry Co-authored-by: Carlos Alberto Cortez --- specification/common/attribute-naming.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 1cf593b9f7..9cd2f187b5 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -8,6 +8,7 @@ - [Name Pluralization guidelines](#name-pluralization-guidelines) +- [Name Reuse Prohibition](#name-reuse-prohibition) - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - [Recommendations for Application Developers](#recommendations-for-application-developers) - [otel.* Namespace](#otel-namespace) @@ -67,6 +68,15 @@ Names SHOULD follow these rules: [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) SHOULD be followed for the attribute name. +## Name Reuse Prohibition + +A new attribute MUST NOT be added with the same name as an attribute that +existed in the past but was renamed (with a corresponding schema file). + +When introducing a new attribute name check all existing schema files to make +sure the name does not appear as a key of any "rename_attributes" section (keys +denote old attribute names in rename operations). + ## Recommendations for OpenTelemetry Authors - All names that are part of OpenTelemetry semantic conventions SHOULD be part From a2667a2dec60265f1199e000b90b6a6614ed0fec Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 26 Jan 2022 16:47:43 -0500 Subject: [PATCH 185/482] Clarify that attribute keys are unique in collections (#2248) Attributes keys must be unique. The key/value pair collections in the specification was always intended to model a map. There was a recent confusion about this. This change clarifies the spec. Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/2245 --- specification/common/common.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 3e5f170456..f098255a22 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -10,6 +10,7 @@ - [Attribute](#attribute) * [Attribute Limits](#attribute-limits) + [Exempt Entities](#exempt-entities) +- [Attribute Collections](#attribute-collections) @@ -105,3 +106,35 @@ attribute limits for Resources. Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). + +## Attribute Collections + +[Resources](../resource/sdk.md), Metrics +[data points](../metrics/datamodel.md#metric-points), +[Spans](../trace/api.md#set-attributes), Span +[Events](../trace/api.md#add-events), Span +[Links](../trace/api.md#specifying-links) and +[Log Records](../logs/data-model.md) may contain a collection of attributes. The +keys in each such collection are unique, i.e. there MUST NOT exist more than one +key-value pair with the same key. The enforcement of uniqueness may be performed +in a variety of ways as it best fits the limitations of the particular +implementation. + +Normally for the telemetry generated using OpenTelemetry SDKs the attribute +key-value pairs are set via an API that either accepts a single key-value pair +or a collection of key-value pairs. Setting an attribute with the same key as an +existing attribute SHOULD overwrite the existing attribute's value. See for +example Span's [SetAttribute](../trace/api.md#set-attributes) API. + +A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API +will enforce the uniqueness by overwriting any existing attribute values pending +to be exported, so that when the Span is eventually exported the exporters see +only unique attributes. The OTLP format in particular requires that exported +Resources, Spans, Metric data points and Log Records contain only unique +attributes. + +Some other implementations may use a streaming approach where every +[SetAttribute](../trace/api.md#set-attributes) API call immediately results in +that individual attribute value being exported using a streaming wire protocol. +In such cases the enforcement of uniqueness will likely be the responsibility of +the recipient of this data. From 16376773274bdcfd735825f1420eac1f059800eb Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 15 Feb 2022 11:34:11 -0500 Subject: [PATCH 186/482] Clarify that Trace/Meter are associated with Instrumentation Scope (#2276) * Clarify that Trace/Meter are associated with Instrumentation Scope This is a slightly different take on https://github.com/open-telemetry/opentelemetry-specification/issues/2203 Instead of renaming instrumentation library to instrumentation scope everywhere this PR suggests targetted editing of wording of the Trace/Meter obtaining API to allow not just instrumentation library but other instrumentation scopes to be used as a parameter. This change does not force renaming of API parameters and is not a breaking change. We consider it a clarification of usage to match the intent that we had for the "name" field. If this PR is accepted there will be a follow up PR that will suggest to rename InstrumentationLibrary* messages in OTLP proto to InstrumentationScope* message. Such a change will not be a breaking change for the OTLP wire format and is acceptable. If this PR is accepted we will also close https://github.com/open-telemetry/opentelemetry-specification/pull/1236 since it will be no longer necessary. The logger name will be recorded as the instrumentation scope. This clarification will be a follow up PR that clarifies the behavior in https://github.com/open-telemetry/oteps/blob/main/text/logs/0150-logging-library-sdk.md --- specification/common/attribute-naming.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 9cd2f187b5..fecbf3b21b 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -148,8 +148,8 @@ Attribute names that start with `otel.` are reserved to be defined by OpenTelemetry specification. These are typically used to express OpenTelemetry concepts in formats that don't have a corresponding concept. -For example, the `otel.library.name` attribute is used to record the -instrumentation library name, which is an OpenTelemetry concept that is natively +For example, the `otel.scope.name` attribute is used to record the +instrumentation scope name, which is an OpenTelemetry concept that is natively represented in OTLP, but does not have an equivalent in other telemetry formats and protocols. From 5bf1bbed5b066606c17075ff13e82b56c63a496a Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Thu, 3 Mar 2022 00:30:53 -0500 Subject: [PATCH 187/482] Describe how to convert non-string primitives for protocols which only support strings (#2343) * Describe how to handle converting non-string primitives for protocols that only support strings * update wording to make clear that only non-string values are converted to strings * unify language * Update specification/common/common.md Co-authored-by: Joshua MacDonald Co-authored-by: Joshua MacDonald Co-authored-by: Bogdan Drutu --- specification/common/common.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index f098255a22..80a13012f4 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -26,8 +26,9 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - The attribute value is either: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, - i.e., it MUST NOT contain values of different types. For protocols that do - not natively support array values such values SHOULD be represented as JSON strings. + i.e., it MUST NOT contain values of different types. + +For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to From d1296366cf9a72b8b2971d75ac48f4af4b9d80d2 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 21 Mar 2022 23:05:45 -0700 Subject: [PATCH 188/482] Fix links (#2426) --- specification/common/common.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 80a13012f4..774c236130 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -9,6 +9,7 @@ - [Attribute](#attribute) * [Attribute Limits](#attribute-limits) + + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) - [Attribute Collections](#attribute-collections) @@ -57,7 +58,7 @@ limits placed on attributes, they can quickly exhaust available memory, resultin in crashes that are difficult to recover from safely. By default an SDK SHOULD apply truncation as per the list of -[configurable parameters](#attribute-limits-configuration) below. +[configurable parameters](#configurable-parameters) below. If an SDK provides a way to: @@ -88,8 +89,7 @@ it isn't set, then the SDK MUST attempt to use the general limit. If neither are defined, then the SDK MUST try to use the model-specific limit default value, followed by the global limit default value. - -**Configurable parameters:** +#### Configurable Parameters * `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; * `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; From b1abb50dd6e3bbcb6481aae093d4058a22436e9c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 22 Mar 2022 08:59:37 -0400 Subject: [PATCH 189/482] Implement OTEP 0178: Mapping external data to AnyValue (#2385) OTEP 0178 [0] proposed this mapping. This PR merges the proposal into specification. The content of this PR is mostly copy/paste of the text of the OTEP minus the irrelevant sections such as "Alternates", etc. 0 - https://github.com/open-telemetry/oteps/blob/main/text/0178-mapping-to-otlp-anyvalue.md --- .../common/attribute-type-mapping.md | 255 ++++++++++++++++++ specification/common/common.md | 3 + 2 files changed, 258 insertions(+) create mode 100644 specification/common/attribute-type-mapping.md diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md new file mode 100644 index 0000000000..46a25c1504 --- /dev/null +++ b/specification/common/attribute-type-mapping.md @@ -0,0 +1,255 @@ +# Mapping Arbitrary Data to OTLP AnyValue + +**Status**: [Experimental](../document-status.md) + +
+Table of Contents + + + +- [Converting to AnyValue](#converting-to-anyvalue) + * [Primitive Values](#primitive-values) + + [Integer Values](#integer-values) + + [Enumerations](#enumerations) + + [Floating Point Values](#floating-point-values) + + [String Values](#string-values) + + [Byte Sequences](#byte-sequences) + * [Composite Values](#composite-values) + + [Array Values](#array-values) + + [Associative Arrays With Unique Keys](#associative-arrays-with-unique-keys) + + [Associative Arrays With Non-Unique Keys](#associative-arrays-with-non-unique-keys) + + [Sets](#sets) + * [Other Values](#other-values) + * [Empty Values](#empty-values) + + + +
+ +This document defines how to map (convert) arbitrary data (e.g. in-memory +objects) to OTLP's [AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/cc4ed55c082cb75e084d40b4ddf3805eda099f97/opentelemetry/proto/common/v1/common.proto#L27). + +The mapping is needed when OpenTelemetry needs to convert a value produced outside +OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be +converted to be used inside OpenTelemetry boundaries. Example use cases are the following: + +- In [Logging Library SDK](../logs/logging-library-sdk.md)s, to convert values received + from logging libraries into OpenTelemetry representation. +- In the Collector, to convert values received from various data sources into + [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) + internal representation. + +## Converting to AnyValue + +[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L27) +is capable of representing primitive and structured data of certain types. + +Implementations that have source data in any form, such as in-memory objects +or data coming from other formats that needs to be converted to AnyValue SHOULD +follow the rules described below. + +### Primitive Values + +#### Integer Values + +Integer values which are within the range of 64 bit signed numbers +[-2^63..2^63-1] SHOULD be converted to AnyValue's +[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) +field. + +Integer values which are outside the range of 64 bit signed numbers SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field using decimal representation. + +#### Enumerations + +Values, which belong to a limited enumerated set (e.g. a Java +[enum](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)), SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field with the value of the string set to the symbolic name of the enumeration. + +If it is not possible to obtain the symbolic name of the enumeration, the +implementation SHOULD map enumeration values to AnyValue's +[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) +field set to the enum's ordinal value, when such an ordinal number is naturally +obtainable. + +If it is also not possible to obtain the ordinal value, the enumeration SHOULD be +converted to AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field in any manner that the implementation deems reasonable. + +#### Floating Point Values + +Floating point values which are within the range and precision of IEEE 754 +64-bit floating point numbers (including IEEE 32-bit floating point values) +SHOULD be converted to AnyValue's +[double_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L34) +field. + +Floating point values which are outside the range or precision of IEEE 754 +64-bit floating point numbers (e.g. IEEE 128-bit floating bit values) SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field using decimal floating point representation. + +#### String Values + +String values which are valid UTF-8 sequences SHOULD be converted to +AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field. + +String values which are not valid Unicode sequences SHOULD be converted to +AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +with the bytes representing the string in the original order and format of the +source string. + +#### Byte Sequences + +Byte sequences (e.g. Go's `[]byte` slice or raw byte content of a file) SHOULD +be converted to AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field. + +### Composite Values + +#### Array Values + +Values that represent ordered sequences of other values (such as +[arrays](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html), +[vectors](https://en.cppreference.com/w/cpp/container/vector), ordered +[lists](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), +[slices](https://golang.org/ref/spec#Slice_types)) SHOULD be converted to +AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field. String values and byte sequences are an exception from this rule (see +above). + +The rules described in this document should be applied recursively to each element +of the array. + +#### Associative Arrays With Unique Keys + +Values that represent associative arrays with unique keys (also often known +as maps, dictionaries or key-value stores) SHOULD be converted to AnyValue's +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field. + +If the keys of the source array are not strings, they MUST be converted to +strings by any means available, often via a toString() or stringify functions +available in programming languages. The conversion function MUST be chosen in a +way that ensures that the resulting string keys are unique in the target array. + +The value part of each element of the source array SHOULD be converted to +AnyValue recursively. + +For example a JSON object `{"a": 123, "b": "def"}` SHOULD be converted to + +``` +AnyValue{ + kvlist_value:KeyValueList{ + values:[ + KeyValue{key:"a",value:AnyValue{int_value:123}}, + KeyValue{key:"b",value:AnyValue{string_value:"def"}}, + ] + } +} +``` + +The rules described in this document should be applied recursively to each value +of the associative array. + +#### Associative Arrays With Non-Unique Keys + +Values that represent an associative arrays with non-unique keys where multiple values may be associated with the same key (also sometimes known +as multimaps, multidicts) SHOULD be converted to AnyValue's +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field. + +The resulting +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field MUST list each key only once and the value of each element of +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field MUST be an array represented using AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field, each element of the +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +representing one value of source array associated with the given key. + +For example an associative array shown in the following table: + +|Key|Value| +|---|---| +|"abc"|123| +|"def"|"foo"| +|"def"|"bar"| + +SHOULD be converted to: + +``` +AnyValue{ + kvlist_value:KeyValueList{ + values:[ + KeyValue{ + key:"abc", + value:AnyValue{array_value:ArrayValue{values[ + AnyValue{int_value:123} + ]}} + }, + KeyValue{ + key:"def", + value:AnyValue{array_value:ArrayValue{values[ + AnyValue{string_value:"foo"}, + AnyValue{string_value:"bar"} + ]}} + }, + ] + } +} +``` + +The rules described in this document should be applied recursively to each value +of the associative array. + +#### Sets + +Unordered collections of unique values (such as +[Java Sets](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html), +[C++ sets](https://en.cppreference.com/w/cpp/container/set), +[Python Sets](https://docs.python.org/3/tutorial/datastructures.html#sets)) SHOULD be +converted to AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field, where each element of the set becomes an element of the array. + +The rules described in this document should be applied recursively to each value +of the set. + +### Other Values + +Any other values not listed above SHOULD be converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field if the source data can be serialized to a string (can be stringified) +using toString() or stringify functions available in programming languages. + +If the source data cannot be serialized to a string then the value SHOULD be +converted AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field by serializing it into a byte sequence by any means available. + +If the source data cannot be serialized neither to a string nor to a byte +sequence then it SHOULD by converted to an empty AnyValue. + +### Empty Values + +If the source data has no type associated with it and is empty, null, nil or +otherwise indicates absence of data it SHOULD be converted to an +[empty](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L29) +AnyValue, where all the fields are unset. + +Empty values which has a type associated with them (e.g. empty associative +array) SHOULD be converted using the corresponding rules defined for the types +above. diff --git a/specification/common/common.md b/specification/common/common.md index 774c236130..6c3e80a527 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -51,6 +51,9 @@ both containing an array of strings to represent a mapping See [Attribute Naming](attribute-naming.md) for naming guidelines. +See [this document](attribute-type-mapping.md) to find out how to map values obtained +outside OpenTelemetry into OpenTelemetry attribute values. + ### Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no From 7a55bf2c53c03c9832d866e3270373bd00c8b9dd Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 8 Apr 2022 13:07:21 -0400 Subject: [PATCH 190/482] Ensure common section has a README (#2479) --- specification/common/{common.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename specification/common/{common.md => README.md} (100%) diff --git a/specification/common/common.md b/specification/common/README.md similarity index 100% rename from specification/common/common.md rename to specification/common/README.md From b8926d2db99cbc1c9345fa35166db447912138fb Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 16 May 2022 10:16:33 -0700 Subject: [PATCH 191/482] Define attribute requirement levels (#2522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nits * review comments * No exceptions for Required attributes, clarifications on performance * Conditional clarifications * nits * Conditional -> required conditionally and minor fixes * Align requirement levels with RFC levels better * Clarify Note on required attributes * Update specification/common/attribute-requirement-level.md Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> * Clarify Note on required attributes * Remove performance from conditionally required attributes * Clarify Conditionally Required case when condition is false * Apply suggestions from code review Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Christian Neumüller * headings for levels and moving things around * nits: formatting Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Co-authored-by: Christian Neumüller Co-authored-by: Reiley Yang --- specification/common/README.md | 2 + .../common/attribute-requirement-level.md | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 specification/common/attribute-requirement-level.md diff --git a/specification/common/README.md b/specification/common/README.md index 6c3e80a527..18d46fe00c 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -51,6 +51,8 @@ both containing an array of strings to represent a mapping See [Attribute Naming](attribute-naming.md) for naming guidelines. +See [Requirement Level](attribute-requirement-level.md) for requirement levels guidelines. + See [this document](attribute-type-mapping.md) to find out how to map values obtained outside OpenTelemetry into OpenTelemetry attribute values. diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md new file mode 100644 index 0000000000..5a7d6e323d --- /dev/null +++ b/specification/common/attribute-requirement-level.md @@ -0,0 +1,69 @@ +# Attribute Requirement Levels for Semantic Conventions + +**Status**: [Experimental](../document-status.md) + +
+Table of Contents + + + +- [Required](#required) +- [Conditionally Required](#conditionally-required) +- [Recommended](#recommended) +- [Optional](#optional) +- [Performance suggestions](#performance-suggestions) + + + +
+ +_This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ + +The following attribute requirement levels are specified: + +- [Required](#required) +- [Conditionally Required](#conditionally-required) +- [Recommended](#recommended) +- [Optional](#optional) + +The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. + +For example, Metric attributes that may have high cardinality can only be defined with `Optional` level. + +Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. + +For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. + +## Required + +All instrumentations MUST populate the attribute. Semantic convention defining a Required attribute expects that an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, can ensure cardinality, security, and other requirements specific to signal defined by the convention. `http.method` is an example of a Required attribute. + +_Note: Consumers of telemetry can detect if telemetry item follows a specific semantic convention by checking the presence of a `Required` attribute defined by such convention. For example, the presence of `db.system` attribute on a span can be used as an indication that the span follows database semantics._ + +## Conditionally Required + +All instrumentations MUST add the attribute when given condition is satisfied. Semantic convention of a `Conditionally Required` level of an attribute MUST clarify the condition under which the attribute is expected to be populated. + +`http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. + +When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. + +For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.peer.ip` is available, instrumentation can do a DNS lookup, cache and populate `net.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. + +## Recommended + +Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. + +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Optional` requirement level on them if the attributes are logically applicable. + +## Optional + +Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Optional` attributes. + +## Performance suggestions + +Here are several examples of expensive operations to be avoided by default: + +- DNS lookup to populate `net.peer.name` if only IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- forcing `http.route` calculation before HTTP framework calculates it +- reading response stream to find `http.response_content_length` when `Content-Length` header is not available From a1f9af0259fe6e43ea806fb318a7cfffa47343b6 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 20 May 2022 02:12:03 -0400 Subject: [PATCH 192/482] Add missing READMEs to section (#2559) --- specification/common/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/common/README.md b/specification/common/README.md index 18d46fe00c..3d1379fde4 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,3 +1,6 @@ + # Common specification concepts **Status**: [Stable, Feature-freeze](../document-status.md) From fb860bc6675cf3b118f7fb331c25ce6ea596ddb3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 2 Jun 2022 03:25:38 -0400 Subject: [PATCH 193/482] Move non-otlp.md to common directory (#2587) --- specification/common/mapping-to-non-otlp.md | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 specification/common/mapping-to-non-otlp.md diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md new file mode 100644 index 0000000000..cb80f685ca --- /dev/null +++ b/specification/common/mapping-to-non-otlp.md @@ -0,0 +1,76 @@ +# OpenTelemetry Transformation to non-OTLP Formats + +**Status**: [Stable](../document-status.md) + +All OpenTelemetry concepts and data recorded using OpenTelemetry API can be +directly and precisely represented using corresponding messages and fields of +OTLP format. However, for other formats this is not always the case. Sometimes a +format will not have a native way to represent a particular OpenTelemetry +concept or a field of a concept. + +This document defines the transformation between OpenTelemetry and formats other +than OTLP, for OpenTelemetry fields and concepts that have no direct semantic +equivalent in those other formats. + +Note: when a format has a direct semantic equivalent for a particular field or +concept then the recommendation in this document MUST be ignored. + +See also additional specific transformation rules for +[Jaeger](../trace/sdk_exporters/jaeger.md) and [Zipkin](../trace/sdk_exporters/zipkin.md). +The specific rules for Jaeger and Zipkin take precedence over the generic rules defined +in this document. + +## Mappings + +### InstrumentationScope + +OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value +pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: + +| OpenTelemetry InstrumentationScope Field | non-OTLP Key | Notes | +| ------------------- | --- | --- | +| `InstrumentationScope.name`|`otel.scope.name`|since 1.10.0| +| `InstrumentationScope.version`|`otel.scope.version`|since 1.10.0| + +The following deprecated aliases MUST also be reported with exact same values for +backward compatibility reasons: + +| non-OTLP Key | Alias for | Notes | +| --- | --- | --- | +|`otel.library.name`|`otel.scope.name`|deprecated since 1.10.0| +|`otel.library.version`|`otel.scope.version`|deprecated since 1.10.0| + +### Span Status + +Span `Status` MUST be reported as key-value pairs associated with the Span, +unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. + +The following table defines the OpenTelemetry `Status`'s mapping to Span's +key-value pairs: + +|OpenTelemetry Status Field|non-OTLP Key|non-OTLP Value| +|--|--|--| +|Code | `otel.status_code` | Name of the code, either `OK` or `ERROR`. MUST NOT be set if the code is `UNSET`. | +|Description | `otel.status_description` | Description of the `Status` if it has a value otherwise not set. | + +### Dropped Attributes Count + +OpenTelemetry dropped attributes count MUST be reported as a key-value +pair associated with the corresponding data entity (e.g. Span, Span Link, Span Event, +Metric data point, LogRecord, etc). The key name MUST be `otel.dropped_attributes_count`. + +This key-value pair should only be recorded when it contains a non-zero value. + +### Dropped Events Count + +OpenTelemetry Span's dropped events count MUST be reported as a key-value pair +associated with the Span. The key name MUST be `otel.dropped_events_count`. + +This key-value pair should only be recorded when it contains a non-zero value. + +### Dropped Links Count + +OpenTelemetry Span's dropped links count MUST be reported as a key-value pair +associated with the Span. The key name MUST be `otel.dropped_links_count`. + +This key-value pair should only be recorded when it contains a non-zero value. From b0047edbc3eff495649ebfe698b429e8a49150f4 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 10 Jun 2022 22:19:33 -0400 Subject: [PATCH 194/482] Introduce Instrumentation Scope Attributes (#2579) --- specification/common/mapping-to-non-otlp.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md index cb80f685ca..656b37fa35 100644 --- a/specification/common/mapping-to-non-otlp.md +++ b/specification/common/mapping-to-non-otlp.md @@ -74,3 +74,9 @@ OpenTelemetry Span's dropped links count MUST be reported as a key-value pair associated with the Span. The key name MUST be `otel.dropped_links_count`. This key-value pair should only be recorded when it contains a non-zero value. + +### Instrumentation Scope Attributes + +Exporters to formats that don't have a concept that is equivalent to the Scope +SHOULD record the attributes at the most suitable place in their corresponding format, +typically at the Span, Metric or LogRecord equivalent. From aafd53c1294122b91307d5f7b1ed5b0a5dc29493 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 13 Jun 2022 12:00:00 -0400 Subject: [PATCH 195/482] Use consistent file name for data-model.md (#2586) --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 3d1379fde4..35d6264b2a 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -119,7 +119,7 @@ at this time, as discussed in ## Attribute Collections [Resources](../resource/sdk.md), Metrics -[data points](../metrics/datamodel.md#metric-points), +[data points](../metrics/data-model.md#metric-points), [Spans](../trace/api.md#set-attributes), Span [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#specifying-links) and From fe3cf1830c14860a5964ae33dafd88844cd6c435 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 8 Jul 2022 03:12:12 -0400 Subject: [PATCH 196/482] Add note to Hugo front matter (#2651) --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 35d6264b2a..2b377a731c 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,4 +1,4 @@ - # Common specification concepts From a181cc323e3c2096f16d6e43c5eb4902604af3ba Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 13 Jul 2022 10:01:44 -0700 Subject: [PATCH 197/482] Define net.sock attributes and clarify logical net.peer|host.name attributes (#2614) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 5a7d6e323d..e015ef89eb 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -48,7 +48,7 @@ All instrumentations MUST add the attribute when given condition is satisfied. S When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.peer.ip` is available, instrumentation can do a DNS lookup, cache and populate `net.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. +For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. ## Recommended From 8267eacc84e712632fb75f798c5f8e38c234b581 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 13 Sep 2022 09:45:58 -0500 Subject: [PATCH 198/482] Align log sdk naming with api (#2768) Resolves #2752. This aligns log SDK and API concepts which have diverged after the merged of #2676. This PR brings alignment to the log API and SDK, and in brings the log signal into alignment with tracing and metrics where there is conceptual overlap. There shouldn't be any new concepts introduced here. - Rename `../logs/logging-library-sdk.md` to `../logs/sdk.md` - Remove wording from SDK that implies that an API doesn't exist, like [this](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L60-L62). - Move [How to Create Log4j Style Appender](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L219) to `api.md` since it describes an API use case. - Move [Implicit / Explicit Context Injection](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L270-L288) sections to `api.md` since they describe API level considerations. - Rename Logger [create](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/api.md#L133) method to be emit, to align with SDK concept of `LogRecordProcessor#onEmit(..)`. - Rename `LogProcessor`, `LogExporter` to `LogRecordProcessor`, `LogRecordExporter`. - Fill in various SDK level TODOs related to shutdown and flushing. The language from these was taken directly from the metrics / tracing SDK - no new concepts were introduced. --- specification/common/attribute-type-mapping.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index 46a25c1504..532d6156bc 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -33,7 +33,7 @@ The mapping is needed when OpenTelemetry needs to convert a value produced outsi OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be converted to be used inside OpenTelemetry boundaries. Example use cases are the following: -- In [Logging Library SDK](../logs/logging-library-sdk.md)s, to convert values received +- In the [Logging SDK](../logs/sdk.md)s, to convert values received from logging libraries into OpenTelemetry representation. - In the Collector, to convert values received from various data sources into [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) From fac9ea093cfedefa37ab919f6a4750d6f4c7a5ca Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 25 Oct 2022 08:46:06 -0700 Subject: [PATCH 199/482] Define semantic conventions yaml for non-otlp conventions (#2850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Define semantic conventions yaml for non-otlp conventions Signed-off-by: Bogdan Drutu * Update semantic_conventions/trace/exporter/exporter.yaml Co-authored-by: Christian Neumüller * Update semantic_conventions/scope/exporter/exporter.yaml Co-authored-by: Joao Grassi * Rename otel to otel_span Signed-off-by: Bogdan Drutu Signed-off-by: Bogdan Drutu Co-authored-by: Christian Neumüller Co-authored-by: Joao Grassi --- specification/common/mapping-to-non-otlp.md | 37 ++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md index 656b37fa35..a82dac3e63 100644 --- a/specification/common/mapping-to-non-otlp.md +++ b/specification/common/mapping-to-non-otlp.md @@ -27,18 +27,22 @@ in this document. OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: -| OpenTelemetry InstrumentationScope Field | non-OTLP Key | Notes | -| ------------------- | --- | --- | -| `InstrumentationScope.name`|`otel.scope.name`|since 1.10.0| -| `InstrumentationScope.version`|`otel.scope.version`|since 1.10.0| + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | Recommended | +| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | Recommended | + The following deprecated aliases MUST also be reported with exact same values for backward compatibility reasons: -| non-OTLP Key | Alias for | Notes | -| --- | --- | --- | -|`otel.library.name`|`otel.scope.name`|deprecated since 1.10.0| -|`otel.library.version`|`otel.scope.version`|deprecated since 1.10.0| + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.library.name` | string | Deprecated, use the `otel.scope.name` attribute. | `io.opentelemetry.contrib.mongodb` | Recommended | +| `otel.library.version` | string | Deprecated, use the `otel.scope.version` attribute. | `1.0.0` | Recommended | + ### Span Status @@ -48,10 +52,19 @@ unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. The following table defines the OpenTelemetry `Status`'s mapping to Span's key-value pairs: -|OpenTelemetry Status Field|non-OTLP Key|non-OTLP Value| -|--|--|--| -|Code | `otel.status_code` | Name of the code, either `OK` or `ERROR`. MUST NOT be set if the code is `UNSET`. | -|Description | `otel.status_description` | Description of the `Status` if it has a value otherwise not set. | + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | Recommended | +| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | Recommended | + +`otel.status_code` MUST be one of the following: + +| Value | Description | +|---|---| +| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | +| `ERROR` | The operation contains an error. | + ### Dropped Attributes Count From 6fb1c444abb11def67c20d80d5d779f3468d6e35 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 26 Jan 2023 16:22:06 -0800 Subject: [PATCH 200/482] Add log attribute limit configuration (#2861) Fixes #2860 Adds log attribute limit configuration. These new environment variables bring more consistency between spans and logs. --- specification/common/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 2b377a731c..f36cb92b85 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -91,11 +91,11 @@ limits programmatically. Names of the configuration options SHOULD be the same a in the list below. An SDK MAY implement model-specific limits, for example -`SpanAttributeCountLimit`. If both a general and a model-specific limit are -implemented, then the SDK MUST first attempt to use the model-specific limit, if -it isn't set, then the SDK MUST attempt to use the general limit. If neither are -defined, then the SDK MUST try to use the model-specific limit default value, -followed by the global limit default value. +`SpanAttributeCountLimit` or `LogRecordAttributeCountLimit`. If both a general +and a model-specific limit are implemented, then the SDK MUST first attempt to +use the model-specific limit, if it isn't set, then the SDK MUST attempt to use +the general limit. If neither are defined, then the SDK MUST try to use the +model-specific limit default value, followed by the global limit default value. #### Configurable Parameters From 6b6cba749ac1adeae31476cc769f7d8684c6e7d2 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 23 Feb 2023 11:38:55 -0500 Subject: [PATCH 201/482] Mark Attribute naming conventions as stable. (#3220) --- specification/common/attribute-naming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index fecbf3b21b..d761b5f9fd 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -1,6 +1,6 @@ # Attribute Naming -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md)
Table of Contents From b8e3c86a2b965590ac7c40c499cd469900ae241c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 1 Mar 2023 15:13:24 -0800 Subject: [PATCH 202/482] Rename Optional attribute requirement level to Opt-In (#3228) --- .../common/attribute-requirement-level.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index e015ef89eb..c030159409 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -10,7 +10,7 @@ - [Required](#required) - [Conditionally Required](#conditionally-required) - [Recommended](#recommended) -- [Optional](#optional) +- [Opt-In](#opt-in) - [Performance suggestions](#performance-suggestions) @@ -24,11 +24,11 @@ The following attribute requirement levels are specified: - [Required](#required) - [Conditionally Required](#conditionally-required) - [Recommended](#recommended) -- [Optional](#optional) +- [Opt-In](#opt-in) The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. -For example, Metric attributes that may have high cardinality can only be defined with `Optional` level. +For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. @@ -46,7 +46,7 @@ All instrumentations MUST add the attribute when given condition is satisfied. S `http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. -When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. +When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. @@ -54,11 +54,11 @@ For example, `net.peer.name` is `Conditionally Required` by [Database convention Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Optional` requirement level on them if the attributes are logically applicable. +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Opt-In` requirement level on them if the attributes are logically applicable. -## Optional +## Opt-In -Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Optional` attributes. +Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. ## Performance suggestions From 8b0bccd2dedd0c1f9d5f90963f1ad363d9a71216 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 6 Mar 2023 10:20:11 -0800 Subject: [PATCH 203/482] Proofread of attribute requirement levels in preparation for stability (#3270) --- .../common/attribute-requirement-level.md | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index c030159409..59432e6096 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -26,44 +26,47 @@ The following attribute requirement levels are specified: - [Recommended](#recommended) - [Opt-In](#opt-in) -The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. +The requirement level for an attribute is specified by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When specifying requirement levels, a semantic convention MUST take into account signal-specific requirements. For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. -Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. +A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. ## Required -All instrumentations MUST populate the attribute. Semantic convention defining a Required attribute expects that an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, can ensure cardinality, security, and other requirements specific to signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. -_Note: Consumers of telemetry can detect if telemetry item follows a specific semantic convention by checking the presence of a `Required` attribute defined by such convention. For example, the presence of `db.system` attribute on a span can be used as an indication that the span follows database semantics._ +_Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ ## Conditionally Required -All instrumentations MUST add the attribute when given condition is satisfied. Semantic convention of a `Conditionally Required` level of an attribute MUST clarify the condition under which the attribute is expected to be populated. +All instrumentations MUST populate the attribute when the given condition is satisfied. The semantic convention of a `Conditionally Required` attribute MUST clarify the condition under which the attribute is to be populated. -`http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. +`http.route` is an example of a conditionally required attribute that is populated when the instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. -When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. +When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. +For example, `net.peer.name` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `net.sock.peer.addr` is available instead, instrumentation can do a DNS lookup, cache and populate `net.peer.name`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Opt-In` requirement level on them if the attributes are logically applicable. +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD allow for users to +opt-in to emit them as defined for the `Opt-In` requirement level (if the attributes are logically applicable). ## Opt-In Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. +This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled enabled explicitly by a user making an informed decision. + ## Performance suggestions Here are several examples of expensive operations to be avoided by default: -- DNS lookup to populate `net.peer.name` if only IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. -- forcing `http.route` calculation before HTTP framework calculates it +- DNS lookups to populate `net.peer.name` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- forcing an `http.route` calculation before the HTTP framework calculates it - reading response stream to find `http.response_content_length` when `Content-Length` header is not available From c717ab4f4cf26669bb448d5caf50c656f42f670c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 7 Mar 2023 11:22:32 -0800 Subject: [PATCH 204/482] Attribute requirement level follow-up edits (#3293) --- specification/common/attribute-requirement-level.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 59432e6096..c7fb99345c 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -36,7 +36,7 @@ For example, [Database semantic convention](../trace/semantic_conventions/databa ## Required -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. _Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ @@ -61,7 +61,7 @@ opt-in to emit them as defined for the `Opt-In` requirement level (if the attrib Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. -This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled enabled explicitly by a user making an informed decision. +This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled explicitly by a user making an informed decision. ## Performance suggestions From 4adbc387e952c33be6710e9174c9659e2b5d7a55 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 16 Mar 2023 06:31:51 -0700 Subject: [PATCH 205/482] Clarify that attribute requirement levels apply to instrumentation libraries (#3289) Based on discussion in semconv stability WG Closes #3283 ## Changes Clarifies that attribute requirement levels apply to instrumentation. And that, because users can transform their telemetry in a number of ways (e.g. metric views, span processors, and collector transformations), these requirement levels cannot be relied on by telemetry consumers. --------- Co-authored-by: Liudmila Molkova Co-authored-by: Bogdan Drutu --- specification/common/attribute-requirement-level.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index c7fb99345c..3543970a29 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -19,6 +19,8 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ +Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). + The following attribute requirement levels are specified: - [Required](#required) From e182ff311df190a2715910a507d938b6750a64e6 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 6 Apr 2023 21:56:17 -0700 Subject: [PATCH 206/482] Mark attribute requirement levels as stable (#3368) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 3543970a29..e9da7f0702 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -1,6 +1,6 @@ # Attribute Requirement Levels for Semantic Conventions -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md)
Table of Contents From f4f8be2cce78c378a8c9f86cac2cfd9658a90a57 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 7 Apr 2023 15:55:06 -0400 Subject: [PATCH 207/482] Use path, not external URL, for link into glossary (#3375) - Contributes to https://github.com/open-telemetry/opentelemetry.io/issues/2429 - This is part of an effort to normalize links, for improved link checking on the OTel website --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index e9da7f0702..cfbc22b9da 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -19,7 +19,7 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ -Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). +Attribute requirement levels apply to the [instrumentation library](../glossary.md#instrumentation-library). The following attribute requirement levels are specified: From 1b014422186a07611d45958a31838625883b3c99 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 8 May 2023 16:19:51 -0700 Subject: [PATCH 208/482] BREAKING: Replace `net.peer.*`/`net.host.*` with `client.*`/`server.*` (and `source.*`/`destination.*`) (#3402) --- specification/common/attribute-requirement-level.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index cfbc22b9da..aca07f487c 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -50,7 +50,7 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `net.sock.peer.addr` is available instead, instrumentation can do a DNS lookup, cache and populate `net.peer.name`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. +For example, `server.address` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended @@ -69,6 +69,6 @@ This attribute requirement level is recommended for attributes that are particul Here are several examples of expensive operations to be avoided by default: -- DNS lookups to populate `net.peer.name` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it - reading response stream to find `http.response_content_length` when `Content-Length` header is not available From d6f3da6f11d145ded1feced9a830ecbd792a6f5e Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 May 2023 17:46:55 -0700 Subject: [PATCH 209/482] BREAKING: Rename remaining network attributes from `net.*` to `network.*` and align definitions with ECS (#3426) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index aca07f487c..fc3f5b89d3 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -34,7 +34,7 @@ For example, Metric attributes that may have high cardinality can only be define A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. -For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. +For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `network.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. ## Required From cc85702f85b13b0538279b502d26569646e369c7 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 8 May 2023 19:55:53 -0700 Subject: [PATCH 210/482] BREAKING: Introduce common `url.*` attributes, and improve use of namespacing under `http.*` (#3355) --- specification/common/attribute-naming.md | 6 +-- .../common/attribute-requirement-level.md | 4 +- specification/common/url.md | 45 +++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 specification/common/url.md diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index d761b5f9fd..67aee0ad09 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -44,7 +44,7 @@ Names SHOULD follow these rules: purpose should primarily drive the decision about forming nested namespaces. - For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.status_code` + words by underscores (i.e. use snake_case). For example `http.response.status_code` denotes the status code in the http namespace. - Names SHOULD NOT coincide with namespaces. For example if @@ -96,8 +96,8 @@ denote old attribute names in rename operations). - Semantic conventions exist for four areas: for Resource, Span, Log, and Metric attribute names. In addition, for spans we have two more areas: Event and Link attribute names. Identical namespaces or names in all these areas MUST have - identical meanings. For example the `http.method` span attribute name denotes - exactly the same concept as the `http.method` metric attribute, has the same + identical meanings. For example the `http.request.method` span attribute name denotes + exactly the same concept as the `http.request.method` metric attribute, has the same data type and the same set of possible values (in both cases it records the value of the HTTP protocol's request method as a string). diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index fc3f5b89d3..52f8e34f26 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -38,7 +38,7 @@ For example, [Database semantic convention](../trace/semantic_conventions/databa ## Required -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.request.method` is an example of a Required attribute. _Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ @@ -71,4 +71,4 @@ Here are several examples of expensive operations to be avoided by default: - DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it -- reading response stream to find `http.response_content_length` when `Content-Length` header is not available +- reading response stream to find `http.response.body.size` when `Content-Length` header is not available diff --git a/specification/common/url.md b/specification/common/url.md new file mode 100644 index 0000000000..bbe041ba67 --- /dev/null +++ b/specification/common/url.md @@ -0,0 +1,45 @@ +# Semantic conventions for URL + +**Status**: [Experimental](../document-status.md) + +This document defines semantic conventions that describe URL and its components. + +
+Table of Contents + + + +- [Attributes](#attributes) +- [Sensitive information](#sensitive-information) + + + +
+ +## Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | +| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | + +**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +**[2]:** When missing, the value is assumed to be `/` + +**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + + +## Sensitive information + +Capturing URL and its components MAY impose security risk. User and password information, when they are provided in [User Information](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1) subcomponent, MUST NOT be recorded. + +Instrumentations that are aware of specific sensitive query string parameters MUST scrub their values before capturing `url.query` attribute. For example, native instrumentation of a client library that passes credentials or user location in URL, must scrub corresponding properties. + +_Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ From bd2b51a2495697a6b77620930f6cdb8b11bc052a Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 26 May 2023 11:23:42 -0400 Subject: [PATCH 211/482] Explain why custom attributes are not recommended to be placed in Otel namespaces (#3507) The @open-telemetry/technical-committee discussed and decided to keep the existing recommendations but clarify them and explain the purpose. --- specification/common/attribute-naming.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 67aee0ad09..badb9acbd0 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -133,6 +133,13 @@ To do that consider a few options: `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. +- It is not recommended to use existing OpenTelemetry semantic convention namespace + as a prefix for a new company- or application-specific attribute name. Doing so + may result in a name clash in the future, if OpenTelemetry decides to use that + same name for a different purpose or if some other third party instrumentation + decides to use that exact same attribute name and you combine that instrumentation + with your own. + - The name may be generally applicable to applications in the industry. In that case consider submitting a proposal to this specification to add a new name to the semantic conventions, and if necessary also to add a new namespace. From 9d7cdb92927eabef6df30b2b824ede02209c232c Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 12 Jul 2023 10:58:54 -0400 Subject: [PATCH 212/482] Hugo front-matter fixes for aliases and linkTitle (#3592) - Followup changes for https://github.com/open-telemetry/opentelemetry.io/issues/2793 - There are only changes to Hugo front matter - Adds `likeTitle`s for "Compatibility" pages - Adds aliases for pages that have moved or were renamed - Related: https://github.com/open-telemetry/opentelemetry.io/issues/3013 -- the `compatibility/openmetrics` spec page is in the list because it was renamed /cc @svrnm @cartermp --- specification/common/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/common/README.md b/specification/common/README.md index f36cb92b85..239bdf2014 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,6 +1,7 @@ + # Common specification concepts **Status**: [Stable, Feature-freeze](../document-status.md) From e3352d43bc1078e249d84688b3ab83e47d97b78f Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 3 Oct 2023 12:13:38 -0400 Subject: [PATCH 213/482] Remove local stubs of semantic conventions. (#3711) --- specification/common/attribute-naming.md | 14 +++----------- .../common/attribute-requirement-level.md | 6 ++++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index badb9acbd0..548703db6f 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -65,7 +65,7 @@ Names SHOULD follow these rules: values: the executable name and command arguments. - When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + [Metric Name Pluralization Guidelines](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md#pluralization) SHOULD be followed for the attribute name. ## Name Reuse Prohibition @@ -83,11 +83,7 @@ denote old attribute names in rename operations). of a namespace. - When coming up with a new semantic convention make sure to check existing - namespaces for - [Resources](../resource/semantic_conventions/README.md), - [Spans](../trace/semantic_conventions/README.md), - and - [Metrics](../metrics/semantic_conventions/README.md) + namespaces ([Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md)) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level @@ -111,11 +107,7 @@ denote old attribute names in rename operations). ## Recommendations for Application Developers As an application developer when you need to record an attribute first consult -existing semantic conventions for -[Resources](../resource/semantic_conventions/README.md), -[Spans](../trace/semantic_conventions/README.md), -and -[Metrics](../metrics/semantic_conventions/README.md). +existing [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md). If an appropriate name does not exists you will need to come up with a new name. To do that consider a few options: diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 52f8e34f26..1866c413ca 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -34,7 +34,8 @@ For example, Metric attributes that may have high cardinality can only be define A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. -For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `network.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. + +For example, [Database semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) references `network.transport` attribute defined in [General attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/README.md) with `Conditionally Required` level on it. ## Required @@ -50,7 +51,8 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. + +For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended From 7ee67a7192013216aaa723196b4dbbfd88bd1415 Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Wed, 11 Oct 2023 01:15:24 +0200 Subject: [PATCH 214/482] Add a new AddLink() operation to Span. (#3678) Fixes #454 Related to #3337 As the Messaging SIG merged its last OTEP 222, we will be adding operations that require Links after Span creation, taking a direct route with `AddLink()`, albeit without any of the new members suggested in #3337, e.g. `timestamp` (to be discussed in a separate issue). ``` AddLink(spanContext, attributes /* optional */) ``` --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 239bdf2014..1f17536bb6 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -123,7 +123,7 @@ at this time, as discussed in [data points](../metrics/data-model.md#metric-points), [Spans](../trace/api.md#set-attributes), Span [Events](../trace/api.md#add-events), Span -[Links](../trace/api.md#specifying-links) and +[Links](../trace/api.md#link) and [Log Records](../logs/data-model.md) may contain a collection of attributes. The keys in each such collection are unique, i.e. there MUST NOT exist more than one key-value pair with the same key. The enforcement of uniqueness may be performed From e56432cc1d9eff83e091a1776c8b3f897a0105a7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 23 Oct 2023 08:19:08 -0700 Subject: [PATCH 215/482] Rename/replace `(client|server).socket.(address|port)` attributes with `network.(peer|local).(address|port)`. (#3713) Co-authored-by: Armin Ruech --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 1866c413ca..7f510fe731 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -52,7 +52,7 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. +For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended From eece45b83c434fbbe7a0a3bcc0ddfec9f5e1bfee Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 7 Nov 2023 14:01:24 -0600 Subject: [PATCH 216/482] Remove files to keep --- specification/common/README.md | 150 ----------- .../common/attribute-type-mapping.md | 255 ------------------ specification/common/mapping-to-non-otlp.md | 95 ------- specification/common/url.md | 45 ---- 4 files changed, 545 deletions(-) delete mode 100644 specification/common/README.md delete mode 100644 specification/common/attribute-type-mapping.md delete mode 100644 specification/common/mapping-to-non-otlp.md delete mode 100644 specification/common/url.md diff --git a/specification/common/README.md b/specification/common/README.md deleted file mode 100644 index 1f17536bb6..0000000000 --- a/specification/common/README.md +++ /dev/null @@ -1,150 +0,0 @@ - - -# Common specification concepts - -**Status**: [Stable, Feature-freeze](../document-status.md) - -
-Table of Contents - - - -- [Attribute](#attribute) - * [Attribute Limits](#attribute-limits) - + [Configurable Parameters](#configurable-parameters) - + [Exempt Entities](#exempt-entities) -- [Attribute Collections](#attribute-collections) - - - -
- -## Attribute - - - -An `Attribute` is a key-value pair, which MUST have the following properties: - -- The attribute key MUST be a non-`null` and non-empty string. -- The attribute value is either: - - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - - An array of primitive type values. The array MUST be homogeneous, - i.e., it MUST NOT contain values of different types. - -For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. - -Attribute values expressing a numerical value of zero, an empty string, or an -empty array are considered meaningful and MUST be stored and passed on to -processors / exporters. - -Attribute values of `null` are not valid and attempting to set a `null` value is -undefined behavior. - -`null` values SHOULD NOT be allowed in arrays. However, if it is impossible to -make sure that no `null` values are accepted -(e.g. in languages that do not have appropriate compile-time type checking), -`null` values within arrays MUST be preserved as-is (i.e., passed on to span -processors / exporters as `null`). If exporters do not support exporting `null` -values, they MAY replace those values by 0, `false`, or empty strings. -This is required for map/dictionary structures represented as two arrays with -indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, -both containing an array of strings to represent a mapping -`header_keys[i] -> header_values[i]`). - -See [Attribute Naming](attribute-naming.md) for naming guidelines. - -See [Requirement Level](attribute-requirement-level.md) for requirement levels guidelines. - -See [this document](attribute-type-mapping.md) to find out how to map values obtained -outside OpenTelemetry into OpenTelemetry attribute values. - -### Attribute Limits - -Execution of erroneous code can result in unintended attributes. If there are no -limits placed on attributes, they can quickly exhaust available memory, resulting -in crashes that are difficult to recover from safely. - -By default an SDK SHOULD apply truncation as per the list of -[configurable parameters](#configurable-parameters) below. - -If an SDK provides a way to: - -- set an attribute value length limit such that for each - attribute value: - - if it is a string, if it exceeds that limit (counting any character in it as - 1), SDKs MUST truncate that value, so that its length is at most equal - to the limit, - - if it is an array of strings, then apply the above rule to each of the - values separately, - - otherwise a value MUST NOT be truncated; -- set a limit of unique attribute keys such that: - - for each unique attribute key, addition of which would result in exceeding - the limit, SDK MUST discard that key/value pair. - -There MAY be a log emitted to indicate to the user that an attribute was -truncated or discarded. To prevent excessive logging, the log MUST NOT be -emitted more than once per record on which an attribute is set. - -If the SDK implements the limits above, it MUST provide a way to change these -limits programmatically. Names of the configuration options SHOULD be the same as -in the list below. - -An SDK MAY implement model-specific limits, for example -`SpanAttributeCountLimit` or `LogRecordAttributeCountLimit`. If both a general -and a model-specific limit are implemented, then the SDK MUST first attempt to -use the model-specific limit, if it isn't set, then the SDK MUST attempt to use -the general limit. If neither are defined, then the SDK MUST try to use the -model-specific limit default value, followed by the global limit default value. - -#### Configurable Parameters - -* `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; -* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; - -#### Exempt Entities - -Resource attributes SHOULD be exempt from the limits described above as resources -are not susceptible to the scenarios (auto-instrumentation) that result in -excessive attributes count or size. Resources are also sent only once per batch -instead of per span so it is relatively cheaper to have more/larger attributes -on them. Resources are also immutable by design and they are generally passed -down to TracerProvider along with limits. This makes it awkward to implement -attribute limits for Resources. - -Attributes, which belong to Metrics, are exempt from the limits described above -at this time, as discussed in -[Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). - -## Attribute Collections - -[Resources](../resource/sdk.md), Metrics -[data points](../metrics/data-model.md#metric-points), -[Spans](../trace/api.md#set-attributes), Span -[Events](../trace/api.md#add-events), Span -[Links](../trace/api.md#link) and -[Log Records](../logs/data-model.md) may contain a collection of attributes. The -keys in each such collection are unique, i.e. there MUST NOT exist more than one -key-value pair with the same key. The enforcement of uniqueness may be performed -in a variety of ways as it best fits the limitations of the particular -implementation. - -Normally for the telemetry generated using OpenTelemetry SDKs the attribute -key-value pairs are set via an API that either accepts a single key-value pair -or a collection of key-value pairs. Setting an attribute with the same key as an -existing attribute SHOULD overwrite the existing attribute's value. See for -example Span's [SetAttribute](../trace/api.md#set-attributes) API. - -A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API -will enforce the uniqueness by overwriting any existing attribute values pending -to be exported, so that when the Span is eventually exported the exporters see -only unique attributes. The OTLP format in particular requires that exported -Resources, Spans, Metric data points and Log Records contain only unique -attributes. - -Some other implementations may use a streaming approach where every -[SetAttribute](../trace/api.md#set-attributes) API call immediately results in -that individual attribute value being exported using a streaming wire protocol. -In such cases the enforcement of uniqueness will likely be the responsibility of -the recipient of this data. diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md deleted file mode 100644 index 532d6156bc..0000000000 --- a/specification/common/attribute-type-mapping.md +++ /dev/null @@ -1,255 +0,0 @@ -# Mapping Arbitrary Data to OTLP AnyValue - -**Status**: [Experimental](../document-status.md) - -
-Table of Contents - - - -- [Converting to AnyValue](#converting-to-anyvalue) - * [Primitive Values](#primitive-values) - + [Integer Values](#integer-values) - + [Enumerations](#enumerations) - + [Floating Point Values](#floating-point-values) - + [String Values](#string-values) - + [Byte Sequences](#byte-sequences) - * [Composite Values](#composite-values) - + [Array Values](#array-values) - + [Associative Arrays With Unique Keys](#associative-arrays-with-unique-keys) - + [Associative Arrays With Non-Unique Keys](#associative-arrays-with-non-unique-keys) - + [Sets](#sets) - * [Other Values](#other-values) - * [Empty Values](#empty-values) - - - -
- -This document defines how to map (convert) arbitrary data (e.g. in-memory -objects) to OTLP's [AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/cc4ed55c082cb75e084d40b4ddf3805eda099f97/opentelemetry/proto/common/v1/common.proto#L27). - -The mapping is needed when OpenTelemetry needs to convert a value produced outside -OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be -converted to be used inside OpenTelemetry boundaries. Example use cases are the following: - -- In the [Logging SDK](../logs/sdk.md)s, to convert values received - from logging libraries into OpenTelemetry representation. -- In the Collector, to convert values received from various data sources into - [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) - internal representation. - -## Converting to AnyValue - -[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L27) -is capable of representing primitive and structured data of certain types. - -Implementations that have source data in any form, such as in-memory objects -or data coming from other formats that needs to be converted to AnyValue SHOULD -follow the rules described below. - -### Primitive Values - -#### Integer Values - -Integer values which are within the range of 64 bit signed numbers -[-2^63..2^63-1] SHOULD be converted to AnyValue's -[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) -field. - -Integer values which are outside the range of 64 bit signed numbers SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field using decimal representation. - -#### Enumerations - -Values, which belong to a limited enumerated set (e.g. a Java -[enum](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)), SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field with the value of the string set to the symbolic name of the enumeration. - -If it is not possible to obtain the symbolic name of the enumeration, the -implementation SHOULD map enumeration values to AnyValue's -[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) -field set to the enum's ordinal value, when such an ordinal number is naturally -obtainable. - -If it is also not possible to obtain the ordinal value, the enumeration SHOULD be -converted to AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field in any manner that the implementation deems reasonable. - -#### Floating Point Values - -Floating point values which are within the range and precision of IEEE 754 -64-bit floating point numbers (including IEEE 32-bit floating point values) -SHOULD be converted to AnyValue's -[double_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L34) -field. - -Floating point values which are outside the range or precision of IEEE 754 -64-bit floating point numbers (e.g. IEEE 128-bit floating bit values) SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field using decimal floating point representation. - -#### String Values - -String values which are valid UTF-8 sequences SHOULD be converted to -AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field. - -String values which are not valid Unicode sequences SHOULD be converted to -AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -with the bytes representing the string in the original order and format of the -source string. - -#### Byte Sequences - -Byte sequences (e.g. Go's `[]byte` slice or raw byte content of a file) SHOULD -be converted to AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field. - -### Composite Values - -#### Array Values - -Values that represent ordered sequences of other values (such as -[arrays](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html), -[vectors](https://en.cppreference.com/w/cpp/container/vector), ordered -[lists](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), -[slices](https://golang.org/ref/spec#Slice_types)) SHOULD be converted to -AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field. String values and byte sequences are an exception from this rule (see -above). - -The rules described in this document should be applied recursively to each element -of the array. - -#### Associative Arrays With Unique Keys - -Values that represent associative arrays with unique keys (also often known -as maps, dictionaries or key-value stores) SHOULD be converted to AnyValue's -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field. - -If the keys of the source array are not strings, they MUST be converted to -strings by any means available, often via a toString() or stringify functions -available in programming languages. The conversion function MUST be chosen in a -way that ensures that the resulting string keys are unique in the target array. - -The value part of each element of the source array SHOULD be converted to -AnyValue recursively. - -For example a JSON object `{"a": 123, "b": "def"}` SHOULD be converted to - -``` -AnyValue{ - kvlist_value:KeyValueList{ - values:[ - KeyValue{key:"a",value:AnyValue{int_value:123}}, - KeyValue{key:"b",value:AnyValue{string_value:"def"}}, - ] - } -} -``` - -The rules described in this document should be applied recursively to each value -of the associative array. - -#### Associative Arrays With Non-Unique Keys - -Values that represent an associative arrays with non-unique keys where multiple values may be associated with the same key (also sometimes known -as multimaps, multidicts) SHOULD be converted to AnyValue's -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field. - -The resulting -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field MUST list each key only once and the value of each element of -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field MUST be an array represented using AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field, each element of the -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -representing one value of source array associated with the given key. - -For example an associative array shown in the following table: - -|Key|Value| -|---|---| -|"abc"|123| -|"def"|"foo"| -|"def"|"bar"| - -SHOULD be converted to: - -``` -AnyValue{ - kvlist_value:KeyValueList{ - values:[ - KeyValue{ - key:"abc", - value:AnyValue{array_value:ArrayValue{values[ - AnyValue{int_value:123} - ]}} - }, - KeyValue{ - key:"def", - value:AnyValue{array_value:ArrayValue{values[ - AnyValue{string_value:"foo"}, - AnyValue{string_value:"bar"} - ]}} - }, - ] - } -} -``` - -The rules described in this document should be applied recursively to each value -of the associative array. - -#### Sets - -Unordered collections of unique values (such as -[Java Sets](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html), -[C++ sets](https://en.cppreference.com/w/cpp/container/set), -[Python Sets](https://docs.python.org/3/tutorial/datastructures.html#sets)) SHOULD be -converted to AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field, where each element of the set becomes an element of the array. - -The rules described in this document should be applied recursively to each value -of the set. - -### Other Values - -Any other values not listed above SHOULD be converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field if the source data can be serialized to a string (can be stringified) -using toString() or stringify functions available in programming languages. - -If the source data cannot be serialized to a string then the value SHOULD be -converted AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field by serializing it into a byte sequence by any means available. - -If the source data cannot be serialized neither to a string nor to a byte -sequence then it SHOULD by converted to an empty AnyValue. - -### Empty Values - -If the source data has no type associated with it and is empty, null, nil or -otherwise indicates absence of data it SHOULD be converted to an -[empty](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L29) -AnyValue, where all the fields are unset. - -Empty values which has a type associated with them (e.g. empty associative -array) SHOULD be converted using the corresponding rules defined for the types -above. diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md deleted file mode 100644 index a82dac3e63..0000000000 --- a/specification/common/mapping-to-non-otlp.md +++ /dev/null @@ -1,95 +0,0 @@ -# OpenTelemetry Transformation to non-OTLP Formats - -**Status**: [Stable](../document-status.md) - -All OpenTelemetry concepts and data recorded using OpenTelemetry API can be -directly and precisely represented using corresponding messages and fields of -OTLP format. However, for other formats this is not always the case. Sometimes a -format will not have a native way to represent a particular OpenTelemetry -concept or a field of a concept. - -This document defines the transformation between OpenTelemetry and formats other -than OTLP, for OpenTelemetry fields and concepts that have no direct semantic -equivalent in those other formats. - -Note: when a format has a direct semantic equivalent for a particular field or -concept then the recommendation in this document MUST be ignored. - -See also additional specific transformation rules for -[Jaeger](../trace/sdk_exporters/jaeger.md) and [Zipkin](../trace/sdk_exporters/zipkin.md). -The specific rules for Jaeger and Zipkin take precedence over the generic rules defined -in this document. - -## Mappings - -### InstrumentationScope - -OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value -pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | Recommended | -| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | Recommended | - - -The following deprecated aliases MUST also be reported with exact same values for -backward compatibility reasons: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.library.name` | string | Deprecated, use the `otel.scope.name` attribute. | `io.opentelemetry.contrib.mongodb` | Recommended | -| `otel.library.version` | string | Deprecated, use the `otel.scope.version` attribute. | `1.0.0` | Recommended | - - -### Span Status - -Span `Status` MUST be reported as key-value pairs associated with the Span, -unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. - -The following table defines the OpenTelemetry `Status`'s mapping to Span's -key-value pairs: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | Recommended | -| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | Recommended | - -`otel.status_code` MUST be one of the following: - -| Value | Description | -|---|---| -| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | -| `ERROR` | The operation contains an error. | - - -### Dropped Attributes Count - -OpenTelemetry dropped attributes count MUST be reported as a key-value -pair associated with the corresponding data entity (e.g. Span, Span Link, Span Event, -Metric data point, LogRecord, etc). The key name MUST be `otel.dropped_attributes_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Dropped Events Count - -OpenTelemetry Span's dropped events count MUST be reported as a key-value pair -associated with the Span. The key name MUST be `otel.dropped_events_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Dropped Links Count - -OpenTelemetry Span's dropped links count MUST be reported as a key-value pair -associated with the Span. The key name MUST be `otel.dropped_links_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Instrumentation Scope Attributes - -Exporters to formats that don't have a concept that is equivalent to the Scope -SHOULD record the attributes at the most suitable place in their corresponding format, -typically at the Span, Metric or LogRecord equivalent. diff --git a/specification/common/url.md b/specification/common/url.md deleted file mode 100644 index bbe041ba67..0000000000 --- a/specification/common/url.md +++ /dev/null @@ -1,45 +0,0 @@ -# Semantic conventions for URL - -**Status**: [Experimental](../document-status.md) - -This document defines semantic conventions that describe URL and its components. - -
-Table of Contents - - - -- [Attributes](#attributes) -- [Sensitive information](#sensitive-information) - - - -
- -## Attributes - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | -| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | - -**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. - -**[2]:** When missing, the value is assumed to be `/` - -**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - - -## Sensitive information - -Capturing URL and its components MAY impose security risk. User and password information, when they are provided in [User Information](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1) subcomponent, MUST NOT be recorded. - -Instrumentations that are aware of specific sensitive query string parameters MUST scrub their values before capturing `url.query` attribute. For example, native instrumentation of a client library that passes credentials or user location in URL, must scrub corresponding properties. - -_Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ From d445ea5eec77394085f39c610eb42f700e07e709 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 7 Nov 2023 14:02:50 -0600 Subject: [PATCH 217/482] Move attribute documents --- {specification/common => docs/general}/attribute-naming.md | 0 .../common => docs/general}/attribute-requirement-level.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {specification/common => docs/general}/attribute-naming.md (100%) rename {specification/common => docs/general}/attribute-requirement-level.md (100%) diff --git a/specification/common/attribute-naming.md b/docs/general/attribute-naming.md similarity index 100% rename from specification/common/attribute-naming.md rename to docs/general/attribute-naming.md diff --git a/specification/common/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md similarity index 100% rename from specification/common/attribute-requirement-level.md rename to docs/general/attribute-requirement-level.md From 84cd08ef20d86c265ca79ec5e198dc5a592df55e Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Thu, 9 Nov 2023 09:30:19 -0600 Subject: [PATCH 218/482] Change to relative links --- docs/general/attribute-naming.md | 6 +++--- docs/general/attribute-requirement-level.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index 548703db6f..1849b09c02 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -65,7 +65,7 @@ Names SHOULD follow these rules: values: the executable name and command arguments. - When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md#pluralization) + [Metric Name Pluralization Guidelines](./metrics.md#pluralization) SHOULD be followed for the attribute name. ## Name Reuse Prohibition @@ -83,7 +83,7 @@ denote old attribute names in rename operations). of a namespace. - When coming up with a new semantic convention make sure to check existing - namespaces ([Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md)) + namespaces ([Semantic Conventions](./README.md)) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level @@ -107,7 +107,7 @@ denote old attribute names in rename operations). ## Recommendations for Application Developers As an application developer when you need to record an attribute first consult -existing [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md). +existing [semantic conventions](./README.md). If an appropriate name does not exists you will need to come up with a new name. To do that consider a few options: diff --git a/docs/general/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md index 7f510fe731..45ba93887b 100644 --- a/docs/general/attribute-requirement-level.md +++ b/docs/general/attribute-requirement-level.md @@ -1,4 +1,4 @@ -# Attribute Requirement Levels for Semantic Conventions +# Attribute Requirement Levels **Status**: [Stable](../document-status.md) @@ -35,7 +35,7 @@ For example, Metric attributes that may have high cardinality can only be define A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. -For example, [Database semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) references `network.transport` attribute defined in [General attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/README.md) with `Conditionally Required` level on it. +For example, [Database semantic convention](../database/README.md) references `network.transport` attribute defined in [General attributes](./README.md) with `Conditionally Required` level on it. ## Required @@ -52,7 +52,7 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. +For example, `server.address` is `Conditionally Required` by the [Database convention](../database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended From f183527bf7c764497b50cf6ce8694b2d3af8fb05 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Thu, 9 Nov 2023 09:48:53 -0600 Subject: [PATCH 219/482] Fix more links --- docs/general/attribute-naming.md | 4 +++- docs/general/attribute-requirement-level.md | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index 1849b09c02..a800f7bd39 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -1,6 +1,6 @@ # Attribute Naming -**Status**: [Stable](../document-status.md) +**Status**: [Stable][DocumentStatus]
Table of Contents @@ -154,3 +154,5 @@ and protocols. Any additions to the `otel.*` namespace MUST be approved as part of OpenTelemetry specification. + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md index 45ba93887b..ef8b46a0b3 100644 --- a/docs/general/attribute-requirement-level.md +++ b/docs/general/attribute-requirement-level.md @@ -1,6 +1,6 @@ # Attribute Requirement Levels -**Status**: [Stable](../document-status.md) +**Status**: [Stable][DocumentStatus]
Table of Contents @@ -19,7 +19,7 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ -Attribute requirement levels apply to the [instrumentation library](../glossary.md#instrumentation-library). +Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). The following attribute requirement levels are specified: @@ -74,3 +74,5 @@ Here are several examples of expensive operations to be avoided by default: - DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it - reading response stream to find `http.response.body.size` when `Content-Length` header is not available + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md From 1dc1e04ab61f47bd7e1c65ee5f478cfec25233da Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Fri, 10 Nov 2023 08:05:47 -0600 Subject: [PATCH 220/482] Point to 1.26.0 of specification --- docs/general/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md index ef8b46a0b3..eb89336df3 100644 --- a/docs/general/attribute-requirement-level.md +++ b/docs/general/attribute-requirement-level.md @@ -19,7 +19,7 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ -Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). +Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/glossary.md#instrumentation-library). The following attribute requirement levels are specified: From b85a0db524135dac1115c880dfb92a9e4cff1920 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Mon, 13 Nov 2023 10:44:46 -0600 Subject: [PATCH 221/482] Update spec references to point to local files --- docs/attributes-registry/README.md | 2 +- docs/resource/README.md | 2 +- model/README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 40c63bf9f5..607e9cfc88 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -49,4 +49,4 @@ Currently, the following namespaces exist: * [URL](url.md) * [User agent](user-agent.md) -[developers recommendations]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md#recommendations-for-application-developers +[developers recommendations]: ../general/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/resource/README.md b/docs/resource/README.md index 4d3e747dd6..5a12b18593 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -47,7 +47,7 @@ This document defines standard attributes for resources. These attributes are ty Attributes are grouped logically by the type of the concept that they described. Attributes in the same group have a common prefix that ends with a dot. For example all attributes that describe Kubernetes properties start with "k8s." -See [Attribute Requirement Levels](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-requirement-level.md) for details on when attributes +See [Attribute Requirement Levels](../general/attribute-requirement-level.md) for details on when attributes should be included. ## Attributes with Special Handling diff --git a/model/README.md b/model/README.md index 482c59ab14..2fc6f39b35 100644 --- a/model/README.md +++ b/model/README.md @@ -10,8 +10,8 @@ the generated markdown output in the [docs](../docs/README.md) folder. ## Writing semantic conventions Semantic conventions for the spec MUST adhere to the -[attribute naming](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md), -[attribute requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-requirement-level.md), +[attribute naming](../docs/general/attribute-naming.md), +[attribute requirement level](../docs/general/attribute-requirement-level.md), and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md) conventions. Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/syntax.md) From 4f5831ca5fc6b9e1eb4717b1c31e43e5d30a5858 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 22 Jul 2020 11:30:11 -0700 Subject: [PATCH 222/482] Centralize attributes definition (#722) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Centralize attributes definition Signed-off-by: Bogdan Drutu * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/common/common.md Co-authored-by: Christian Neumüller * Update specification/overview.md Co-authored-by: Christian Neumüller Co-authored-by: Christian Neumüller --- specification/common/common.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 specification/common/common.md diff --git a/specification/common/common.md b/specification/common/common.md new file mode 100644 index 0000000000..b8d99a5eef --- /dev/null +++ b/specification/common/common.md @@ -0,0 +1,29 @@ +# Common specification concepts + +
+ +Table of Contents + + +- [Attributes](#attribute) + +
+ +## Attributes + +Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have the following properties: + +- The attribute key, which MUST be a non-`null` and non-empty string. +- The attribute value, which is either: + - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. + - An array of primitive type values. The array MUST be homogeneous, + i.e. it MUST NOT contain values of different types. For protocols that do + not natively support array values such values SHOULD be represented as JSON strings. + +`null` values within arrays MUST be preserved as-is (i.e., passed on to span +processors / exporters as `null`). If exporters do not support exporting `null` +values, they MAY replace those values by 0, `false`, or empty strings. +This is required for map/dictionary structures represented as two arrays with +indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, +both containing an array of strings to represent a mapping +`header_keys[i] -> header_values[i]`). From 4a2a4ef946cc316e177676c03f64ea1f1c822389 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jul 2020 10:51:44 -0700 Subject: [PATCH 223/482] DocFX sanity check (#742) --- specification/common/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index b8d99a5eef..b55f47c1bb 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -5,7 +5,7 @@ Table of Contents -- [Attributes](#attribute) +- [Attributes](#attributes)
From 46b79ae1e78a970b35b03828abafbf008c65761e Mon Sep 17 00:00:00 2001 From: Giovanni Liva Date: Thu, 13 Aug 2020 19:10:46 +0200 Subject: [PATCH 224/482] Consistency between Span and Resource attributes (#777) * Consistency between Span and Resource attributes * Address feedback * Wording --- specification/common/common.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index b55f47c1bb..681721fb11 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -20,6 +20,15 @@ Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have i.e. it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. +Attributes SHOULD preserve the order in which they're set. + +Attribute values expressing a numerical value of zero, an empty string, or an +empty array are considered meaningful and MUST be stored and passed on to +processors / exporters. Attribute values of `null` are considered to be not set +and get discarded as if that `Attribute` has never been created. +As an exception to this, if overwriting of values is supported, this results in +removing the attribute. + `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. From 7a01501836e0af659eaea57f2942d963d6081a29 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 17 Aug 2020 12:40:17 -0400 Subject: [PATCH 225/482] Add conventions for attribute names (#807) * Add conventions for attribute names Resolves: https://github.com/open-telemetry/opentelemetry-specification/issues/726 * Address PR comments * Re-word company/application specific attribute recommendations --- specification/common/common.md | 88 +++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index 681721fb11..62637d5ec9 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -6,7 +6,7 @@ Table of Contents - [Attributes](#attributes) - + - [Attribute Naming](#attribute-naming)
## Attributes @@ -36,3 +36,89 @@ This is required for map/dictionary structures represented as two arrays with indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). + +### Attribute Naming + +Attribute name (also known as the "attribute key") MUST be a valid Unicode +sequence. + +Attribute names SHOULD follow these rules: + +- Use namespacing to avoid name clashes. Delimit the namespaces using a dot + character. For example `service.version` denotes the service version where + `service` is the namespace and `version` is an attribute in that namespace. + +- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside + top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute + inside `telemetry.sdk` namespace. + +- For each multi-word dot-delimited component of the attribute name separate the + words by underscores (i.e. use snake_case). For example `http.status_code` + denotes the status code in the http namespace. + +- Attribute names SHOULD NOT coincide with namespaces. For example if + `service.instance.id` is an attribute name then it is no longer valid to have + an attribute named `service.instance` because `service.instance` is already a + namespace. Because of this rule be careful when choosing attribute names: + every existing attribute name prohibits existence of an equally named + namespace in the future, and vice versa: any existing namespace prohibits + existence of an equally named attribute in the future. + +#### Recommendations for OpenTelemetry Authors + +- All attribute names that are part of OpenTelemetry semantic conventions + SHOULD be part of a namespace. + +- When coming up with a new convention make sure to check existing namespaces + for + [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), + [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), + and + [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) + to see if the new attributes fits. + +- When a new namespace is necessary consider whether it should be a top-level + namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). + +- Semantic conventions MUST limit attribute names to printable Basic Latin + characters (more precisely to + [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) + subset of Unicode code points). It is recommended to further limit attribute + names to the following Unicode code points: Latin alphabet, Numeric, + Underscore, Dot (as namespace delimiter). + +#### Recommendations for Application Developers + +As an application developer when you need to record an attribute first consult +existing semantic conventions for +[Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), +[Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), +and +[Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). +If appropriate attribute name does not exists you will need to come up with a +new name. To do that consider a few options: + +- The attribute is specific to your company and may be possibly used outside the + company as well. To avoid name clashes with attributes introduced by other + companies (in a distributed system that uses applications from multiple + vendors) it is recommended to prefix the attribute name by your company's + reverse domain name, e.g. `com.acme.shopname`. + +- The attribute is specific to your application that will be used internally + only. If you already have an internal company process that helps you to ensure + no name clashes happen then feel free to follow it. Otherwise it is + recommended to prefix the attribute name by your application name, provided + that the application name is reasonably unique within your organization (e.g. + `myuniquemapapp.longitude` is likely fine). Make sure the application name + does not clash with an existing semantic convention namespace. + +- The attribute may be generally applicable to applications in the industry. In + that case consider submitting a proposal to this specification to add a new + attribute to the semantic conventions, if necessary also to add a new + namespace for the attribute. + +It is recommended to limit attribute names to printable Basic Latin characters +(more precisely to +[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) +subset of Unicode code points). + From 3fb086c80f761c02c4ef43d9a2ddbaa36fb2f16d Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 19 Aug 2020 13:49:28 -0400 Subject: [PATCH 226/482] Extend attribute naming rules to metric labels (#821) * Extend attribute naming rules to metric labels We earlier defined naming rules for attributes, however we do not have similar rules for metric labels. This commit extends the exact same set of rules to metric labels. This was brought up in this comment https://github.com/open-telemetry/opentelemetry-specification/pull/807#discussion_r471550053 * Address PR comments --- specification/common/common.md | 95 +++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 62637d5ec9..7cedad5f3f 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -6,7 +6,7 @@ Table of Contents - [Attributes](#attributes) - - [Attribute Naming](#attribute-naming) + - [Attribute and Label Naming](#attribute-and-label-naming)
## Attributes @@ -37,12 +37,22 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -### Attribute Naming +## Attribute and Label Naming -Attribute name (also known as the "attribute key") MUST be a valid Unicode -sequence. +_This section applies to Resource, Span and Log attribute names (also known as +the "attribute keys") and to keys of Metric labels. For brevity within this +section when we use the term "name" without an adjective it is implied to mean +"attribute name or metric label key"._ -Attribute names SHOULD follow these rules: +Every name MUST be a valid Unicode sequence. + +_Note: we merely require that the names are represented as Unicode sequences. +This specification does not define how exactly the Unicode sequences are +encoded. The encoding can vary from one programming language to another and from +one wire format to another. Use the idiomatic way to represent Unicode in the +particular programming language or wire format._ + +Names SHOULD follow these rules: - Use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example `service.version` denotes the service version where @@ -56,68 +66,67 @@ Attribute names SHOULD follow these rules: words by underscores (i.e. use snake_case). For example `http.status_code` denotes the status code in the http namespace. -- Attribute names SHOULD NOT coincide with namespaces. For example if +- Names SHOULD NOT coincide with namespaces. For example if `service.instance.id` is an attribute name then it is no longer valid to have an attribute named `service.instance` because `service.instance` is already a - namespace. Because of this rule be careful when choosing attribute names: - every existing attribute name prohibits existence of an equally named - namespace in the future, and vice versa: any existing namespace prohibits - existence of an equally named attribute in the future. + namespace. Because of this rule be careful when choosing names: every existing + name prohibits existence of an equally named namespace in the future, and vice + versa: any existing namespace prohibits existence of an equally named + attribute or label key in the future. -#### Recommendations for OpenTelemetry Authors +### Recommendations for OpenTelemetry Authors -- All attribute names that are part of OpenTelemetry semantic conventions - SHOULD be part of a namespace. +- All names that are part of OpenTelemetry semantic conventions SHOULD be part + of a namespace. -- When coming up with a new convention make sure to check existing namespaces - for +- When coming up with a new semantic convention make sure to check existing + namespaces for [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), and [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) - to see if the new attributes fits. + to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). -- Semantic conventions MUST limit attribute names to printable Basic Latin - characters (more precisely to +- Semantic conventions MUST limit names to printable Basic Latin characters + (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) - subset of Unicode code points). It is recommended to further limit attribute - names to the following Unicode code points: Latin alphabet, Numeric, - Underscore, Dot (as namespace delimiter). + subset of Unicode code points). It is recommended to further limit names to + the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot + (as namespace delimiter). -#### Recommendations for Application Developers +### Recommendations for Application Developers -As an application developer when you need to record an attribute first consult -existing semantic conventions for +As an application developer when you need to record an attribute or a label +first consult existing semantic conventions for [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), and [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). -If appropriate attribute name does not exists you will need to come up with a -new name. To do that consider a few options: - -- The attribute is specific to your company and may be possibly used outside the - company as well. To avoid name clashes with attributes introduced by other - companies (in a distributed system that uses applications from multiple - vendors) it is recommended to prefix the attribute name by your company's - reverse domain name, e.g. `com.acme.shopname`. - -- The attribute is specific to your application that will be used internally - only. If you already have an internal company process that helps you to ensure - no name clashes happen then feel free to follow it. Otherwise it is - recommended to prefix the attribute name by your application name, provided - that the application name is reasonably unique within your organization (e.g. +If an appropriate name does not exists you will need to come up with a new name. +To do that consider a few options: + +- The name is specific to your company and may be possibly used outside the + company as well. To avoid clashes with names introduced by other companies (in + a distributed system that uses applications from multiple vendors) it is + recommended to prefix the new name by your company's reverse domain name, e.g. + `com.acme.shopname`. + +- The name is specific to your application that will be used internally only. If + you already have an internal company process that helps you to ensure no name + clashes happen then feel free to follow it. Otherwise it is recommended to + prefix the attribute name or label key by your application name, provided that + the application name is reasonably unique within your organization (e.g. `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. -- The attribute may be generally applicable to applications in the industry. In - that case consider submitting a proposal to this specification to add a new - attribute to the semantic conventions, if necessary also to add a new - namespace for the attribute. +- The name may be generally applicable to applications in the industry. In that + case consider submitting a proposal to this specification to add a new name to + the semantic conventions, and if necessary also to add a new namespace. -It is recommended to limit attribute names to printable Basic Latin characters +It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). From 15097436c79462b75e4b967d83516c24f935639b Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Wed, 19 Aug 2020 14:43:05 -0700 Subject: [PATCH 227/482] Fix lint check in makefile, fix errors (#837) Signed-off-by: Bogdan Drutu --- specification/common/common.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/common.md b/specification/common/common.md index 7cedad5f3f..f6a917b4cf 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,6 +7,7 @@ Table of Contents - [Attributes](#attributes) - [Attribute and Label Naming](#attribute-and-label-naming) +
## Attributes @@ -130,4 +131,3 @@ It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). - From a15b95dafa054326ac44acd23312c0b3c001ce30 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 24 Aug 2020 13:14:37 -0400 Subject: [PATCH 228/482] Require that names and namespaces are one global space across all semantic convention areas (#832) * Require that names and namespaces are one global space across all semantic convention areas We have semantic conventions for Resources, Spans and Metrics (in the future also Logs are expected). It was not clear if the attribute names across all convention areas should be globally unique. This commit asserts that conventions are one space, they are not independent spaces with their own namespaces each. We prohibit using the same Span or Resource attribute name or metric label name but give them slightly different meanings or value sets. Resolves: https://github.com/open-telemetry/opentelemetry-specification/issues/815 * Address PR comments Co-authored-by: Bogdan Drutu --- specification/common/common.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index f6a917b4cf..44f5ccf2f5 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -91,6 +91,15 @@ Names SHOULD follow these rules: - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). +- Semantic conventions exist for four areas: for Resource, Span and Log + attribute names as well as Metric label keys. In addition, for spans we have + two more areas: Event and Link attribute names. Identical namespaces or names + in all these areas MUST have identical meanings. For example the `http.method` + span attribute name denotes exactly the same concept as the `http.method` + metric label, has the same data type and the same set of possible values (in + both cases it records the value of the HTTP protocol's request method as a + string). + - Semantic conventions MUST limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) From 906beb96fc8f8c38f3d2e31c9226b7efcb279067 Mon Sep 17 00:00:00 2001 From: Armin Ruech Date: Fri, 25 Sep 2020 11:49:15 +0200 Subject: [PATCH 229/482] Define `null` as an invalid value for attributes and declare attempts to set `null` as undefined behavior (#992) --- specification/common/common.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 44f5ccf2f5..974cf51821 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -25,10 +25,10 @@ Attributes SHOULD preserve the order in which they're set. Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to -processors / exporters. Attribute values of `null` are considered to be not set -and get discarded as if that `Attribute` has never been created. -As an exception to this, if overwriting of values is supported, this results in -removing the attribute. +processors / exporters. + +Attribute values of `null` are not valid and attempting to set a `null` value is +undefined behavior. `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` From 9d54f2f42b380473bd3eae52e4048363a909e4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 4 Nov 2020 21:29:48 +0100 Subject: [PATCH 230/482] Fix absolute links to spec (#1192) * Remove absolute links where possible. * Work around semantic conventions. * Docfx. * Fix YAML. * More docfx. --- specification/common/common.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 974cf51821..0352f819ab 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -82,10 +82,10 @@ Names SHOULD follow these rules: - When coming up with a new semantic convention make sure to check existing namespaces for - [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), - [Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), + [Resources](../resource/semantic_conventions/README.md), + [Spans](../trace/semantic_conventions/README.md), and - [Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions) + [Metrics](../metrics/semantic_conventions/README.md) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level @@ -111,10 +111,10 @@ Names SHOULD follow these rules: As an application developer when you need to record an attribute or a label first consult existing semantic conventions for -[Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions), -[Spans](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions), +[Resources](../resource/semantic_conventions/README.md), +[Spans](../trace/semantic_conventions/README.md), and -[Metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/metrics/semantic_conventions). +[Metrics](../metrics/semantic_conventions/README.md). If an appropriate name does not exists you will need to come up with a new name. To do that consider a few options: From 2012c9e3864445c2dd9fbbef0103c1e8e32bbc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 10 Nov 2020 17:05:58 +0100 Subject: [PATCH 231/482] Remove ordering reqirement for attributes. (#1212) * Remove ordering for attributes. * Fill in CHANGELOG link --- specification/common/common.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 0352f819ab..fca4b007a1 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -21,8 +21,6 @@ Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have i.e. it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. -Attributes SHOULD preserve the order in which they're set. - Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors / exporters. From 501f8a108a58b0a43d3c745458affa2515b9b8f3 Mon Sep 17 00:00:00 2001 From: Przemek Maciolek <58699843+pmm-sumo@users.noreply.github.com> Date: Tue, 10 Nov 2020 21:19:52 +0100 Subject: [PATCH 232/482] Include attribute name pluralization guidelines (#1115) (#1140) --- specification/common/common.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index fca4b007a1..3a759e09e0 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,6 +7,9 @@ Table of Contents - [Attributes](#attributes) - [Attribute and Label Naming](#attribute-and-label-naming) + - [Name Pluralization Guidelines](#name-pluralization-guidelines) + - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) + - [Recommendations for Application Developers](#recommendations-for-application-developers) @@ -72,6 +75,19 @@ Names SHOULD follow these rules: name prohibits existence of an equally named namespace in the future, and vice versa: any existing namespace prohibits existence of an equally named attribute or label key in the future. + +### Name Pluralization guidelines + +- When an attribute represents a single entity, the attribute name SHOULD be singular. + Examples: `host.name`, `db.user`, `container.id`. + +- When attribute can represent multiple entities, the attribute name SHOULD be pluralized + and the value type SHOULD be an array. E.g. `process.command_args` might include multiple + values: the executable name and command arguments. + +- When an attribute represents a measurement, + [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + SHOULD be followed for the attribute name. ### Recommendations for OpenTelemetry Authors From 82b14e151c25401d0b6c660b67e1f7da32914ea3 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 10 Nov 2020 15:51:16 -0500 Subject: [PATCH 233/482] Add guidance on when to use and not use nested namespaces (#1197) This topic has come up at least 3 times now. I believe a clarification is warranted. The clarification is aligned with previous recommendations: https://github.com/open-telemetry/opentelemetry-specification/pull/789#issuecomment-675506855 https://github.com/open-telemetry/opentelemetry-specification/pull/882#issuecomment-690945900 https://github.com/open-telemetry/opentelemetry-specification/pull/1194#issuecomment-722431982 --- specification/common/common.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 3a759e09e0..15d25304c4 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -63,6 +63,10 @@ Names SHOULD follow these rules: - Namespaces can be nested. For example `telemetry.sdk` is a namespace inside top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute inside `telemetry.sdk` namespace. + Note: the fact that an entity is located within another entity is typically + not a sufficient reason for forming nested namespaces. The purpose of a + namespace is to avoid name clashes, not to indicate entity hierarchies. This + purpose should primarily drive the decision about forming nested namespaces. - For each multi-word dot-delimited component of the attribute name separate the words by underscores (i.e. use snake_case). For example `http.status_code` From ba5580577ab0a7f40001c68f7b1d676b45b74109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 11 Nov 2020 02:15:41 +0100 Subject: [PATCH 234/482] Nulls SHOULD NOT be allowed in arrays. (#1214) * Nulls SHOULD NOT be allowed in arrays. * Fill in CHANGELOG link Co-authored-by: Armin Ruech --- specification/common/common.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 15d25304c4..f1526b9518 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -31,6 +31,9 @@ processors / exporters. Attribute values of `null` are not valid and attempting to set a `null` value is undefined behavior. +`null` values SHOULD NOT be allowed in arrays. However, if it is impossible to +make sure that no `null` values are accepted +(e.g. in languages that do not have appropriate compile-time type checking), `null` values within arrays MUST be preserved as-is (i.e., passed on to span processors / exporters as `null`). If exporters do not support exporting `null` values, they MAY replace those values by 0, `false`, or empty strings. From 4c23074b10495846f67c449e8648045748203dfd Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 17 Nov 2020 16:41:56 -0500 Subject: [PATCH 235/482] Declare freeze of Trace API Specification 1.0 (#1121) * Declare freeze of Trace Specification 1.0 We want to freeze Trace specification 1.0 so that we no longer accept substantial changes (unless a fundamental problem is found in the spec). Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/1120 --- .../common/attribute-and-label-naming.md | 130 ++++++++++++++++++ specification/common/common.md | 126 +---------------- 2 files changed, 133 insertions(+), 123 deletions(-) create mode 100644 specification/common/attribute-and-label-naming.md diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md new file mode 100644 index 0000000000..d84eab4c62 --- /dev/null +++ b/specification/common/attribute-and-label-naming.md @@ -0,0 +1,130 @@ +# Attribute and Label Naming + +
+ +Table of Contents + + +- [Name Pluralization Guidelines](#name-pluralization-guidelines) +- [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) +- [Recommendations for Application Developers](#recommendations-for-application-developers) + +
+ +_This section applies to Resource, Span and Log attribute names (also known as +the "attribute keys") and to keys of Metric labels. For brevity within this +section when we use the term "name" without an adjective it is implied to mean +"attribute name or metric label key"._ + +Every name MUST be a valid Unicode sequence. + +_Note: we merely require that the names are represented as Unicode sequences. +This specification does not define how exactly the Unicode sequences are +encoded. The encoding can vary from one programming language to another and from +one wire format to another. Use the idiomatic way to represent Unicode in the +particular programming language or wire format._ + +Names SHOULD follow these rules: + +- Use namespacing to avoid name clashes. Delimit the namespaces using a dot + character. For example `service.version` denotes the service version where + `service` is the namespace and `version` is an attribute in that namespace. + +- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside + top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute + inside `telemetry.sdk` namespace. + Note: the fact that an entity is located within another entity is typically + not a sufficient reason for forming nested namespaces. The purpose of a + namespace is to avoid name clashes, not to indicate entity hierarchies. This + purpose should primarily drive the decision about forming nested namespaces. + +- For each multi-word dot-delimited component of the attribute name separate the + words by underscores (i.e. use snake_case). For example `http.status_code` + denotes the status code in the http namespace. + +- Names SHOULD NOT coincide with namespaces. For example if + `service.instance.id` is an attribute name then it is no longer valid to have + an attribute named `service.instance` because `service.instance` is already a + namespace. Because of this rule be careful when choosing names: every existing + name prohibits existence of an equally named namespace in the future, and vice + versa: any existing namespace prohibits existence of an equally named + attribute or label key in the future. + +## Name Pluralization guidelines + +- When an attribute represents a single entity, the attribute name SHOULD be singular. + Examples: `host.name`, `db.user`, `container.id`. + +- When attribute can represent multiple entities, the attribute name SHOULD be pluralized + and the value type SHOULD be an array. E.g. `process.command_args` might include multiple + values: the executable name and command arguments. + +- When an attribute represents a measurement, + [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + SHOULD be followed for the attribute name. + +## Recommendations for OpenTelemetry Authors + +- All names that are part of OpenTelemetry semantic conventions SHOULD be part + of a namespace. + +- When coming up with a new semantic convention make sure to check existing + namespaces for + [Resources](../resource/semantic_conventions/README.md), + [Spans](../trace/semantic_conventions/README.md), + and + [Metrics](../metrics/semantic_conventions/README.md) + to see if the new name fits. + +- When a new namespace is necessary consider whether it should be a top-level + namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). + +- Semantic conventions exist for four areas: for Resource, Span and Log + attribute names as well as Metric label keys. In addition, for spans we have + two more areas: Event and Link attribute names. Identical namespaces or names + in all these areas MUST have identical meanings. For example the `http.method` + span attribute name denotes exactly the same concept as the `http.method` + metric label, has the same data type and the same set of possible values (in + both cases it records the value of the HTTP protocol's request method as a + string). + +- Semantic conventions MUST limit names to printable Basic Latin characters + (more precisely to + [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) + subset of Unicode code points). It is recommended to further limit names to + the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot + (as namespace delimiter). + +## Recommendations for Application Developers + +As an application developer when you need to record an attribute or a label +first consult existing semantic conventions for +[Resources](../resource/semantic_conventions/README.md), +[Spans](../trace/semantic_conventions/README.md), +and +[Metrics](../metrics/semantic_conventions/README.md). +If an appropriate name does not exists you will need to come up with a new name. +To do that consider a few options: + +- The name is specific to your company and may be possibly used outside the + company as well. To avoid clashes with names introduced by other companies (in + a distributed system that uses applications from multiple vendors) it is + recommended to prefix the new name by your company's reverse domain name, e.g. + `com.acme.shopname`. + +- The name is specific to your application that will be used internally only. If + you already have an internal company process that helps you to ensure no name + clashes happen then feel free to follow it. Otherwise it is recommended to + prefix the attribute name or label key by your application name, provided that + the application name is reasonably unique within your organization (e.g. + `myuniquemapapp.longitude` is likely fine). Make sure the application name + does not clash with an existing semantic convention namespace. + +- The name may be generally applicable to applications in the industry. In that + case consider submitting a proposal to this specification to add a new name to + the semantic conventions, and if necessary also to add a new namespace. + +It is recommended to limit names to printable Basic Latin characters +(more precisely to +[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) +subset of Unicode code points). diff --git a/specification/common/common.md b/specification/common/common.md index f1526b9518..51ce946c48 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -1,15 +1,13 @@ # Common specification concepts +**Status**: [Feature-freeze](../document-status.md). +
Table of Contents - [Attributes](#attributes) - - [Attribute and Label Naming](#attribute-and-label-naming) - - [Name Pluralization Guidelines](#name-pluralization-guidelines) - - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - - [Recommendations for Application Developers](#recommendations-for-application-developers)
@@ -42,122 +40,4 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -## Attribute and Label Naming - -_This section applies to Resource, Span and Log attribute names (also known as -the "attribute keys") and to keys of Metric labels. For brevity within this -section when we use the term "name" without an adjective it is implied to mean -"attribute name or metric label key"._ - -Every name MUST be a valid Unicode sequence. - -_Note: we merely require that the names are represented as Unicode sequences. -This specification does not define how exactly the Unicode sequences are -encoded. The encoding can vary from one programming language to another and from -one wire format to another. Use the idiomatic way to represent Unicode in the -particular programming language or wire format._ - -Names SHOULD follow these rules: - -- Use namespacing to avoid name clashes. Delimit the namespaces using a dot - character. For example `service.version` denotes the service version where - `service` is the namespace and `version` is an attribute in that namespace. - -- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside - top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute - inside `telemetry.sdk` namespace. - Note: the fact that an entity is located within another entity is typically - not a sufficient reason for forming nested namespaces. The purpose of a - namespace is to avoid name clashes, not to indicate entity hierarchies. This - purpose should primarily drive the decision about forming nested namespaces. - -- For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.status_code` - denotes the status code in the http namespace. - -- Names SHOULD NOT coincide with namespaces. For example if - `service.instance.id` is an attribute name then it is no longer valid to have - an attribute named `service.instance` because `service.instance` is already a - namespace. Because of this rule be careful when choosing names: every existing - name prohibits existence of an equally named namespace in the future, and vice - versa: any existing namespace prohibits existence of an equally named - attribute or label key in the future. - -### Name Pluralization guidelines - -- When an attribute represents a single entity, the attribute name SHOULD be singular. - Examples: `host.name`, `db.user`, `container.id`. - -- When attribute can represent multiple entities, the attribute name SHOULD be pluralized - and the value type SHOULD be an array. E.g. `process.command_args` might include multiple - values: the executable name and command arguments. - -- When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) - SHOULD be followed for the attribute name. - -### Recommendations for OpenTelemetry Authors - -- All names that are part of OpenTelemetry semantic conventions SHOULD be part - of a namespace. - -- When coming up with a new semantic convention make sure to check existing - namespaces for - [Resources](../resource/semantic_conventions/README.md), - [Spans](../trace/semantic_conventions/README.md), - and - [Metrics](../metrics/semantic_conventions/README.md) - to see if the new name fits. - -- When a new namespace is necessary consider whether it should be a top-level - namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). - -- Semantic conventions exist for four areas: for Resource, Span and Log - attribute names as well as Metric label keys. In addition, for spans we have - two more areas: Event and Link attribute names. Identical namespaces or names - in all these areas MUST have identical meanings. For example the `http.method` - span attribute name denotes exactly the same concept as the `http.method` - metric label, has the same data type and the same set of possible values (in - both cases it records the value of the HTTP protocol's request method as a - string). - -- Semantic conventions MUST limit names to printable Basic Latin characters - (more precisely to - [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) - subset of Unicode code points). It is recommended to further limit names to - the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot - (as namespace delimiter). - -### Recommendations for Application Developers - -As an application developer when you need to record an attribute or a label -first consult existing semantic conventions for -[Resources](../resource/semantic_conventions/README.md), -[Spans](../trace/semantic_conventions/README.md), -and -[Metrics](../metrics/semantic_conventions/README.md). -If an appropriate name does not exists you will need to come up with a new name. -To do that consider a few options: - -- The name is specific to your company and may be possibly used outside the - company as well. To avoid clashes with names introduced by other companies (in - a distributed system that uses applications from multiple vendors) it is - recommended to prefix the new name by your company's reverse domain name, e.g. - `com.acme.shopname`. - -- The name is specific to your application that will be used internally only. If - you already have an internal company process that helps you to ensure no name - clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name or label key by your application name, provided that - the application name is reasonably unique within your organization (e.g. - `myuniquemapapp.longitude` is likely fine). Make sure the application name - does not clash with an existing semantic convention namespace. - -- The name may be generally applicable to applications in the industry. In that - case consider submitting a proposal to this specification to add a new name to - the semantic conventions, and if necessary also to add a new namespace. - -It is recommended to limit names to printable Basic Latin characters -(more precisely to -[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) -subset of Unicode code points). +See [Attribute and Label Naming](attribute-and-label-naming.md) for naming guidelines. From 8de36bfb30587f84109db6cc4daa27f9a6e818a9 Mon Sep 17 00:00:00 2001 From: Ted Young Date: Thu, 4 Feb 2021 06:06:46 -0800 Subject: [PATCH 236/482] Add lifecycle statuses to all documents (#1385) --- specification/common/attribute-and-label-naming.md | 2 ++ specification/common/common.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md index d84eab4c62..0a9e3356e8 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-and-label-naming.md @@ -1,5 +1,7 @@ # Attribute and Label Naming +**Status**: [Experimental](../document-status.md) +
Table of Contents diff --git a/specification/common/common.md b/specification/common/common.md index 51ce946c48..203a25b912 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -1,6 +1,6 @@ # Common specification concepts -**Status**: [Feature-freeze](../document-status.md). +**Status**: [Stable, Feature-freeze](../document-status.md)
From cb6ead3c7a2eb3e523bf7196a33253b6653ac2d0 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 28 Apr 2021 10:38:46 -0400 Subject: [PATCH 237/482] Clarify usage of "otel." attribute namespace (#1640) I noticed developers adding their own attributes to this namespace without going through the specification. We need to regulate this namespace through the specification, just like we do it for other semantic conventions. --- specification/common/attribute-and-label-naming.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-and-label-naming.md index 0a9e3356e8..6ebe80ed2f 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-and-label-naming.md @@ -130,3 +130,17 @@ It is recommended to limit names to printable Basic Latin characters (more precisely to [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) subset of Unicode code points). + +## otel.* Namespace + +Attribute and label names that start with `otel.` are reserved to be defined by +OpenTelemetry specification. These are typically used to express OpenTelemetry +concepts in formats that don't have a corresponding concept. + +For example, the `otel.library.name` attribute is used to record the +instrumentation library name, which is an OpenTelemetry concept that is natively +represented in OTLP, but does not have an equivalent in other telemetry formats +and protocols. + +Any additions to the `otel.*` namespace MUST be approved as part of +OpenTelemetry specification. From c37549e1d8997e07c158219540d115c225f6a50f Mon Sep 17 00:00:00 2001 From: Jakub Malinowski Date: Thu, 1 Jul 2021 00:11:54 +0200 Subject: [PATCH 238/482] Rename Metrics labels to attributes (#1775) --- ...nd-label-naming.md => attribute-naming.md} | 36 +++++++++---------- specification/common/common.md | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) rename specification/common/{attribute-and-label-naming.md => attribute-naming.md} (84%) diff --git a/specification/common/attribute-and-label-naming.md b/specification/common/attribute-naming.md similarity index 84% rename from specification/common/attribute-and-label-naming.md rename to specification/common/attribute-naming.md index 6ebe80ed2f..6599f6b239 100644 --- a/specification/common/attribute-and-label-naming.md +++ b/specification/common/attribute-naming.md @@ -1,4 +1,4 @@ -# Attribute and Label Naming +# Attribute Naming **Status**: [Experimental](../document-status.md) @@ -13,10 +13,9 @@ Table of Contents
-_This section applies to Resource, Span and Log attribute names (also known as -the "attribute keys") and to keys of Metric labels. For brevity within this -section when we use the term "name" without an adjective it is implied to mean -"attribute name or metric label key"._ +_This section applies to Resource, Span, Log, and Metric attribute names (also +known as the "attribute keys"). For brevity within this section when we use the +term "name" without an adjective it is implied to mean "attribute name"._ Every name MUST be a valid Unicode sequence. @@ -50,8 +49,8 @@ Names SHOULD follow these rules: namespace. Because of this rule be careful when choosing names: every existing name prohibits existence of an equally named namespace in the future, and vice versa: any existing namespace prohibits existence of an equally named - attribute or label key in the future. - + attribute key in the future. + ## Name Pluralization guidelines - When an attribute represents a single entity, the attribute name SHOULD be singular. @@ -81,14 +80,13 @@ Names SHOULD follow these rules: - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). -- Semantic conventions exist for four areas: for Resource, Span and Log - attribute names as well as Metric label keys. In addition, for spans we have - two more areas: Event and Link attribute names. Identical namespaces or names - in all these areas MUST have identical meanings. For example the `http.method` - span attribute name denotes exactly the same concept as the `http.method` - metric label, has the same data type and the same set of possible values (in - both cases it records the value of the HTTP protocol's request method as a - string). +- Semantic conventions exist for four areas: for Resource, Span, Log, and Metric + attribute names. In addition, for spans we have two more areas: Event and Link + attribute names. Identical namespaces or names in all these areas MUST have + identical meanings. For example the `http.method` span attribute name denotes + exactly the same concept as the `http.method` metric attribute, has the same + data type and the same set of possible values (in both cases it records the + value of the HTTP protocol's request method as a string). - Semantic conventions MUST limit names to printable Basic Latin characters (more precisely to @@ -99,8 +97,8 @@ Names SHOULD follow these rules: ## Recommendations for Application Developers -As an application developer when you need to record an attribute or a label -first consult existing semantic conventions for +As an application developer when you need to record an attribute first consult +existing semantic conventions for [Resources](../resource/semantic_conventions/README.md), [Spans](../trace/semantic_conventions/README.md), and @@ -117,7 +115,7 @@ To do that consider a few options: - The name is specific to your application that will be used internally only. If you already have an internal company process that helps you to ensure no name clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name or label key by your application name, provided that + prefix the attribute name by your application name, provided that the application name is reasonably unique within your organization (e.g. `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. @@ -133,7 +131,7 @@ subset of Unicode code points). ## otel.* Namespace -Attribute and label names that start with `otel.` are reserved to be defined by +Attribute names that start with `otel.` are reserved to be defined by OpenTelemetry specification. These are typically used to express OpenTelemetry concepts in formats that don't have a corresponding concept. diff --git a/specification/common/common.md b/specification/common/common.md index 203a25b912..1b34c4f9f8 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -40,4 +40,4 @@ indices that are kept in sync (e.g., two attributes `header_keys` and `header_va both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). -See [Attribute and Label Naming](attribute-and-label-naming.md) for naming guidelines. +See [Attribute Naming](attribute-naming.md) for naming guidelines. From 43e0a08c24a2eef9894c0086e1fe404202b7b245 Mon Sep 17 00:00:00 2001 From: Jakub Malinowski Date: Wed, 4 Aug 2021 00:26:10 +0200 Subject: [PATCH 239/482] Add an option to limit length of values of attributes and metric values (#1130) --- specification/common/common.md | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 1b34c4f9f8..6cb26c12f9 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -8,6 +8,8 @@ Table of Contents
- [Attributes](#attributes) + - [Attribute Limits](#attribute-limits) + - [Exempt Entities](#exempt-entities)
@@ -41,3 +43,52 @@ both containing an array of strings to represent a mapping `header_keys[i] -> header_values[i]`). See [Attribute Naming](attribute-naming.md) for naming guidelines. + +### Attribute Limits + +Execution of erroneous code can result in unintended attributes. If there are no +limits placed on attributes, they can quickly exhaust available memory, resulting +in crashes that are difficult to recover from safely. + +By default an SDK SHOULD apply truncation as per the list of +[configurable parameters](#attribute-limits-configuration) below. + +If an SDK provides a way to: + +- set an attribute value length limit such that for each + attribute value: + - if it is a string, if it exceeds that limit (counting any character in it as + 1), SDKs MUST truncate that value, so that its length is at most equal + to the limit, + - if it is an array of strings, then apply the above rule to each of the + values separately, + - otherwise a value MUST NOT be truncated; +- set a limit of unique attribute keys such that: + - for each unique attributes key, addition of which would result in exceeding + the limit, SDK MUST discard that key/value pair. + +There MAY be a log emitted to indicate to the user that an attribute was +truncated or discarded. To prevent excessive logging, the log MUST NOT be +emitted more than once per record on which an attribute is set. + +If the SDK implements the limits above, it MUST provide a way to change these +limits programmatically. Names of the configuration options SHOULD be the same as +in the list below. + +An SDK MAY implement model-specific limits, for example +`SpanAttributeCountLimit`. If both a general and a model-specific limit are +implemented, then the SDK MUST first attempt to use the model-specific limit, if +it isn't set and doesn't have a default, then the SDK MUST attempt to use the +general limit. + + +**Configurable parameters:** + +* `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; +* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; + +#### Exempt Entities + +Attributes, which belong to Metrics, are exempt from the limits described above +at this time, as discussed in +[Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). From 36ebbcad536af547f8f0da1a010433f7823cf276 Mon Sep 17 00:00:00 2001 From: Owais Lone Date: Tue, 14 Sep 2021 16:40:45 +0530 Subject: [PATCH 240/482] Prefer global limit over model-specific default (#1893) --- specification/common/common.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 6cb26c12f9..c3f434aa89 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -78,8 +78,9 @@ in the list below. An SDK MAY implement model-specific limits, for example `SpanAttributeCountLimit`. If both a general and a model-specific limit are implemented, then the SDK MUST first attempt to use the model-specific limit, if -it isn't set and doesn't have a default, then the SDK MUST attempt to use the -general limit. +it isn't set, then the SDK MUST attempt to use the general limit. If neither are +defined, then the SDK MUST try to use the model-specific limit default value, +followed by the global limit default value. **Configurable parameters:** From 19e4040e36a8d5d10459baf339879eefe51b2919 Mon Sep 17 00:00:00 2001 From: Owais Lone Date: Thu, 23 Sep 2021 05:19:00 +0530 Subject: [PATCH 241/482] Exempt resources from attribute limits (#1892) Resources are not susceptible to scenarios where excessive attributes can be recorded unlike Spans. Resources are also immutable and it can be hard for some SDKs to apply the limits at source at the time the attributes are added to a resource. Furthermore, limits and Resources both are generally defined and passed on to a TracerProvider which forces a TracerProvider to either mutate the resource or generate a new one with duplicate attributes in order to apply the limits to it. Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> --- specification/common/common.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index c3f434aa89..b0779ad652 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -90,6 +90,14 @@ followed by the global limit default value. #### Exempt Entities +Resource attributes SHOULD be exempt from the limits described above as resources +are not susceptible to the scenarios (auto-instrumentation) that result in +excessive attributes count or size. Resources are also sent only once per batch +instead of per span so it is relatively cheaper to have more/larger attributes +on them. Resources are also immutable by design and they are generally passed +down to TracerProvider along with limits. This makes it awkward to implement +attribute limits for Resources. + Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). From 6c59f11a4aef0ee0506a4f6cda2e18cea9f33b23 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 16 Nov 2021 10:05:01 -0500 Subject: [PATCH 242/482] Provide a normative definition of Attribute (singular) rather than Attributes (plural) (#2123) * Provide a normative definition of Attribute (singular) - Providing a normative definition of **attribute** (singular) - Other copyedits /cc @austinlparker @tedsuo * Move anchor to make markdown checker happy --- specification/common/common.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index b0779ad652..19d3d87eb7 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -7,21 +7,23 @@ Table of Contents -- [Attributes](#attributes) +- [Attribute](#attribute) - [Attribute Limits](#attribute-limits) - [Exempt Entities](#exempt-entities) -## Attributes +## Attribute -Attributes are a list of zero or more key-value pairs. An `Attribute` MUST have the following properties: + -- The attribute key, which MUST be a non-`null` and non-empty string. -- The attribute value, which is either: +An `Attribute` is a key-value pair, which MUST have the following properties: + +- The attribute key MUST be a non-`null` and non-empty string. +- The attribute value is either: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, - i.e. it MUST NOT contain values of different types. For protocols that do + i.e., it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. Attribute values expressing a numerical value of zero, an empty string, or an @@ -64,7 +66,7 @@ If an SDK provides a way to: values separately, - otherwise a value MUST NOT be truncated; - set a limit of unique attribute keys such that: - - for each unique attributes key, addition of which would result in exceeding + - for each unique attribute key, addition of which would result in exceeding the limit, SDK MUST discard that key/value pair. There MAY be a log emitted to indicate to the user that an attribute was From 70eaeee2aa18d7fae80e01038fade6a0791c4fe1 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 24 Nov 2021 09:57:38 -0500 Subject: [PATCH 243/482] Ensure all ToCs are generated using markdown-toc (#2146) --- specification/common/attribute-naming.md | 11 +++++++---- specification/common/common.md | 12 +++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 6599f6b239..1cf593b9f7 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -3,13 +3,16 @@ **Status**: [Experimental](../document-status.md)
- -Table of Contents - +Table of Contents -- [Name Pluralization Guidelines](#name-pluralization-guidelines) + + +- [Name Pluralization guidelines](#name-pluralization-guidelines) - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - [Recommendations for Application Developers](#recommendations-for-application-developers) +- [otel.* Namespace](#otel-namespace) + +
diff --git a/specification/common/common.md b/specification/common/common.md index 19d3d87eb7..3e5f170456 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -3,13 +3,15 @@ **Status**: [Stable, Feature-freeze](../document-status.md)
- -Table of Contents - +Table of Contents + + - [Attribute](#attribute) - - [Attribute Limits](#attribute-limits) - - [Exempt Entities](#exempt-entities) + * [Attribute Limits](#attribute-limits) + + [Exempt Entities](#exempt-entities) + +
From 22b6b073e3c50eb0adeac22fde7d61d465cd1f76 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 13 Dec 2021 13:04:41 -0500 Subject: [PATCH 244/482] Prohibit usage of retired names in semantic conventions (#2191) * Prohibit usage of retired names in semantic conventions This change adds a prohibition clause that requires that no old metric or attribute name is used for a new attribute. This is important to ensure reversibility of schema transformation (converting from a new version to an old version of schema). Without this restriction the following is possible: Schema version 1. Attribute A exists. Schema version 2. Attribute A is renamed to B. Appropriate schema file is created. Schema version 3. Attribute A is introduced (a completely different new attribute). Now attempting to go from Version 3 to version 1 is impossible since it requires renaming B to A (for the change in version 2), but a different attribute A already exists. * Fix based on comments * Add changelog entry Co-authored-by: Carlos Alberto Cortez --- specification/common/attribute-naming.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 1cf593b9f7..9cd2f187b5 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -8,6 +8,7 @@ - [Name Pluralization guidelines](#name-pluralization-guidelines) +- [Name Reuse Prohibition](#name-reuse-prohibition) - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - [Recommendations for Application Developers](#recommendations-for-application-developers) - [otel.* Namespace](#otel-namespace) @@ -67,6 +68,15 @@ Names SHOULD follow these rules: [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) SHOULD be followed for the attribute name. +## Name Reuse Prohibition + +A new attribute MUST NOT be added with the same name as an attribute that +existed in the past but was renamed (with a corresponding schema file). + +When introducing a new attribute name check all existing schema files to make +sure the name does not appear as a key of any "rename_attributes" section (keys +denote old attribute names in rename operations). + ## Recommendations for OpenTelemetry Authors - All names that are part of OpenTelemetry semantic conventions SHOULD be part From c948e38726d43e8ddbbd10d95f111118fe9d0522 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Wed, 26 Jan 2022 16:47:43 -0500 Subject: [PATCH 245/482] Clarify that attribute keys are unique in collections (#2248) Attributes keys must be unique. The key/value pair collections in the specification was always intended to model a map. There was a recent confusion about this. This change clarifies the spec. Resolves https://github.com/open-telemetry/opentelemetry-specification/issues/2245 --- specification/common/common.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/specification/common/common.md b/specification/common/common.md index 3e5f170456..f098255a22 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -10,6 +10,7 @@ - [Attribute](#attribute) * [Attribute Limits](#attribute-limits) + [Exempt Entities](#exempt-entities) +- [Attribute Collections](#attribute-collections) @@ -105,3 +106,35 @@ attribute limits for Resources. Attributes, which belong to Metrics, are exempt from the limits described above at this time, as discussed in [Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). + +## Attribute Collections + +[Resources](../resource/sdk.md), Metrics +[data points](../metrics/datamodel.md#metric-points), +[Spans](../trace/api.md#set-attributes), Span +[Events](../trace/api.md#add-events), Span +[Links](../trace/api.md#specifying-links) and +[Log Records](../logs/data-model.md) may contain a collection of attributes. The +keys in each such collection are unique, i.e. there MUST NOT exist more than one +key-value pair with the same key. The enforcement of uniqueness may be performed +in a variety of ways as it best fits the limitations of the particular +implementation. + +Normally for the telemetry generated using OpenTelemetry SDKs the attribute +key-value pairs are set via an API that either accepts a single key-value pair +or a collection of key-value pairs. Setting an attribute with the same key as an +existing attribute SHOULD overwrite the existing attribute's value. See for +example Span's [SetAttribute](../trace/api.md#set-attributes) API. + +A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API +will enforce the uniqueness by overwriting any existing attribute values pending +to be exported, so that when the Span is eventually exported the exporters see +only unique attributes. The OTLP format in particular requires that exported +Resources, Spans, Metric data points and Log Records contain only unique +attributes. + +Some other implementations may use a streaming approach where every +[SetAttribute](../trace/api.md#set-attributes) API call immediately results in +that individual attribute value being exported using a streaming wire protocol. +In such cases the enforcement of uniqueness will likely be the responsibility of +the recipient of this data. From 132fd6aa149ca1fe2e3cc0e89e65260922f8b31c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 15 Feb 2022 11:34:11 -0500 Subject: [PATCH 246/482] Clarify that Trace/Meter are associated with Instrumentation Scope (#2276) * Clarify that Trace/Meter are associated with Instrumentation Scope This is a slightly different take on https://github.com/open-telemetry/opentelemetry-specification/issues/2203 Instead of renaming instrumentation library to instrumentation scope everywhere this PR suggests targetted editing of wording of the Trace/Meter obtaining API to allow not just instrumentation library but other instrumentation scopes to be used as a parameter. This change does not force renaming of API parameters and is not a breaking change. We consider it a clarification of usage to match the intent that we had for the "name" field. If this PR is accepted there will be a follow up PR that will suggest to rename InstrumentationLibrary* messages in OTLP proto to InstrumentationScope* message. Such a change will not be a breaking change for the OTLP wire format and is acceptable. If this PR is accepted we will also close https://github.com/open-telemetry/opentelemetry-specification/pull/1236 since it will be no longer necessary. The logger name will be recorded as the instrumentation scope. This clarification will be a follow up PR that clarifies the behavior in https://github.com/open-telemetry/oteps/blob/main/text/logs/0150-logging-library-sdk.md --- specification/common/attribute-naming.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 9cd2f187b5..fecbf3b21b 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -148,8 +148,8 @@ Attribute names that start with `otel.` are reserved to be defined by OpenTelemetry specification. These are typically used to express OpenTelemetry concepts in formats that don't have a corresponding concept. -For example, the `otel.library.name` attribute is used to record the -instrumentation library name, which is an OpenTelemetry concept that is natively +For example, the `otel.scope.name` attribute is used to record the +instrumentation scope name, which is an OpenTelemetry concept that is natively represented in OTLP, but does not have an equivalent in other telemetry formats and protocols. From 5f93caf5bbe8a04a203ccc1158b600baa5ff0f8e Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Thu, 3 Mar 2022 00:30:53 -0500 Subject: [PATCH 247/482] Describe how to convert non-string primitives for protocols which only support strings (#2343) * Describe how to handle converting non-string primitives for protocols that only support strings * update wording to make clear that only non-string values are converted to strings * unify language * Update specification/common/common.md Co-authored-by: Joshua MacDonald Co-authored-by: Joshua MacDonald Co-authored-by: Bogdan Drutu --- specification/common/common.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index f098255a22..80a13012f4 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -26,8 +26,9 @@ An `Attribute` is a key-value pair, which MUST have the following properties: - The attribute value is either: - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - An array of primitive type values. The array MUST be homogeneous, - i.e., it MUST NOT contain values of different types. For protocols that do - not natively support array values such values SHOULD be represented as JSON strings. + i.e., it MUST NOT contain values of different types. + +For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to From ec4cee89aef97ffa7f807fc7dcc04d1046e52c7c Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 21 Mar 2022 23:05:45 -0700 Subject: [PATCH 248/482] Fix links (#2426) --- specification/common/common.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/common/common.md b/specification/common/common.md index 80a13012f4..774c236130 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -9,6 +9,7 @@ - [Attribute](#attribute) * [Attribute Limits](#attribute-limits) + + [Configurable Parameters](#configurable-parameters) + [Exempt Entities](#exempt-entities) - [Attribute Collections](#attribute-collections) @@ -57,7 +58,7 @@ limits placed on attributes, they can quickly exhaust available memory, resultin in crashes that are difficult to recover from safely. By default an SDK SHOULD apply truncation as per the list of -[configurable parameters](#attribute-limits-configuration) below. +[configurable parameters](#configurable-parameters) below. If an SDK provides a way to: @@ -88,8 +89,7 @@ it isn't set, then the SDK MUST attempt to use the general limit. If neither are defined, then the SDK MUST try to use the model-specific limit default value, followed by the global limit default value. - -**Configurable parameters:** +#### Configurable Parameters * `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; * `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; From b5306f3db2de7b46a746bbba4f3893bc5cb6f3f5 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Tue, 22 Mar 2022 08:59:37 -0400 Subject: [PATCH 249/482] Implement OTEP 0178: Mapping external data to AnyValue (#2385) OTEP 0178 [0] proposed this mapping. This PR merges the proposal into specification. The content of this PR is mostly copy/paste of the text of the OTEP minus the irrelevant sections such as "Alternates", etc. 0 - https://github.com/open-telemetry/oteps/blob/main/text/0178-mapping-to-otlp-anyvalue.md --- .../common/attribute-type-mapping.md | 255 ++++++++++++++++++ specification/common/common.md | 3 + 2 files changed, 258 insertions(+) create mode 100644 specification/common/attribute-type-mapping.md diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md new file mode 100644 index 0000000000..46a25c1504 --- /dev/null +++ b/specification/common/attribute-type-mapping.md @@ -0,0 +1,255 @@ +# Mapping Arbitrary Data to OTLP AnyValue + +**Status**: [Experimental](../document-status.md) + +
+Table of Contents + + + +- [Converting to AnyValue](#converting-to-anyvalue) + * [Primitive Values](#primitive-values) + + [Integer Values](#integer-values) + + [Enumerations](#enumerations) + + [Floating Point Values](#floating-point-values) + + [String Values](#string-values) + + [Byte Sequences](#byte-sequences) + * [Composite Values](#composite-values) + + [Array Values](#array-values) + + [Associative Arrays With Unique Keys](#associative-arrays-with-unique-keys) + + [Associative Arrays With Non-Unique Keys](#associative-arrays-with-non-unique-keys) + + [Sets](#sets) + * [Other Values](#other-values) + * [Empty Values](#empty-values) + + + +
+ +This document defines how to map (convert) arbitrary data (e.g. in-memory +objects) to OTLP's [AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/cc4ed55c082cb75e084d40b4ddf3805eda099f97/opentelemetry/proto/common/v1/common.proto#L27). + +The mapping is needed when OpenTelemetry needs to convert a value produced outside +OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be +converted to be used inside OpenTelemetry boundaries. Example use cases are the following: + +- In [Logging Library SDK](../logs/logging-library-sdk.md)s, to convert values received + from logging libraries into OpenTelemetry representation. +- In the Collector, to convert values received from various data sources into + [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) + internal representation. + +## Converting to AnyValue + +[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L27) +is capable of representing primitive and structured data of certain types. + +Implementations that have source data in any form, such as in-memory objects +or data coming from other formats that needs to be converted to AnyValue SHOULD +follow the rules described below. + +### Primitive Values + +#### Integer Values + +Integer values which are within the range of 64 bit signed numbers +[-2^63..2^63-1] SHOULD be converted to AnyValue's +[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) +field. + +Integer values which are outside the range of 64 bit signed numbers SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field using decimal representation. + +#### Enumerations + +Values, which belong to a limited enumerated set (e.g. a Java +[enum](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)), SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field with the value of the string set to the symbolic name of the enumeration. + +If it is not possible to obtain the symbolic name of the enumeration, the +implementation SHOULD map enumeration values to AnyValue's +[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) +field set to the enum's ordinal value, when such an ordinal number is naturally +obtainable. + +If it is also not possible to obtain the ordinal value, the enumeration SHOULD be +converted to AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field in any manner that the implementation deems reasonable. + +#### Floating Point Values + +Floating point values which are within the range and precision of IEEE 754 +64-bit floating point numbers (including IEEE 32-bit floating point values) +SHOULD be converted to AnyValue's +[double_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L34) +field. + +Floating point values which are outside the range or precision of IEEE 754 +64-bit floating point numbers (e.g. IEEE 128-bit floating bit values) SHOULD be +converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field using decimal floating point representation. + +#### String Values + +String values which are valid UTF-8 sequences SHOULD be converted to +AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field. + +String values which are not valid Unicode sequences SHOULD be converted to +AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +with the bytes representing the string in the original order and format of the +source string. + +#### Byte Sequences + +Byte sequences (e.g. Go's `[]byte` slice or raw byte content of a file) SHOULD +be converted to AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field. + +### Composite Values + +#### Array Values + +Values that represent ordered sequences of other values (such as +[arrays](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html), +[vectors](https://en.cppreference.com/w/cpp/container/vector), ordered +[lists](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), +[slices](https://golang.org/ref/spec#Slice_types)) SHOULD be converted to +AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field. String values and byte sequences are an exception from this rule (see +above). + +The rules described in this document should be applied recursively to each element +of the array. + +#### Associative Arrays With Unique Keys + +Values that represent associative arrays with unique keys (also often known +as maps, dictionaries or key-value stores) SHOULD be converted to AnyValue's +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field. + +If the keys of the source array are not strings, they MUST be converted to +strings by any means available, often via a toString() or stringify functions +available in programming languages. The conversion function MUST be chosen in a +way that ensures that the resulting string keys are unique in the target array. + +The value part of each element of the source array SHOULD be converted to +AnyValue recursively. + +For example a JSON object `{"a": 123, "b": "def"}` SHOULD be converted to + +``` +AnyValue{ + kvlist_value:KeyValueList{ + values:[ + KeyValue{key:"a",value:AnyValue{int_value:123}}, + KeyValue{key:"b",value:AnyValue{string_value:"def"}}, + ] + } +} +``` + +The rules described in this document should be applied recursively to each value +of the associative array. + +#### Associative Arrays With Non-Unique Keys + +Values that represent an associative arrays with non-unique keys where multiple values may be associated with the same key (also sometimes known +as multimaps, multidicts) SHOULD be converted to AnyValue's +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field. + +The resulting +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field MUST list each key only once and the value of each element of +[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) +field MUST be an array represented using AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field, each element of the +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +representing one value of source array associated with the given key. + +For example an associative array shown in the following table: + +|Key|Value| +|---|---| +|"abc"|123| +|"def"|"foo"| +|"def"|"bar"| + +SHOULD be converted to: + +``` +AnyValue{ + kvlist_value:KeyValueList{ + values:[ + KeyValue{ + key:"abc", + value:AnyValue{array_value:ArrayValue{values[ + AnyValue{int_value:123} + ]}} + }, + KeyValue{ + key:"def", + value:AnyValue{array_value:ArrayValue{values[ + AnyValue{string_value:"foo"}, + AnyValue{string_value:"bar"} + ]}} + }, + ] + } +} +``` + +The rules described in this document should be applied recursively to each value +of the associative array. + +#### Sets + +Unordered collections of unique values (such as +[Java Sets](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html), +[C++ sets](https://en.cppreference.com/w/cpp/container/set), +[Python Sets](https://docs.python.org/3/tutorial/datastructures.html#sets)) SHOULD be +converted to AnyValue's +[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) +field, where each element of the set becomes an element of the array. + +The rules described in this document should be applied recursively to each value +of the set. + +### Other Values + +Any other values not listed above SHOULD be converted to AnyValue's +[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) +field if the source data can be serialized to a string (can be stringified) +using toString() or stringify functions available in programming languages. + +If the source data cannot be serialized to a string then the value SHOULD be +converted AnyValue's +[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) +field by serializing it into a byte sequence by any means available. + +If the source data cannot be serialized neither to a string nor to a byte +sequence then it SHOULD by converted to an empty AnyValue. + +### Empty Values + +If the source data has no type associated with it and is empty, null, nil or +otherwise indicates absence of data it SHOULD be converted to an +[empty](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L29) +AnyValue, where all the fields are unset. + +Empty values which has a type associated with them (e.g. empty associative +array) SHOULD be converted using the corresponding rules defined for the types +above. diff --git a/specification/common/common.md b/specification/common/common.md index 774c236130..6c3e80a527 100644 --- a/specification/common/common.md +++ b/specification/common/common.md @@ -51,6 +51,9 @@ both containing an array of strings to represent a mapping See [Attribute Naming](attribute-naming.md) for naming guidelines. +See [this document](attribute-type-mapping.md) to find out how to map values obtained +outside OpenTelemetry into OpenTelemetry attribute values. + ### Attribute Limits Execution of erroneous code can result in unintended attributes. If there are no From 97d6ebffccafadacb9b64a8f7a7bab6916b1ff3d Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 8 Apr 2022 13:07:21 -0400 Subject: [PATCH 250/482] Ensure common section has a README (#2479) --- specification/common/{common.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename specification/common/{common.md => README.md} (100%) diff --git a/specification/common/common.md b/specification/common/README.md similarity index 100% rename from specification/common/common.md rename to specification/common/README.md From 37675886662f0f200ca6f3c4090fddb64f34ce93 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 16 May 2022 10:16:33 -0700 Subject: [PATCH 251/482] Define attribute requirement levels (#2522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nits * review comments * No exceptions for Required attributes, clarifications on performance * Conditional clarifications * nits * Conditional -> required conditionally and minor fixes * Align requirement levels with RFC levels better * Clarify Note on required attributes * Update specification/common/attribute-requirement-level.md Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> * Clarify Note on required attributes * Remove performance from conditionally required attributes * Clarify Conditionally Required case when condition is false * Apply suggestions from code review Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Christian Neumüller * headings for levels and moving things around * nits: formatting Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Co-authored-by: Christian Neumüller Co-authored-by: Reiley Yang --- specification/common/README.md | 2 + .../common/attribute-requirement-level.md | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 specification/common/attribute-requirement-level.md diff --git a/specification/common/README.md b/specification/common/README.md index 6c3e80a527..18d46fe00c 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -51,6 +51,8 @@ both containing an array of strings to represent a mapping See [Attribute Naming](attribute-naming.md) for naming guidelines. +See [Requirement Level](attribute-requirement-level.md) for requirement levels guidelines. + See [this document](attribute-type-mapping.md) to find out how to map values obtained outside OpenTelemetry into OpenTelemetry attribute values. diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md new file mode 100644 index 0000000000..5a7d6e323d --- /dev/null +++ b/specification/common/attribute-requirement-level.md @@ -0,0 +1,69 @@ +# Attribute Requirement Levels for Semantic Conventions + +**Status**: [Experimental](../document-status.md) + +
+Table of Contents + + + +- [Required](#required) +- [Conditionally Required](#conditionally-required) +- [Recommended](#recommended) +- [Optional](#optional) +- [Performance suggestions](#performance-suggestions) + + + +
+ +_This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ + +The following attribute requirement levels are specified: + +- [Required](#required) +- [Conditionally Required](#conditionally-required) +- [Recommended](#recommended) +- [Optional](#optional) + +The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. + +For example, Metric attributes that may have high cardinality can only be defined with `Optional` level. + +Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. + +For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. + +## Required + +All instrumentations MUST populate the attribute. Semantic convention defining a Required attribute expects that an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, can ensure cardinality, security, and other requirements specific to signal defined by the convention. `http.method` is an example of a Required attribute. + +_Note: Consumers of telemetry can detect if telemetry item follows a specific semantic convention by checking the presence of a `Required` attribute defined by such convention. For example, the presence of `db.system` attribute on a span can be used as an indication that the span follows database semantics._ + +## Conditionally Required + +All instrumentations MUST add the attribute when given condition is satisfied. Semantic convention of a `Conditionally Required` level of an attribute MUST clarify the condition under which the attribute is expected to be populated. + +`http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. + +When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. + +For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.peer.ip` is available, instrumentation can do a DNS lookup, cache and populate `net.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. + +## Recommended + +Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. + +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Optional` requirement level on them if the attributes are logically applicable. + +## Optional + +Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Optional` attributes. + +## Performance suggestions + +Here are several examples of expensive operations to be avoided by default: + +- DNS lookup to populate `net.peer.name` if only IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- forcing `http.route` calculation before HTTP framework calculates it +- reading response stream to find `http.response_content_length` when `Content-Length` header is not available From 8781d7df056c4f8f59f653d98c0ef35079077ef5 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 20 May 2022 02:12:03 -0400 Subject: [PATCH 252/482] Add missing READMEs to section (#2559) --- specification/common/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/common/README.md b/specification/common/README.md index 18d46fe00c..3d1379fde4 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,3 +1,6 @@ + # Common specification concepts **Status**: [Stable, Feature-freeze](../document-status.md) From 9eaea0af14eae15dbd02a5823efa131cf97bac2c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Thu, 2 Jun 2022 03:25:38 -0400 Subject: [PATCH 253/482] Move non-otlp.md to common directory (#2587) --- specification/common/mapping-to-non-otlp.md | 76 +++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 specification/common/mapping-to-non-otlp.md diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md new file mode 100644 index 0000000000..cb80f685ca --- /dev/null +++ b/specification/common/mapping-to-non-otlp.md @@ -0,0 +1,76 @@ +# OpenTelemetry Transformation to non-OTLP Formats + +**Status**: [Stable](../document-status.md) + +All OpenTelemetry concepts and data recorded using OpenTelemetry API can be +directly and precisely represented using corresponding messages and fields of +OTLP format. However, for other formats this is not always the case. Sometimes a +format will not have a native way to represent a particular OpenTelemetry +concept or a field of a concept. + +This document defines the transformation between OpenTelemetry and formats other +than OTLP, for OpenTelemetry fields and concepts that have no direct semantic +equivalent in those other formats. + +Note: when a format has a direct semantic equivalent for a particular field or +concept then the recommendation in this document MUST be ignored. + +See also additional specific transformation rules for +[Jaeger](../trace/sdk_exporters/jaeger.md) and [Zipkin](../trace/sdk_exporters/zipkin.md). +The specific rules for Jaeger and Zipkin take precedence over the generic rules defined +in this document. + +## Mappings + +### InstrumentationScope + +OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value +pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: + +| OpenTelemetry InstrumentationScope Field | non-OTLP Key | Notes | +| ------------------- | --- | --- | +| `InstrumentationScope.name`|`otel.scope.name`|since 1.10.0| +| `InstrumentationScope.version`|`otel.scope.version`|since 1.10.0| + +The following deprecated aliases MUST also be reported with exact same values for +backward compatibility reasons: + +| non-OTLP Key | Alias for | Notes | +| --- | --- | --- | +|`otel.library.name`|`otel.scope.name`|deprecated since 1.10.0| +|`otel.library.version`|`otel.scope.version`|deprecated since 1.10.0| + +### Span Status + +Span `Status` MUST be reported as key-value pairs associated with the Span, +unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. + +The following table defines the OpenTelemetry `Status`'s mapping to Span's +key-value pairs: + +|OpenTelemetry Status Field|non-OTLP Key|non-OTLP Value| +|--|--|--| +|Code | `otel.status_code` | Name of the code, either `OK` or `ERROR`. MUST NOT be set if the code is `UNSET`. | +|Description | `otel.status_description` | Description of the `Status` if it has a value otherwise not set. | + +### Dropped Attributes Count + +OpenTelemetry dropped attributes count MUST be reported as a key-value +pair associated with the corresponding data entity (e.g. Span, Span Link, Span Event, +Metric data point, LogRecord, etc). The key name MUST be `otel.dropped_attributes_count`. + +This key-value pair should only be recorded when it contains a non-zero value. + +### Dropped Events Count + +OpenTelemetry Span's dropped events count MUST be reported as a key-value pair +associated with the Span. The key name MUST be `otel.dropped_events_count`. + +This key-value pair should only be recorded when it contains a non-zero value. + +### Dropped Links Count + +OpenTelemetry Span's dropped links count MUST be reported as a key-value pair +associated with the Span. The key name MUST be `otel.dropped_links_count`. + +This key-value pair should only be recorded when it contains a non-zero value. From e67da74c1fba3a78f8b781f0216de0569f5af674 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 10 Jun 2022 22:19:33 -0400 Subject: [PATCH 254/482] Introduce Instrumentation Scope Attributes (#2579) --- specification/common/mapping-to-non-otlp.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md index cb80f685ca..656b37fa35 100644 --- a/specification/common/mapping-to-non-otlp.md +++ b/specification/common/mapping-to-non-otlp.md @@ -74,3 +74,9 @@ OpenTelemetry Span's dropped links count MUST be reported as a key-value pair associated with the Span. The key name MUST be `otel.dropped_links_count`. This key-value pair should only be recorded when it contains a non-zero value. + +### Instrumentation Scope Attributes + +Exporters to formats that don't have a concept that is equivalent to the Scope +SHOULD record the attributes at the most suitable place in their corresponding format, +typically at the Span, Metric or LogRecord equivalent. From 894b49059be3930df120f1e056e921a49c1df13c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 13 Jun 2022 12:00:00 -0400 Subject: [PATCH 255/482] Use consistent file name for data-model.md (#2586) --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 3d1379fde4..35d6264b2a 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -119,7 +119,7 @@ at this time, as discussed in ## Attribute Collections [Resources](../resource/sdk.md), Metrics -[data points](../metrics/datamodel.md#metric-points), +[data points](../metrics/data-model.md#metric-points), [Spans](../trace/api.md#set-attributes), Span [Events](../trace/api.md#add-events), Span [Links](../trace/api.md#specifying-links) and From 6cd23747866ccaf171926fb941b163177e9f1d90 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 8 Jul 2022 03:12:12 -0400 Subject: [PATCH 256/482] Add note to Hugo front matter (#2651) --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 35d6264b2a..2b377a731c 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,4 +1,4 @@ - # Common specification concepts From 5f11d9f4f7ed0efabb7ae5df8d9ee5d881285988 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 13 Jul 2022 10:01:44 -0700 Subject: [PATCH 257/482] Define net.sock attributes and clarify logical net.peer|host.name attributes (#2614) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 5a7d6e323d..e015ef89eb 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -48,7 +48,7 @@ All instrumentations MUST add the attribute when given condition is satisfied. S When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.peer.ip` is available, instrumentation can do a DNS lookup, cache and populate `net.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. +For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. ## Recommended From 3fd804bd853d584efeace2018f9d7f9244116bd9 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 13 Sep 2022 09:45:58 -0500 Subject: [PATCH 258/482] Align log sdk naming with api (#2768) Resolves #2752. This aligns log SDK and API concepts which have diverged after the merged of #2676. This PR brings alignment to the log API and SDK, and in brings the log signal into alignment with tracing and metrics where there is conceptual overlap. There shouldn't be any new concepts introduced here. - Rename `../logs/logging-library-sdk.md` to `../logs/sdk.md` - Remove wording from SDK that implies that an API doesn't exist, like [this](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L60-L62). - Move [How to Create Log4j Style Appender](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L219) to `api.md` since it describes an API use case. - Move [Implicit / Explicit Context Injection](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/logging-library-sdk.md#L270-L288) sections to `api.md` since they describe API level considerations. - Rename Logger [create](https://github.com/open-telemetry/opentelemetry-specification/blame/main/specification/logs/api.md#L133) method to be emit, to align with SDK concept of `LogRecordProcessor#onEmit(..)`. - Rename `LogProcessor`, `LogExporter` to `LogRecordProcessor`, `LogRecordExporter`. - Fill in various SDK level TODOs related to shutdown and flushing. The language from these was taken directly from the metrics / tracing SDK - no new concepts were introduced. --- specification/common/attribute-type-mapping.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md index 46a25c1504..532d6156bc 100644 --- a/specification/common/attribute-type-mapping.md +++ b/specification/common/attribute-type-mapping.md @@ -33,7 +33,7 @@ The mapping is needed when OpenTelemetry needs to convert a value produced outsi OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be converted to be used inside OpenTelemetry boundaries. Example use cases are the following: -- In [Logging Library SDK](../logs/logging-library-sdk.md)s, to convert values received +- In the [Logging SDK](../logs/sdk.md)s, to convert values received from logging libraries into OpenTelemetry representation. - In the Collector, to convert values received from various data sources into [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) From d1eb5e2e74f28590022c267379b9ff9b374cc02f Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 25 Oct 2022 08:46:06 -0700 Subject: [PATCH 259/482] Define semantic conventions yaml for non-otlp conventions (#2850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Define semantic conventions yaml for non-otlp conventions Signed-off-by: Bogdan Drutu * Update semantic_conventions/trace/exporter/exporter.yaml Co-authored-by: Christian Neumüller * Update semantic_conventions/scope/exporter/exporter.yaml Co-authored-by: Joao Grassi * Rename otel to otel_span Signed-off-by: Bogdan Drutu Signed-off-by: Bogdan Drutu Co-authored-by: Christian Neumüller Co-authored-by: Joao Grassi --- specification/common/mapping-to-non-otlp.md | 37 ++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md index 656b37fa35..a82dac3e63 100644 --- a/specification/common/mapping-to-non-otlp.md +++ b/specification/common/mapping-to-non-otlp.md @@ -27,18 +27,22 @@ in this document. OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: -| OpenTelemetry InstrumentationScope Field | non-OTLP Key | Notes | -| ------------------- | --- | --- | -| `InstrumentationScope.name`|`otel.scope.name`|since 1.10.0| -| `InstrumentationScope.version`|`otel.scope.version`|since 1.10.0| + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | Recommended | +| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | Recommended | + The following deprecated aliases MUST also be reported with exact same values for backward compatibility reasons: -| non-OTLP Key | Alias for | Notes | -| --- | --- | --- | -|`otel.library.name`|`otel.scope.name`|deprecated since 1.10.0| -|`otel.library.version`|`otel.scope.version`|deprecated since 1.10.0| + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.library.name` | string | Deprecated, use the `otel.scope.name` attribute. | `io.opentelemetry.contrib.mongodb` | Recommended | +| `otel.library.version` | string | Deprecated, use the `otel.scope.version` attribute. | `1.0.0` | Recommended | + ### Span Status @@ -48,10 +52,19 @@ unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. The following table defines the OpenTelemetry `Status`'s mapping to Span's key-value pairs: -|OpenTelemetry Status Field|non-OTLP Key|non-OTLP Value| -|--|--|--| -|Code | `otel.status_code` | Name of the code, either `OK` or `ERROR`. MUST NOT be set if the code is `UNSET`. | -|Description | `otel.status_description` | Description of the `Status` if it has a value otherwise not set. | + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | Recommended | +| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | Recommended | + +`otel.status_code` MUST be one of the following: + +| Value | Description | +|---|---| +| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | +| `ERROR` | The operation contains an error. | + ### Dropped Attributes Count From 99f6917344dd6f3427cae5c45056dc42c1cce501 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 26 Jan 2023 16:22:06 -0800 Subject: [PATCH 260/482] Add log attribute limit configuration (#2861) Fixes #2860 Adds log attribute limit configuration. These new environment variables bring more consistency between spans and logs. --- specification/common/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/common/README.md b/specification/common/README.md index 2b377a731c..f36cb92b85 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -91,11 +91,11 @@ limits programmatically. Names of the configuration options SHOULD be the same a in the list below. An SDK MAY implement model-specific limits, for example -`SpanAttributeCountLimit`. If both a general and a model-specific limit are -implemented, then the SDK MUST first attempt to use the model-specific limit, if -it isn't set, then the SDK MUST attempt to use the general limit. If neither are -defined, then the SDK MUST try to use the model-specific limit default value, -followed by the global limit default value. +`SpanAttributeCountLimit` or `LogRecordAttributeCountLimit`. If both a general +and a model-specific limit are implemented, then the SDK MUST first attempt to +use the model-specific limit, if it isn't set, then the SDK MUST attempt to use +the general limit. If neither are defined, then the SDK MUST try to use the +model-specific limit default value, followed by the global limit default value. #### Configurable Parameters From 35e27bcb99d51cd1db10757f4b87f3d687af670e Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 23 Feb 2023 11:38:55 -0500 Subject: [PATCH 261/482] Mark Attribute naming conventions as stable. (#3220) --- specification/common/attribute-naming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index fecbf3b21b..d761b5f9fd 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -1,6 +1,6 @@ # Attribute Naming -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md)
Table of Contents From 58c415c1ba87ef72640d2ec7257f27b5d3cc17f4 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 1 Mar 2023 15:13:24 -0800 Subject: [PATCH 262/482] Rename Optional attribute requirement level to Opt-In (#3228) --- .../common/attribute-requirement-level.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index e015ef89eb..c030159409 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -10,7 +10,7 @@ - [Required](#required) - [Conditionally Required](#conditionally-required) - [Recommended](#recommended) -- [Optional](#optional) +- [Opt-In](#opt-in) - [Performance suggestions](#performance-suggestions) @@ -24,11 +24,11 @@ The following attribute requirement levels are specified: - [Required](#required) - [Conditionally Required](#conditionally-required) - [Recommended](#recommended) -- [Optional](#optional) +- [Opt-In](#opt-in) The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. -For example, Metric attributes that may have high cardinality can only be defined with `Optional` level. +For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. @@ -46,7 +46,7 @@ All instrumentations MUST add the attribute when given condition is satisfied. S `http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. -When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Optional` requirement level on the attribute. +When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. @@ -54,11 +54,11 @@ For example, `net.peer.name` is `Conditionally Required` by [Database convention Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Optional` requirement level on them if the attributes are logically applicable. +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Opt-In` requirement level on them if the attributes are logically applicable. -## Optional +## Opt-In -Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Optional` attributes. +Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. ## Performance suggestions From dba3c1c9a33049fb24ea721709af9cbf98f9d4ca Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 6 Mar 2023 10:20:11 -0800 Subject: [PATCH 263/482] Proofread of attribute requirement levels in preparation for stability (#3270) --- .../common/attribute-requirement-level.md | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index c030159409..59432e6096 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -26,44 +26,47 @@ The following attribute requirement levels are specified: - [Recommended](#recommended) - [Opt-In](#opt-in) -The requirement level for attribute is defined by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When defining requirement levels, semantic conventions MUST take into account signal-specific requirements. +The requirement level for an attribute is specified by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When specifying requirement levels, a semantic convention MUST take into account signal-specific requirements. For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. -Semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. +A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. ## Required -All instrumentations MUST populate the attribute. Semantic convention defining a Required attribute expects that an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, can ensure cardinality, security, and other requirements specific to signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. -_Note: Consumers of telemetry can detect if telemetry item follows a specific semantic convention by checking the presence of a `Required` attribute defined by such convention. For example, the presence of `db.system` attribute on a span can be used as an indication that the span follows database semantics._ +_Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ ## Conditionally Required -All instrumentations MUST add the attribute when given condition is satisfied. Semantic convention of a `Conditionally Required` level of an attribute MUST clarify the condition under which the attribute is expected to be populated. +All instrumentations MUST populate the attribute when the given condition is satisfied. The semantic convention of a `Conditionally Required` attribute MUST clarify the condition under which the attribute is to be populated. -`http.route` is an example of a conditionally required attribute to be populated when instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. +`http.route` is an example of a conditionally required attribute that is populated when the instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. -When the condition on `Conditionally Required` attribute is not satisfied and there is no requirement to populate attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. +When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by [Database convention](../trace/semantic_conventions/database.md) when available. When only `net.sock.peer.addr` is available, instrumentation can do a DNS lookup, cache and populate `net.sock.peer.name` but only if user explicitly enables instrumentation to do so, considering performance issues the DNS lookup introduces. +For example, `net.peer.name` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `net.sock.peer.addr` is available instead, instrumentation can do a DNS lookup, cache and populate `net.peer.name`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD use the `Opt-In` requirement level on them if the attributes are logically applicable. +Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD allow for users to +opt-in to emit them as defined for the `Opt-In` requirement level (if the attributes are logically applicable). ## Opt-In Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. +This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled enabled explicitly by a user making an informed decision. + ## Performance suggestions Here are several examples of expensive operations to be avoided by default: -- DNS lookup to populate `net.peer.name` if only IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. -- forcing `http.route` calculation before HTTP framework calculates it +- DNS lookups to populate `net.peer.name` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- forcing an `http.route` calculation before the HTTP framework calculates it - reading response stream to find `http.response_content_length` when `Content-Length` header is not available From b5f419fee375fc694bb684f3ee3230d35870b7a7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 7 Mar 2023 11:22:32 -0800 Subject: [PATCH 264/482] Attribute requirement level follow-up edits (#3293) --- specification/common/attribute-requirement-level.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 59432e6096..c7fb99345c 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -36,7 +36,7 @@ For example, [Database semantic convention](../trace/semantic_conventions/databa ## Required -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. _Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ @@ -61,7 +61,7 @@ opt-in to emit them as defined for the `Opt-In` requirement level (if the attrib Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. -This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled enabled explicitly by a user making an informed decision. +This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled explicitly by a user making an informed decision. ## Performance suggestions From eadd2af3a16345b216fe88a600375b7c92e5e09f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 16 Mar 2023 06:31:51 -0700 Subject: [PATCH 265/482] Clarify that attribute requirement levels apply to instrumentation libraries (#3289) Based on discussion in semconv stability WG Closes #3283 ## Changes Clarifies that attribute requirement levels apply to instrumentation. And that, because users can transform their telemetry in a number of ways (e.g. metric views, span processors, and collector transformations), these requirement levels cannot be relied on by telemetry consumers. --------- Co-authored-by: Liudmila Molkova Co-authored-by: Bogdan Drutu --- specification/common/attribute-requirement-level.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index c7fb99345c..3543970a29 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -19,6 +19,8 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ +Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). + The following attribute requirement levels are specified: - [Required](#required) From 899a24adb154ce7f57f9eed9a37be33e65af970d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 6 Apr 2023 21:56:17 -0700 Subject: [PATCH 266/482] Mark attribute requirement levels as stable (#3368) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 3543970a29..e9da7f0702 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -1,6 +1,6 @@ # Attribute Requirement Levels for Semantic Conventions -**Status**: [Experimental](../document-status.md) +**Status**: [Stable](../document-status.md)
Table of Contents From 079ef0c249cd19c9371b1f8b0e74cedffbfa5879 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 7 Apr 2023 15:55:06 -0400 Subject: [PATCH 267/482] Use path, not external URL, for link into glossary (#3375) - Contributes to https://github.com/open-telemetry/opentelemetry.io/issues/2429 - This is part of an effort to normalize links, for improved link checking on the OTel website --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index e9da7f0702..cfbc22b9da 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -19,7 +19,7 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ -Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library). +Attribute requirement levels apply to the [instrumentation library](../glossary.md#instrumentation-library). The following attribute requirement levels are specified: From 3d4e7b452af76e7f08a9e41575ce5ff623430139 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 8 May 2023 16:19:51 -0700 Subject: [PATCH 268/482] BREAKING: Replace `net.peer.*`/`net.host.*` with `client.*`/`server.*` (and `source.*`/`destination.*`) (#3402) --- specification/common/attribute-requirement-level.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index cfbc22b9da..aca07f487c 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -50,7 +50,7 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `net.peer.name` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `net.sock.peer.addr` is available instead, instrumentation can do a DNS lookup, cache and populate `net.peer.name`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. +For example, `server.address` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended @@ -69,6 +69,6 @@ This attribute requirement level is recommended for attributes that are particul Here are several examples of expensive operations to be avoided by default: -- DNS lookups to populate `net.peer.name` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it - reading response stream to find `http.response_content_length` when `Content-Length` header is not available From 70ffed7002dec16bbf839ad2619c6aee712507f4 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 May 2023 17:46:55 -0700 Subject: [PATCH 269/482] BREAKING: Rename remaining network attributes from `net.*` to `network.*` and align definitions with ECS (#3426) --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index aca07f487c..fc3f5b89d3 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -34,7 +34,7 @@ For example, Metric attributes that may have high cardinality can only be define A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. -For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `net.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. +For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `network.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. ## Required From 92a7f35fc07818475c7e838c36f1344f56025f91 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 8 May 2023 19:55:53 -0700 Subject: [PATCH 270/482] BREAKING: Introduce common `url.*` attributes, and improve use of namespacing under `http.*` (#3355) --- specification/common/attribute-naming.md | 6 +-- .../common/attribute-requirement-level.md | 4 +- specification/common/url.md | 45 +++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 specification/common/url.md diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index d761b5f9fd..67aee0ad09 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -44,7 +44,7 @@ Names SHOULD follow these rules: purpose should primarily drive the decision about forming nested namespaces. - For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.status_code` + words by underscores (i.e. use snake_case). For example `http.response.status_code` denotes the status code in the http namespace. - Names SHOULD NOT coincide with namespaces. For example if @@ -96,8 +96,8 @@ denote old attribute names in rename operations). - Semantic conventions exist for four areas: for Resource, Span, Log, and Metric attribute names. In addition, for spans we have two more areas: Event and Link attribute names. Identical namespaces or names in all these areas MUST have - identical meanings. For example the `http.method` span attribute name denotes - exactly the same concept as the `http.method` metric attribute, has the same + identical meanings. For example the `http.request.method` span attribute name denotes + exactly the same concept as the `http.request.method` metric attribute, has the same data type and the same set of possible values (in both cases it records the value of the HTTP protocol's request method as a string). diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index fc3f5b89d3..52f8e34f26 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -38,7 +38,7 @@ For example, [Database semantic convention](../trace/semantic_conventions/databa ## Required -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.request.method` is an example of a Required attribute. _Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ @@ -71,4 +71,4 @@ Here are several examples of expensive operations to be avoided by default: - DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it -- reading response stream to find `http.response_content_length` when `Content-Length` header is not available +- reading response stream to find `http.response.body.size` when `Content-Length` header is not available diff --git a/specification/common/url.md b/specification/common/url.md new file mode 100644 index 0000000000..bbe041ba67 --- /dev/null +++ b/specification/common/url.md @@ -0,0 +1,45 @@ +# Semantic conventions for URL + +**Status**: [Experimental](../document-status.md) + +This document defines semantic conventions that describe URL and its components. + +
+Table of Contents + + + +- [Attributes](#attributes) +- [Sensitive information](#sensitive-information) + + + +
+ +## Attributes + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | +| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | + +**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +**[2]:** When missing, the value is assumed to be `/` + +**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + + +## Sensitive information + +Capturing URL and its components MAY impose security risk. User and password information, when they are provided in [User Information](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1) subcomponent, MUST NOT be recorded. + +Instrumentations that are aware of specific sensitive query string parameters MUST scrub their values before capturing `url.query` attribute. For example, native instrumentation of a client library that passes credentials or user location in URL, must scrub corresponding properties. + +_Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ From db45b8950cd1c46192b90a22ea4c8add53e947c0 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 26 May 2023 11:23:42 -0400 Subject: [PATCH 271/482] Explain why custom attributes are not recommended to be placed in Otel namespaces (#3507) The @open-telemetry/technical-committee discussed and decided to keep the existing recommendations but clarify them and explain the purpose. --- specification/common/attribute-naming.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index 67aee0ad09..badb9acbd0 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -133,6 +133,13 @@ To do that consider a few options: `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. +- It is not recommended to use existing OpenTelemetry semantic convention namespace + as a prefix for a new company- or application-specific attribute name. Doing so + may result in a name clash in the future, if OpenTelemetry decides to use that + same name for a different purpose or if some other third party instrumentation + decides to use that exact same attribute name and you combine that instrumentation + with your own. + - The name may be generally applicable to applications in the industry. In that case consider submitting a proposal to this specification to add a new name to the semantic conventions, and if necessary also to add a new namespace. From 2af3a419d362e891efb2063104a2accd982cdbb6 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 12 Jul 2023 10:58:54 -0400 Subject: [PATCH 272/482] Hugo front-matter fixes for aliases and linkTitle (#3592) - Followup changes for https://github.com/open-telemetry/opentelemetry.io/issues/2793 - There are only changes to Hugo front matter - Adds `likeTitle`s for "Compatibility" pages - Adds aliases for pages that have moved or were renamed - Related: https://github.com/open-telemetry/opentelemetry.io/issues/3013 -- the `compatibility/openmetrics` spec page is in the list because it was renamed /cc @svrnm @cartermp --- specification/common/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/common/README.md b/specification/common/README.md index f36cb92b85..239bdf2014 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -1,6 +1,7 @@ + # Common specification concepts **Status**: [Stable, Feature-freeze](../document-status.md) From 0b3465ca3d727831418e058120c2bfed7c76cc48 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 3 Oct 2023 12:13:38 -0400 Subject: [PATCH 273/482] Remove local stubs of semantic conventions. (#3711) --- specification/common/attribute-naming.md | 14 +++----------- .../common/attribute-requirement-level.md | 6 ++++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md index badb9acbd0..548703db6f 100644 --- a/specification/common/attribute-naming.md +++ b/specification/common/attribute-naming.md @@ -65,7 +65,7 @@ Names SHOULD follow these rules: values: the executable name and command arguments. - When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](../metrics/semantic_conventions/README.md#pluralization) + [Metric Name Pluralization Guidelines](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md#pluralization) SHOULD be followed for the attribute name. ## Name Reuse Prohibition @@ -83,11 +83,7 @@ denote old attribute names in rename operations). of a namespace. - When coming up with a new semantic convention make sure to check existing - namespaces for - [Resources](../resource/semantic_conventions/README.md), - [Spans](../trace/semantic_conventions/README.md), - and - [Metrics](../metrics/semantic_conventions/README.md) + namespaces ([Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md)) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level @@ -111,11 +107,7 @@ denote old attribute names in rename operations). ## Recommendations for Application Developers As an application developer when you need to record an attribute first consult -existing semantic conventions for -[Resources](../resource/semantic_conventions/README.md), -[Spans](../trace/semantic_conventions/README.md), -and -[Metrics](../metrics/semantic_conventions/README.md). +existing [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md). If an appropriate name does not exists you will need to come up with a new name. To do that consider a few options: diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 52f8e34f26..1866c413ca 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -34,7 +34,8 @@ For example, Metric attributes that may have high cardinality can only be define A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. -For example, [Database semantic convention](../trace/semantic_conventions/database.md) references `network.transport` attribute defined in [General attributes](../trace/semantic_conventions/span-general.md) with `Conditionally Required` level on it. + +For example, [Database semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) references `network.transport` attribute defined in [General attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/README.md) with `Conditionally Required` level on it. ## Required @@ -50,7 +51,8 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](../trace/semantic_conventions/database.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. + +For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended From c0513fbd9918226ef6eb5ae0e7ce1c40b508124f Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Wed, 11 Oct 2023 01:15:24 +0200 Subject: [PATCH 274/482] Add a new AddLink() operation to Span. (#3678) Fixes #454 Related to #3337 As the Messaging SIG merged its last OTEP 222, we will be adding operations that require Links after Span creation, taking a direct route with `AddLink()`, albeit without any of the new members suggested in #3337, e.g. `timestamp` (to be discussed in a separate issue). ``` AddLink(spanContext, attributes /* optional */) ``` --- specification/common/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/README.md b/specification/common/README.md index 239bdf2014..1f17536bb6 100644 --- a/specification/common/README.md +++ b/specification/common/README.md @@ -123,7 +123,7 @@ at this time, as discussed in [data points](../metrics/data-model.md#metric-points), [Spans](../trace/api.md#set-attributes), Span [Events](../trace/api.md#add-events), Span -[Links](../trace/api.md#specifying-links) and +[Links](../trace/api.md#link) and [Log Records](../logs/data-model.md) may contain a collection of attributes. The keys in each such collection are unique, i.e. there MUST NOT exist more than one key-value pair with the same key. The enforcement of uniqueness may be performed From 04d784279e3782459e65e024da927b884263bbea Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 23 Oct 2023 08:19:08 -0700 Subject: [PATCH 275/482] Rename/replace `(client|server).socket.(address|port)` attributes with `network.(peer|local).(address|port)`. (#3713) Co-authored-by: Armin Ruech --- specification/common/attribute-requirement-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md index 1866c413ca..7f510fe731 100644 --- a/specification/common/attribute-requirement-level.md +++ b/specification/common/attribute-requirement-level.md @@ -52,7 +52,7 @@ All instrumentations MUST populate the attribute when the given condition is sat When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `server.socket.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. +For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. ## Recommended From 7e251196c98cca076ad3ce98f91c29df1fcc00d5 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 7 Nov 2023 14:01:24 -0600 Subject: [PATCH 276/482] Remove files to keep --- specification/common/README.md | 150 ----------- .../common/attribute-type-mapping.md | 255 ------------------ specification/common/mapping-to-non-otlp.md | 95 ------- specification/common/url.md | 45 ---- 4 files changed, 545 deletions(-) delete mode 100644 specification/common/README.md delete mode 100644 specification/common/attribute-type-mapping.md delete mode 100644 specification/common/mapping-to-non-otlp.md delete mode 100644 specification/common/url.md diff --git a/specification/common/README.md b/specification/common/README.md deleted file mode 100644 index 1f17536bb6..0000000000 --- a/specification/common/README.md +++ /dev/null @@ -1,150 +0,0 @@ - - -# Common specification concepts - -**Status**: [Stable, Feature-freeze](../document-status.md) - -
-Table of Contents - - - -- [Attribute](#attribute) - * [Attribute Limits](#attribute-limits) - + [Configurable Parameters](#configurable-parameters) - + [Exempt Entities](#exempt-entities) -- [Attribute Collections](#attribute-collections) - - - -
- -## Attribute - - - -An `Attribute` is a key-value pair, which MUST have the following properties: - -- The attribute key MUST be a non-`null` and non-empty string. -- The attribute value is either: - - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - - An array of primitive type values. The array MUST be homogeneous, - i.e., it MUST NOT contain values of different types. - -For protocols that do not natively support non-string values, non-string values SHOULD be represented as JSON-encoded strings. For example, the expression `int64(100)` will be encoded as `100`, `float64(1.5)` will be encoded as `1.5`, and an empty array of any type will be encoded as `[]`. - -Attribute values expressing a numerical value of zero, an empty string, or an -empty array are considered meaningful and MUST be stored and passed on to -processors / exporters. - -Attribute values of `null` are not valid and attempting to set a `null` value is -undefined behavior. - -`null` values SHOULD NOT be allowed in arrays. However, if it is impossible to -make sure that no `null` values are accepted -(e.g. in languages that do not have appropriate compile-time type checking), -`null` values within arrays MUST be preserved as-is (i.e., passed on to span -processors / exporters as `null`). If exporters do not support exporting `null` -values, they MAY replace those values by 0, `false`, or empty strings. -This is required for map/dictionary structures represented as two arrays with -indices that are kept in sync (e.g., two attributes `header_keys` and `header_values`, -both containing an array of strings to represent a mapping -`header_keys[i] -> header_values[i]`). - -See [Attribute Naming](attribute-naming.md) for naming guidelines. - -See [Requirement Level](attribute-requirement-level.md) for requirement levels guidelines. - -See [this document](attribute-type-mapping.md) to find out how to map values obtained -outside OpenTelemetry into OpenTelemetry attribute values. - -### Attribute Limits - -Execution of erroneous code can result in unintended attributes. If there are no -limits placed on attributes, they can quickly exhaust available memory, resulting -in crashes that are difficult to recover from safely. - -By default an SDK SHOULD apply truncation as per the list of -[configurable parameters](#configurable-parameters) below. - -If an SDK provides a way to: - -- set an attribute value length limit such that for each - attribute value: - - if it is a string, if it exceeds that limit (counting any character in it as - 1), SDKs MUST truncate that value, so that its length is at most equal - to the limit, - - if it is an array of strings, then apply the above rule to each of the - values separately, - - otherwise a value MUST NOT be truncated; -- set a limit of unique attribute keys such that: - - for each unique attribute key, addition of which would result in exceeding - the limit, SDK MUST discard that key/value pair. - -There MAY be a log emitted to indicate to the user that an attribute was -truncated or discarded. To prevent excessive logging, the log MUST NOT be -emitted more than once per record on which an attribute is set. - -If the SDK implements the limits above, it MUST provide a way to change these -limits programmatically. Names of the configuration options SHOULD be the same as -in the list below. - -An SDK MAY implement model-specific limits, for example -`SpanAttributeCountLimit` or `LogRecordAttributeCountLimit`. If both a general -and a model-specific limit are implemented, then the SDK MUST first attempt to -use the model-specific limit, if it isn't set, then the SDK MUST attempt to use -the general limit. If neither are defined, then the SDK MUST try to use the -model-specific limit default value, followed by the global limit default value. - -#### Configurable Parameters - -* `AttributeCountLimit` (Default=128) - Maximum allowed attribute count per record; -* `AttributeValueLengthLimit` (Default=Infinity) - Maximum allowed attribute value length; - -#### Exempt Entities - -Resource attributes SHOULD be exempt from the limits described above as resources -are not susceptible to the scenarios (auto-instrumentation) that result in -excessive attributes count or size. Resources are also sent only once per batch -instead of per span so it is relatively cheaper to have more/larger attributes -on them. Resources are also immutable by design and they are generally passed -down to TracerProvider along with limits. This makes it awkward to implement -attribute limits for Resources. - -Attributes, which belong to Metrics, are exempt from the limits described above -at this time, as discussed in -[Metrics Attribute Limits](../metrics/sdk.md#attribute-limits). - -## Attribute Collections - -[Resources](../resource/sdk.md), Metrics -[data points](../metrics/data-model.md#metric-points), -[Spans](../trace/api.md#set-attributes), Span -[Events](../trace/api.md#add-events), Span -[Links](../trace/api.md#link) and -[Log Records](../logs/data-model.md) may contain a collection of attributes. The -keys in each such collection are unique, i.e. there MUST NOT exist more than one -key-value pair with the same key. The enforcement of uniqueness may be performed -in a variety of ways as it best fits the limitations of the particular -implementation. - -Normally for the telemetry generated using OpenTelemetry SDKs the attribute -key-value pairs are set via an API that either accepts a single key-value pair -or a collection of key-value pairs. Setting an attribute with the same key as an -existing attribute SHOULD overwrite the existing attribute's value. See for -example Span's [SetAttribute](../trace/api.md#set-attributes) API. - -A typical implementation of [SetAttribute](../trace/api.md#set-attributes) API -will enforce the uniqueness by overwriting any existing attribute values pending -to be exported, so that when the Span is eventually exported the exporters see -only unique attributes. The OTLP format in particular requires that exported -Resources, Spans, Metric data points and Log Records contain only unique -attributes. - -Some other implementations may use a streaming approach where every -[SetAttribute](../trace/api.md#set-attributes) API call immediately results in -that individual attribute value being exported using a streaming wire protocol. -In such cases the enforcement of uniqueness will likely be the responsibility of -the recipient of this data. diff --git a/specification/common/attribute-type-mapping.md b/specification/common/attribute-type-mapping.md deleted file mode 100644 index 532d6156bc..0000000000 --- a/specification/common/attribute-type-mapping.md +++ /dev/null @@ -1,255 +0,0 @@ -# Mapping Arbitrary Data to OTLP AnyValue - -**Status**: [Experimental](../document-status.md) - -
-Table of Contents - - - -- [Converting to AnyValue](#converting-to-anyvalue) - * [Primitive Values](#primitive-values) - + [Integer Values](#integer-values) - + [Enumerations](#enumerations) - + [Floating Point Values](#floating-point-values) - + [String Values](#string-values) - + [Byte Sequences](#byte-sequences) - * [Composite Values](#composite-values) - + [Array Values](#array-values) - + [Associative Arrays With Unique Keys](#associative-arrays-with-unique-keys) - + [Associative Arrays With Non-Unique Keys](#associative-arrays-with-non-unique-keys) - + [Sets](#sets) - * [Other Values](#other-values) - * [Empty Values](#empty-values) - - - -
- -This document defines how to map (convert) arbitrary data (e.g. in-memory -objects) to OTLP's [AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/cc4ed55c082cb75e084d40b4ddf3805eda099f97/opentelemetry/proto/common/v1/common.proto#L27). - -The mapping is needed when OpenTelemetry needs to convert a value produced outside -OpenTelemetry into a value that can be exported using an OTLP exporter, or otherwise be -converted to be used inside OpenTelemetry boundaries. Example use cases are the following: - -- In the [Logging SDK](../logs/sdk.md)s, to convert values received - from logging libraries into OpenTelemetry representation. -- In the Collector, to convert values received from various data sources into - [pdata](https://github.com/open-telemetry/opentelemetry-collector/blob/4998703dadd19fa91a88eabf7ccc68d728bee3fd/model/pdata/common.go#L84) - internal representation. - -## Converting to AnyValue - -[AnyValue](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L27) -is capable of representing primitive and structured data of certain types. - -Implementations that have source data in any form, such as in-memory objects -or data coming from other formats that needs to be converted to AnyValue SHOULD -follow the rules described below. - -### Primitive Values - -#### Integer Values - -Integer values which are within the range of 64 bit signed numbers -[-2^63..2^63-1] SHOULD be converted to AnyValue's -[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) -field. - -Integer values which are outside the range of 64 bit signed numbers SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field using decimal representation. - -#### Enumerations - -Values, which belong to a limited enumerated set (e.g. a Java -[enum](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)), SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field with the value of the string set to the symbolic name of the enumeration. - -If it is not possible to obtain the symbolic name of the enumeration, the -implementation SHOULD map enumeration values to AnyValue's -[int_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L33) -field set to the enum's ordinal value, when such an ordinal number is naturally -obtainable. - -If it is also not possible to obtain the ordinal value, the enumeration SHOULD be -converted to AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field in any manner that the implementation deems reasonable. - -#### Floating Point Values - -Floating point values which are within the range and precision of IEEE 754 -64-bit floating point numbers (including IEEE 32-bit floating point values) -SHOULD be converted to AnyValue's -[double_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L34) -field. - -Floating point values which are outside the range or precision of IEEE 754 -64-bit floating point numbers (e.g. IEEE 128-bit floating bit values) SHOULD be -converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field using decimal floating point representation. - -#### String Values - -String values which are valid UTF-8 sequences SHOULD be converted to -AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field. - -String values which are not valid Unicode sequences SHOULD be converted to -AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -with the bytes representing the string in the original order and format of the -source string. - -#### Byte Sequences - -Byte sequences (e.g. Go's `[]byte` slice or raw byte content of a file) SHOULD -be converted to AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field. - -### Composite Values - -#### Array Values - -Values that represent ordered sequences of other values (such as -[arrays](https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html), -[vectors](https://en.cppreference.com/w/cpp/container/vector), ordered -[lists](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists), -[slices](https://golang.org/ref/spec#Slice_types)) SHOULD be converted to -AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field. String values and byte sequences are an exception from this rule (see -above). - -The rules described in this document should be applied recursively to each element -of the array. - -#### Associative Arrays With Unique Keys - -Values that represent associative arrays with unique keys (also often known -as maps, dictionaries or key-value stores) SHOULD be converted to AnyValue's -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field. - -If the keys of the source array are not strings, they MUST be converted to -strings by any means available, often via a toString() or stringify functions -available in programming languages. The conversion function MUST be chosen in a -way that ensures that the resulting string keys are unique in the target array. - -The value part of each element of the source array SHOULD be converted to -AnyValue recursively. - -For example a JSON object `{"a": 123, "b": "def"}` SHOULD be converted to - -``` -AnyValue{ - kvlist_value:KeyValueList{ - values:[ - KeyValue{key:"a",value:AnyValue{int_value:123}}, - KeyValue{key:"b",value:AnyValue{string_value:"def"}}, - ] - } -} -``` - -The rules described in this document should be applied recursively to each value -of the associative array. - -#### Associative Arrays With Non-Unique Keys - -Values that represent an associative arrays with non-unique keys where multiple values may be associated with the same key (also sometimes known -as multimaps, multidicts) SHOULD be converted to AnyValue's -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field. - -The resulting -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field MUST list each key only once and the value of each element of -[kvlist_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L36) -field MUST be an array represented using AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field, each element of the -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -representing one value of source array associated with the given key. - -For example an associative array shown in the following table: - -|Key|Value| -|---|---| -|"abc"|123| -|"def"|"foo"| -|"def"|"bar"| - -SHOULD be converted to: - -``` -AnyValue{ - kvlist_value:KeyValueList{ - values:[ - KeyValue{ - key:"abc", - value:AnyValue{array_value:ArrayValue{values[ - AnyValue{int_value:123} - ]}} - }, - KeyValue{ - key:"def", - value:AnyValue{array_value:ArrayValue{values[ - AnyValue{string_value:"foo"}, - AnyValue{string_value:"bar"} - ]}} - }, - ] - } -} -``` - -The rules described in this document should be applied recursively to each value -of the associative array. - -#### Sets - -Unordered collections of unique values (such as -[Java Sets](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html), -[C++ sets](https://en.cppreference.com/w/cpp/container/set), -[Python Sets](https://docs.python.org/3/tutorial/datastructures.html#sets)) SHOULD be -converted to AnyValue's -[array_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L35) -field, where each element of the set becomes an element of the array. - -The rules described in this document should be applied recursively to each value -of the set. - -### Other Values - -Any other values not listed above SHOULD be converted to AnyValue's -[string_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L31) -field if the source data can be serialized to a string (can be stringified) -using toString() or stringify functions available in programming languages. - -If the source data cannot be serialized to a string then the value SHOULD be -converted AnyValue's -[bytes_value](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L37) -field by serializing it into a byte sequence by any means available. - -If the source data cannot be serialized neither to a string nor to a byte -sequence then it SHOULD by converted to an empty AnyValue. - -### Empty Values - -If the source data has no type associated with it and is empty, null, nil or -otherwise indicates absence of data it SHOULD be converted to an -[empty](https://github.com/open-telemetry/opentelemetry-proto/blob/38b5b9b6e5257c6500a843f7fdacf89dd95833e8/opentelemetry/proto/common/v1/common.proto#L29) -AnyValue, where all the fields are unset. - -Empty values which has a type associated with them (e.g. empty associative -array) SHOULD be converted using the corresponding rules defined for the types -above. diff --git a/specification/common/mapping-to-non-otlp.md b/specification/common/mapping-to-non-otlp.md deleted file mode 100644 index a82dac3e63..0000000000 --- a/specification/common/mapping-to-non-otlp.md +++ /dev/null @@ -1,95 +0,0 @@ -# OpenTelemetry Transformation to non-OTLP Formats - -**Status**: [Stable](../document-status.md) - -All OpenTelemetry concepts and data recorded using OpenTelemetry API can be -directly and precisely represented using corresponding messages and fields of -OTLP format. However, for other formats this is not always the case. Sometimes a -format will not have a native way to represent a particular OpenTelemetry -concept or a field of a concept. - -This document defines the transformation between OpenTelemetry and formats other -than OTLP, for OpenTelemetry fields and concepts that have no direct semantic -equivalent in those other formats. - -Note: when a format has a direct semantic equivalent for a particular field or -concept then the recommendation in this document MUST be ignored. - -See also additional specific transformation rules for -[Jaeger](../trace/sdk_exporters/jaeger.md) and [Zipkin](../trace/sdk_exporters/zipkin.md). -The specific rules for Jaeger and Zipkin take precedence over the generic rules defined -in this document. - -## Mappings - -### InstrumentationScope - -OpenTelemetry `InstrumentationScope`'s fields MUST be reported as key-value -pairs associated with the Span, Metric Data Point or LogRecord using the following mapping: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | Recommended | -| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | Recommended | - - -The following deprecated aliases MUST also be reported with exact same values for -backward compatibility reasons: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.library.name` | string | Deprecated, use the `otel.scope.name` attribute. | `io.opentelemetry.contrib.mongodb` | Recommended | -| `otel.library.version` | string | Deprecated, use the `otel.scope.version` attribute. | `1.0.0` | Recommended | - - -### Span Status - -Span `Status` MUST be reported as key-value pairs associated with the Span, -unless the `Status` is `UNSET`. In the latter case it MUST NOT be reported. - -The following table defines the OpenTelemetry `Status`'s mapping to Span's -key-value pairs: - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | Recommended | -| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | Recommended | - -`otel.status_code` MUST be one of the following: - -| Value | Description | -|---|---| -| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | -| `ERROR` | The operation contains an error. | - - -### Dropped Attributes Count - -OpenTelemetry dropped attributes count MUST be reported as a key-value -pair associated with the corresponding data entity (e.g. Span, Span Link, Span Event, -Metric data point, LogRecord, etc). The key name MUST be `otel.dropped_attributes_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Dropped Events Count - -OpenTelemetry Span's dropped events count MUST be reported as a key-value pair -associated with the Span. The key name MUST be `otel.dropped_events_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Dropped Links Count - -OpenTelemetry Span's dropped links count MUST be reported as a key-value pair -associated with the Span. The key name MUST be `otel.dropped_links_count`. - -This key-value pair should only be recorded when it contains a non-zero value. - -### Instrumentation Scope Attributes - -Exporters to formats that don't have a concept that is equivalent to the Scope -SHOULD record the attributes at the most suitable place in their corresponding format, -typically at the Span, Metric or LogRecord equivalent. diff --git a/specification/common/url.md b/specification/common/url.md deleted file mode 100644 index bbe041ba67..0000000000 --- a/specification/common/url.md +++ /dev/null @@ -1,45 +0,0 @@ -# Semantic conventions for URL - -**Status**: [Experimental](../document-status.md) - -This document defines semantic conventions that describe URL and its components. - -
-Table of Contents - - - -- [Attributes](#attributes) -- [Sensitive information](#sensitive-information) - - - -
- -## Attributes - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | -| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | - -**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. - -**[2]:** When missing, the value is assumed to be `/` - -**[3]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - - -## Sensitive information - -Capturing URL and its components MAY impose security risk. User and password information, when they are provided in [User Information](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1) subcomponent, MUST NOT be recorded. - -Instrumentations that are aware of specific sensitive query string parameters MUST scrub their values before capturing `url.query` attribute. For example, native instrumentation of a client library that passes credentials or user location in URL, must scrub corresponding properties. - -_Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ From 55f5ce9a0c3c7fe34c48b14d418889b30f8ad907 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 7 Nov 2023 14:02:50 -0600 Subject: [PATCH 277/482] Move attribute documents --- specification/common/attribute-naming.md | 156 ------------------ .../common/attribute-requirement-level.md | 76 --------- 2 files changed, 232 deletions(-) delete mode 100644 specification/common/attribute-naming.md delete mode 100644 specification/common/attribute-requirement-level.md diff --git a/specification/common/attribute-naming.md b/specification/common/attribute-naming.md deleted file mode 100644 index 548703db6f..0000000000 --- a/specification/common/attribute-naming.md +++ /dev/null @@ -1,156 +0,0 @@ -# Attribute Naming - -**Status**: [Stable](../document-status.md) - -
-Table of Contents - - - -- [Name Pluralization guidelines](#name-pluralization-guidelines) -- [Name Reuse Prohibition](#name-reuse-prohibition) -- [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) -- [Recommendations for Application Developers](#recommendations-for-application-developers) -- [otel.* Namespace](#otel-namespace) - - - -
- -_This section applies to Resource, Span, Log, and Metric attribute names (also -known as the "attribute keys"). For brevity within this section when we use the -term "name" without an adjective it is implied to mean "attribute name"._ - -Every name MUST be a valid Unicode sequence. - -_Note: we merely require that the names are represented as Unicode sequences. -This specification does not define how exactly the Unicode sequences are -encoded. The encoding can vary from one programming language to another and from -one wire format to another. Use the idiomatic way to represent Unicode in the -particular programming language or wire format._ - -Names SHOULD follow these rules: - -- Use namespacing to avoid name clashes. Delimit the namespaces using a dot - character. For example `service.version` denotes the service version where - `service` is the namespace and `version` is an attribute in that namespace. - -- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside - top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute - inside `telemetry.sdk` namespace. - Note: the fact that an entity is located within another entity is typically - not a sufficient reason for forming nested namespaces. The purpose of a - namespace is to avoid name clashes, not to indicate entity hierarchies. This - purpose should primarily drive the decision about forming nested namespaces. - -- For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.response.status_code` - denotes the status code in the http namespace. - -- Names SHOULD NOT coincide with namespaces. For example if - `service.instance.id` is an attribute name then it is no longer valid to have - an attribute named `service.instance` because `service.instance` is already a - namespace. Because of this rule be careful when choosing names: every existing - name prohibits existence of an equally named namespace in the future, and vice - versa: any existing namespace prohibits existence of an equally named - attribute key in the future. - -## Name Pluralization guidelines - -- When an attribute represents a single entity, the attribute name SHOULD be singular. - Examples: `host.name`, `db.user`, `container.id`. - -- When attribute can represent multiple entities, the attribute name SHOULD be pluralized - and the value type SHOULD be an array. E.g. `process.command_args` might include multiple - values: the executable name and command arguments. - -- When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/metrics.md#pluralization) - SHOULD be followed for the attribute name. - -## Name Reuse Prohibition - -A new attribute MUST NOT be added with the same name as an attribute that -existed in the past but was renamed (with a corresponding schema file). - -When introducing a new attribute name check all existing schema files to make -sure the name does not appear as a key of any "rename_attributes" section (keys -denote old attribute names in rename operations). - -## Recommendations for OpenTelemetry Authors - -- All names that are part of OpenTelemetry semantic conventions SHOULD be part - of a namespace. - -- When coming up with a new semantic convention make sure to check existing - namespaces ([Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md)) - to see if the new name fits. - -- When a new namespace is necessary consider whether it should be a top-level - namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). - -- Semantic conventions exist for four areas: for Resource, Span, Log, and Metric - attribute names. In addition, for spans we have two more areas: Event and Link - attribute names. Identical namespaces or names in all these areas MUST have - identical meanings. For example the `http.request.method` span attribute name denotes - exactly the same concept as the `http.request.method` metric attribute, has the same - data type and the same set of possible values (in both cases it records the - value of the HTTP protocol's request method as a string). - -- Semantic conventions MUST limit names to printable Basic Latin characters - (more precisely to - [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) - subset of Unicode code points). It is recommended to further limit names to - the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot - (as namespace delimiter). - -## Recommendations for Application Developers - -As an application developer when you need to record an attribute first consult -existing [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md). -If an appropriate name does not exists you will need to come up with a new name. -To do that consider a few options: - -- The name is specific to your company and may be possibly used outside the - company as well. To avoid clashes with names introduced by other companies (in - a distributed system that uses applications from multiple vendors) it is - recommended to prefix the new name by your company's reverse domain name, e.g. - `com.acme.shopname`. - -- The name is specific to your application that will be used internally only. If - you already have an internal company process that helps you to ensure no name - clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name by your application name, provided that - the application name is reasonably unique within your organization (e.g. - `myuniquemapapp.longitude` is likely fine). Make sure the application name - does not clash with an existing semantic convention namespace. - -- It is not recommended to use existing OpenTelemetry semantic convention namespace - as a prefix for a new company- or application-specific attribute name. Doing so - may result in a name clash in the future, if OpenTelemetry decides to use that - same name for a different purpose or if some other third party instrumentation - decides to use that exact same attribute name and you combine that instrumentation - with your own. - -- The name may be generally applicable to applications in the industry. In that - case consider submitting a proposal to this specification to add a new name to - the semantic conventions, and if necessary also to add a new namespace. - -It is recommended to limit names to printable Basic Latin characters -(more precisely to -[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) -subset of Unicode code points). - -## otel.* Namespace - -Attribute names that start with `otel.` are reserved to be defined by -OpenTelemetry specification. These are typically used to express OpenTelemetry -concepts in formats that don't have a corresponding concept. - -For example, the `otel.scope.name` attribute is used to record the -instrumentation scope name, which is an OpenTelemetry concept that is natively -represented in OTLP, but does not have an equivalent in other telemetry formats -and protocols. - -Any additions to the `otel.*` namespace MUST be approved as part of -OpenTelemetry specification. diff --git a/specification/common/attribute-requirement-level.md b/specification/common/attribute-requirement-level.md deleted file mode 100644 index 7f510fe731..0000000000 --- a/specification/common/attribute-requirement-level.md +++ /dev/null @@ -1,76 +0,0 @@ -# Attribute Requirement Levels for Semantic Conventions - -**Status**: [Stable](../document-status.md) - -
-Table of Contents - - - -- [Required](#required) -- [Conditionally Required](#conditionally-required) -- [Recommended](#recommended) -- [Opt-In](#opt-in) -- [Performance suggestions](#performance-suggestions) - - - -
- -_This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ - -Attribute requirement levels apply to the [instrumentation library](../glossary.md#instrumentation-library). - -The following attribute requirement levels are specified: - -- [Required](#required) -- [Conditionally Required](#conditionally-required) -- [Recommended](#recommended) -- [Opt-In](#opt-in) - -The requirement level for an attribute is specified by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When specifying requirement levels, a semantic convention MUST take into account signal-specific requirements. - -For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. - -A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. - - -For example, [Database semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) references `network.transport` attribute defined in [General attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/README.md) with `Conditionally Required` level on it. - -## Required - -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.request.method` is an example of a Required attribute. - -_Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ - -## Conditionally Required - -All instrumentations MUST populate the attribute when the given condition is satisfied. The semantic convention of a `Conditionally Required` attribute MUST clarify the condition under which the attribute is to be populated. - -`http.route` is an example of a conditionally required attribute that is populated when the instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. - -When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. - - -For example, `server.address` is `Conditionally Required` by the [Database convention](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. - -## Recommended - -Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. - -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD allow for users to -opt-in to emit them as defined for the `Opt-In` requirement level (if the attributes are logically applicable). - -## Opt-In - -Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. - -This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled explicitly by a user making an informed decision. - -## Performance suggestions - -Here are several examples of expensive operations to be avoided by default: - -- DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. -- forcing an `http.route` calculation before the HTTP framework calculates it -- reading response stream to find `http.response.body.size` when `Content-Length` header is not available From 48d3348fea34973b3cb48b0fd0302072e7d9ca6b Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 14 Nov 2023 13:54:47 -0600 Subject: [PATCH 278/482] Format with prettier --- docs/general/attribute-naming.md | 76 +++++++++--------- docs/general/attribute-requirement-level.md | 89 ++++++++++++++++----- 2 files changed, 107 insertions(+), 58 deletions(-) diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index a800f7bd39..b84f71f03e 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -11,7 +11,7 @@ - [Name Reuse Prohibition](#name-reuse-prohibition) - [Recommendations for OpenTelemetry Authors](#recommendations-for-opentelemetry-authors) - [Recommendations for Application Developers](#recommendations-for-application-developers) -- [otel.* Namespace](#otel-namespace) +- [otel.\* Namespace](#otel-namespace) @@ -37,15 +37,15 @@ Names SHOULD follow these rules: - Namespaces can be nested. For example `telemetry.sdk` is a namespace inside top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute - inside `telemetry.sdk` namespace. - Note: the fact that an entity is located within another entity is typically - not a sufficient reason for forming nested namespaces. The purpose of a - namespace is to avoid name clashes, not to indicate entity hierarchies. This - purpose should primarily drive the decision about forming nested namespaces. + inside `telemetry.sdk` namespace. Note: the fact that an entity is located + within another entity is typically not a sufficient reason for forming nested + namespaces. The purpose of a namespace is to avoid name clashes, not to + indicate entity hierarchies. This purpose should primarily drive the decision + about forming nested namespaces. - For each multi-word dot-delimited component of the attribute name separate the - words by underscores (i.e. use snake_case). For example `http.response.status_code` - denotes the status code in the http namespace. + words by underscores (i.e. use snake_case). For example + `http.response.status_code` denotes the status code in the http namespace. - Names SHOULD NOT coincide with namespaces. For example if `service.instance.id` is an attribute name then it is no longer valid to have @@ -57,16 +57,16 @@ Names SHOULD follow these rules: ## Name Pluralization guidelines -- When an attribute represents a single entity, the attribute name SHOULD be singular. - Examples: `host.name`, `db.user`, `container.id`. +- When an attribute represents a single entity, the attribute name SHOULD be + singular. Examples: `host.name`, `db.user`, `container.id`. -- When attribute can represent multiple entities, the attribute name SHOULD be pluralized - and the value type SHOULD be an array. E.g. `process.command_args` might include multiple - values: the executable name and command arguments. +- When attribute can represent multiple entities, the attribute name SHOULD be + pluralized and the value type SHOULD be an array. E.g. `process.command_args` + might include multiple values: the executable name and command arguments. - When an attribute represents a measurement, - [Metric Name Pluralization Guidelines](./metrics.md#pluralization) - SHOULD be followed for the attribute name. + [Metric Name Pluralization Guidelines](./metrics.md#pluralization) SHOULD be + followed for the attribute name. ## Name Reuse Prohibition @@ -83,8 +83,7 @@ denote old attribute names in rename operations). of a namespace. - When coming up with a new semantic convention make sure to check existing - namespaces ([Semantic Conventions](./README.md)) - to see if the new name fits. + namespaces ([Semantic Conventions](./README.md)) to see if the new name fits. - When a new namespace is necessary consider whether it should be a top-level namespace (e.g. `service`) or a nested namespace (e.g. `service.instance`). @@ -92,14 +91,14 @@ denote old attribute names in rename operations). - Semantic conventions exist for four areas: for Resource, Span, Log, and Metric attribute names. In addition, for spans we have two more areas: Event and Link attribute names. Identical namespaces or names in all these areas MUST have - identical meanings. For example the `http.request.method` span attribute name denotes - exactly the same concept as the `http.request.method` metric attribute, has the same - data type and the same set of possible values (in both cases it records the - value of the HTTP protocol's request method as a string). + identical meanings. For example the `http.request.method` span attribute name + denotes exactly the same concept as the `http.request.method` metric + attribute, has the same data type and the same set of possible values (in both + cases it records the value of the HTTP protocol's request method as a string). - Semantic conventions MUST limit names to printable Basic Latin characters (more precisely to - [U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) + [U+0021 .. U+007E]() subset of Unicode code points). It is recommended to further limit names to the following Unicode code points: Latin alphabet, Numeric, Underscore, Dot (as namespace delimiter). @@ -107,9 +106,9 @@ denote old attribute names in rename operations). ## Recommendations for Application Developers As an application developer when you need to record an attribute first consult -existing [semantic conventions](./README.md). -If an appropriate name does not exists you will need to come up with a new name. -To do that consider a few options: +existing [semantic conventions](./README.md). If an appropriate name does not +exists you will need to come up with a new name. To do that consider a few +options: - The name is specific to your company and may be possibly used outside the company as well. To avoid clashes with names introduced by other companies (in @@ -120,28 +119,28 @@ To do that consider a few options: - The name is specific to your application that will be used internally only. If you already have an internal company process that helps you to ensure no name clashes happen then feel free to follow it. Otherwise it is recommended to - prefix the attribute name by your application name, provided that - the application name is reasonably unique within your organization (e.g. + prefix the attribute name by your application name, provided that the + application name is reasonably unique within your organization (e.g. `myuniquemapapp.longitude` is likely fine). Make sure the application name does not clash with an existing semantic convention namespace. -- It is not recommended to use existing OpenTelemetry semantic convention namespace - as a prefix for a new company- or application-specific attribute name. Doing so - may result in a name clash in the future, if OpenTelemetry decides to use that - same name for a different purpose or if some other third party instrumentation - decides to use that exact same attribute name and you combine that instrumentation - with your own. +- It is not recommended to use existing OpenTelemetry semantic convention + namespace as a prefix for a new company- or application-specific attribute + name. Doing so may result in a name clash in the future, if OpenTelemetry + decides to use that same name for a different purpose or if some other third + party instrumentation decides to use that exact same attribute name and you + combine that instrumentation with your own. - The name may be generally applicable to applications in the industry. In that case consider submitting a proposal to this specification to add a new name to the semantic conventions, and if necessary also to add a new namespace. -It is recommended to limit names to printable Basic Latin characters -(more precisely to -[U+0021 .. U+007E](https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)#Table_of_characters) +It is recommended to limit names to printable Basic Latin characters (more +precisely to +[U+0021 .. U+007E]() subset of Unicode code points). -## otel.* Namespace +## otel.\* Namespace Attribute names that start with `otel.` are reserved to be defined by OpenTelemetry specification. These are typically used to express OpenTelemetry @@ -155,4 +154,5 @@ and protocols. Any additions to the `otel.*` namespace MUST be approved as part of OpenTelemetry specification. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md index eb89336df3..4fe6ddb9dd 100644 --- a/docs/general/attribute-requirement-level.md +++ b/docs/general/attribute-requirement-level.md @@ -17,9 +17,11 @@
-_This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ +_This section applies to Log, Metric, Resource, and Span, and describes +requirement levels for attributes defined in semantic conventions._ -Attribute requirement levels apply to the [instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/glossary.md#instrumentation-library). +Attribute requirement levels apply to the +[instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/glossary.md#instrumentation-library). The following attribute requirement levels are specified: @@ -28,51 +30,98 @@ The following attribute requirement levels are specified: - [Recommended](#recommended) - [Opt-In](#opt-in) -The requirement level for an attribute is specified by semantic conventions depending on attribute availability across instrumented entities, performance, security, and other factors. When specifying requirement levels, a semantic convention MUST take into account signal-specific requirements. +The requirement level for an attribute is specified by semantic conventions +depending on attribute availability across instrumented entities, performance, +security, and other factors. When specifying requirement levels, a semantic +convention MUST take into account signal-specific requirements. -For example, Metric attributes that may have high cardinality can only be defined with `Opt-In` level. +For example, Metric attributes that may have high cardinality can only be +defined with `Opt-In` level. -A semantic convention that refers to an attribute from another semantic convention MAY modify the requirement level within its own scope. Otherwise, requirement level from the referred semantic convention applies. +A semantic convention that refers to an attribute from another semantic +convention MAY modify the requirement level within its own scope. Otherwise, +requirement level from the referred semantic convention applies. -For example, [Database semantic convention](../database/README.md) references `network.transport` attribute defined in [General attributes](./README.md) with `Conditionally Required` level on it. + +For example, [Database semantic convention](../database/README.md) references +`network.transport` attribute defined in [General attributes](./README.md) with +`Conditionally Required` level on it. ## Required -All instrumentations MUST populate the attribute. A semantic convention defining a Required attribute expects an absolute majority of instrumentation libraries and applications are able to efficiently retrieve and populate it, and can additionally meet requirements for cardinality, security, and any others specific to the signal defined by the convention. `http.request.method` is an example of a Required attribute. +All instrumentations MUST populate the attribute. A semantic convention defining +a Required attribute expects an absolute majority of instrumentation libraries +and applications are able to efficiently retrieve and populate it, and can +additionally meet requirements for cardinality, security, and any others +specific to the signal defined by the convention. `http.request.method` is an +example of a Required attribute. -_Note: Consumers of telemetry can detect if a telemetry item follows a specific semantic convention by checking for the presence of a `Required` attribute defined by such convention. For example, the presence of the `db.system` attribute on a span can be used as an indication that the span follows database semantics._ +_Note: Consumers of telemetry can detect if a telemetry item follows a specific +semantic convention by checking for the presence of a `Required` attribute +defined by such convention. For example, the presence of the `db.system` +attribute on a span can be used as an indication that the span follows database +semantics._ ## Conditionally Required -All instrumentations MUST populate the attribute when the given condition is satisfied. The semantic convention of a `Conditionally Required` attribute MUST clarify the condition under which the attribute is to be populated. +All instrumentations MUST populate the attribute when the given condition is +satisfied. The semantic convention of a `Conditionally Required` attribute MUST +clarify the condition under which the attribute is to be populated. -`http.route` is an example of a conditionally required attribute that is populated when the instrumented HTTP framework provides route information for the instrumented request. Some low-level HTTP server implementations do not support routing and corresponding instrumentations can't populate the attribute. +`http.route` is an example of a conditionally required attribute that is +populated when the instrumented HTTP framework provides route information for +the instrumented request. Some low-level HTTP server implementations do not +support routing and corresponding instrumentations can't populate the attribute. -When a `Conditionally Required` attribute's condition is not satisfied, and there is no requirement to populate the attribute, semantic conventions MAY provide special instructions on how to handle it. If no instructions are given and if instrumentation can populate the attribute, instrumentation SHOULD use the `Opt-In` requirement level on the attribute. +When a `Conditionally Required` attribute's condition is not satisfied, and +there is no requirement to populate the attribute, semantic conventions MAY +provide special instructions on how to handle it. If no instructions are given +and if instrumentation can populate the attribute, instrumentation SHOULD use +the `Opt-In` requirement level on the attribute. -For example, `server.address` is `Conditionally Required` by the [Database convention](../database/README.md) when available. When `network.peer.address` is available instead, instrumentation can do a DNS lookup, cache and populate `server.address`, but only if the user explicitly enables the instrumentation to do so, considering the performance issues that DNS lookups introduce. + +For example, `server.address` is `Conditionally Required` by the +[Database convention](../database/README.md) when available. When +`network.peer.address` is available instead, instrumentation can do a DNS +lookup, cache and populate `server.address`, but only if the user explicitly +enables the instrumentation to do so, considering the performance issues that +DNS lookups introduce. ## Recommended -Instrumentations SHOULD add the attribute by default if it's readily available and can be [efficiently populated](#performance-suggestions). Instrumentations MAY offer a configuration option to disable Recommended attributes. +Instrumentations SHOULD add the attribute by default if it's readily available +and can be [efficiently populated](#performance-suggestions). Instrumentations +MAY offer a configuration option to disable Recommended attributes. -Instrumentations that decide not to populate `Recommended` attributes due to [performance](#performance-suggestions), security, privacy, or other consideration by default, SHOULD allow for users to -opt-in to emit them as defined for the `Opt-In` requirement level (if the attributes are logically applicable). +Instrumentations that decide not to populate `Recommended` attributes due to +[performance](#performance-suggestions), security, privacy, or other +consideration by default, SHOULD allow for users to opt-in to emit them as +defined for the `Opt-In` requirement level (if the attributes are logically +applicable). ## Opt-In -Instrumentations SHOULD populate the attribute if and only if the user configures the instrumentation to do so. Instrumentation that doesn't support configuration MUST NOT populate `Opt-In` attributes. +Instrumentations SHOULD populate the attribute if and only if the user +configures the instrumentation to do so. Instrumentation that doesn't support +configuration MUST NOT populate `Opt-In` attributes. -This attribute requirement level is recommended for attributes that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled explicitly by a user making an informed decision. +This attribute requirement level is recommended for attributes that are +particularly expensive to retrieve or might pose a security or privacy risk. +These should therefore only be enabled explicitly by a user making an informed +decision. ## Performance suggestions Here are several examples of expensive operations to be avoided by default: -- DNS lookups to populate `server.address` when only an IP address is available to the instrumentation. Caching lookup results does not solve the issue for all possible cases and should be avoided by default too. +- DNS lookups to populate `server.address` when only an IP address is available + to the instrumentation. Caching lookup results does not solve the issue for + all possible cases and should be avoided by default too. - forcing an `http.route` calculation before the HTTP framework calculates it -- reading response stream to find `http.response.body.size` when `Content-Length` header is not available +- reading response stream to find `http.response.body.size` when + `Content-Length` header is not available -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md From 811dbab22aa5e9944988a9c1ed77b34a6ee65eeb Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Fri, 17 Nov 2023 09:46:57 +0100 Subject: [PATCH 279/482] Moved database attributes to the attributes registry (#441) Signed-off-by: Alexander Wert Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/db.md | 222 +++++++++++++++ docs/database/cassandra.md | 18 +- docs/database/cosmosdb.md | 18 +- docs/database/couchdb.md | 4 +- docs/database/database-spans.md | 32 ++- docs/database/dynamodb.md | 2 +- docs/database/elasticsearch.md | 27 +- docs/database/hbase.md | 4 +- docs/database/mongodb.md | 4 +- docs/database/mssql.md | 6 +- docs/database/redis.md | 6 +- docs/database/sql.md | 4 +- model/registry/db.yaml | 424 +++++++++++++++++++++++++++ model/trace/database.yaml | 444 +++-------------------------- 15 files changed, 770 insertions(+), 446 deletions(-) create mode 100644 docs/attributes-registry/db.md create mode 100644 model/registry/db.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 607e9cfc88..c8a0702d3e 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -31,6 +31,7 @@ Currently, the following namespaces exist: * [Cloud](cloud.md) * [Code](code.md) * [Container](container.md) +* [DB](db.md) (database) * [Destination](destination.md) * [Device](device.md) * [Error](error.md) diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md new file mode 100644 index 0000000000..1964f71282 --- /dev/null +++ b/docs/attributes-registry/db.md @@ -0,0 +1,222 @@ + + +# Database + + + +- [Generic Database Attributes](#generic-database-attributes) +- [Cassandra Attributes](#cassandra-attributes) +- [CosmosDB Attributes](#cosmosdb-attributes) +- [Elasticsearch Attributes](#elasticsearch-attributes) +- [JDBC Attributes](#jdbc-attributes) +- [MongoDB Attributes](#mongodb-attributes) +- [MSSQL Attributes](#mssql-attributes) +- [Redis Attributes](#redis-attributes) +- [SQL Attributes](#sql-attributes) + + + +## Generic Database Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | +| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | +| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | +| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | + +**[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + +**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + +`db.system` 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 | +|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | +| `mssql` | Microsoft SQL Server | +| `mssqlcompact` | Microsoft SQL Server Compact | +| `mysql` | MySQL | +| `oracle` | Oracle Database | +| `db2` | IBM Db2 | +| `postgresql` | PostgreSQL | +| `redshift` | Amazon Redshift | +| `hive` | Apache Hive | +| `cloudscape` | Cloudscape | +| `hsqldb` | HyperSQL DataBase | +| `progress` | Progress Database | +| `maxdb` | SAP MaxDB | +| `hanadb` | SAP HANA | +| `ingres` | Ingres | +| `firstsql` | FirstSQL | +| `edb` | EnterpriseDB | +| `cache` | InterSystems Caché | +| `adabas` | Adabas (Adaptable Database System) | +| `firebird` | Firebird | +| `derby` | Apache Derby | +| `filemaker` | FileMaker | +| `informix` | Informix | +| `instantdb` | InstantDB | +| `interbase` | InterBase | +| `mariadb` | MariaDB | +| `netezza` | Netezza | +| `pervasive` | Pervasive PSQL | +| `pointbase` | PointBase | +| `sqlite` | SQLite | +| `sybase` | Sybase | +| `teradata` | Teradata | +| `vertica` | Vertica | +| `h2` | H2 | +| `coldfusion` | ColdFusion IMQ | +| `cassandra` | Apache Cassandra | +| `hbase` | Apache HBase | +| `mongodb` | MongoDB | +| `redis` | Redis | +| `couchbase` | Couchbase | +| `couchdb` | CouchDB | +| `cosmosdb` | Microsoft Azure Cosmos DB | +| `dynamodb` | Amazon DynamoDB | +| `neo4j` | Neo4j | +| `geode` | Apache Geode | +| `elasticsearch` | Elasticsearch | +| `memcached` | Memcached | +| `cockroachdb` | CockroachDB | +| `opensearch` | OpenSearch | +| `clickhouse` | ClickHouse | +| `spanner` | Cloud Spanner | +| `trino` | Trino | + + +## Cassandra Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | +| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | +| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | +| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | +| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | +| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | +| `db.cassandra.table` | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | + +**[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + +`db.cassandra.consistency_level` MUST be one of the following: + +| Value | Description | +|---|---| +| `all` | all | +| `each_quorum` | each_quorum | +| `quorum` | quorum | +| `local_quorum` | local_quorum | +| `one` | one | +| `two` | two | +| `three` | three | +| `local_one` | local_one | +| `any` | any | +| `serial` | serial | +| `local_serial` | local_serial | + + +## CosmosDB Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | +| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | +| `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | +| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | +| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | +| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | +| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | +| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | + +`db.cosmosdb.connection_mode` MUST be one of the following: + +| Value | Description | +|---|---| +| `gateway` | Gateway (HTTP) connections mode | +| `direct` | Direct connection. | + +`db.cosmosdb.operation_type` 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 | +|---|---| +| `Invalid` | invalid | +| `Create` | create | +| `Patch` | patch | +| `Read` | read | +| `ReadFeed` | read_feed | +| `Delete` | delete | +| `Replace` | replace | +| `Execute` | execute | +| `Query` | query | +| `Head` | head | +| `HeadFeed` | head_feed | +| `Upsert` | upsert | +| `Batch` | batch | +| `QueryPlan` | query_plan | +| `ExecuteJavaScript` | execute_javascript | + + +## Elasticsearch Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | +| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | + +**[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. + + +## JDBC Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.jdbc.driver_classname` | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | + + +## MongoDB Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.mongodb.collection` | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | + + +## MSSQL Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | + +**[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + + +## Redis Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | + + +## SQL Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | + +**[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index b6f160457c..0fcc385c82 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -14,17 +14,17 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | Recommended | -| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | Recommended | -| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | Recommended | -| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | Recommended | -| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | Recommended | -| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | Recommended | -| `db.cassandra.table` | string | The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | -| [`db.name`](database-spans.md) | string | The keyspace name in Cassandra. [2] | `mykeyspace` | Conditionally Required: If applicable. | +| [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | Recommended | +| [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | Recommended | +| [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | Recommended | +| [`db.cassandra.idempotence`](../attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | Recommended | +| [`db.cassandra.page_size`](../attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | Recommended | +| [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | Recommended | +| [`db.cassandra.table`](../attributes-registry/db.md) | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | +| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [2] | `mykeyspace` | Conditionally Required: If applicable. | **[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 3c2669879c..1862a1efa7 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -17,17 +17,17 @@ described on this page. Cosmos DB instrumentation includes call-level (public API) surface spans and network spans. Depending on the connection mode (Gateway or Direct), network-level spans may also be created. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | Recommended | -| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | Conditionally Required: if not `direct` (or pick gw as default) | -| `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | Conditionally Required: if available | -| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | Conditionally Required: [1] | -| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | Conditionally Required: when available | -| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | Recommended | -| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | Conditionally Required: if response was received | -| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | Conditionally Required: [2] | +| [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | Recommended | +| [`db.cosmosdb.connection_mode`](../attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway` | Conditionally Required: if not `direct` (or pick gw as default) | +| [`db.cosmosdb.container`](../attributes-registry/db.md) | string | Cosmos DB container name. | `anystring` | Conditionally Required: if available | +| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | Conditionally Required: [1] | +| [`db.cosmosdb.request_charge`](../attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1.0` | Conditionally Required: when available | +| [`db.cosmosdb.request_content_length`](../attributes-registry/db.md) | int | Request payload size in bytes | | Recommended | +| [`db.cosmosdb.status_code`](../attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | Conditionally Required: if response was received | +| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | Conditionally Required: [2] | | [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | Recommended | **[1]:** when performing one of the operations in this list diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 3ee335d759..6702a92b40 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -14,10 +14,10 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.operation`](database-spans.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | Conditionally Required: If `db.statement` is not applicable. | +| [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | Conditionally Required: If `db.statement` is not applicable. | **[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 1d3f6471f9..b6cf27a20f 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -61,12 +61,12 @@ When it's otherwise impossible to get any meaningful span name, `db.name` or the These attributes will usually be the same for all operations performed over the same database connection. Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | +| [`db.connection_string`](../attributes-registry/db.md) | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | +| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | +| [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | @@ -144,6 +144,22 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `clickhouse` | ClickHouse | | `spanner` | Cloud Spanner | | `trino` | Trino | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | ### Notes and well-known identifiers for `db.system` @@ -169,12 +185,12 @@ When additional attributes are added that only apply to a specific DBMS, its ide These attributes may be different for each operation performed, even if the same connection is used for multiple operations. Usually only one `db.name` will be used per connection though. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | -| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | -| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | +| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | +| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 61299804a6..137ebc6f37 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -19,7 +19,7 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.system`](database-spans.md) | string | The value `dynamodb`. | `dynamodb` | Required | +| [`db.system`](../attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | Required | ## DynamoDB.BatchGetItem diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 0dc1a722fa..156e7cb15f 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -23,14 +23,14 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | -| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | Recommended: [2] | -| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [3] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | -| [`db.operation`](database-spans.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | -| [`db.statement`](database-spans.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | +| [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | +| [`db.elasticsearch.node.name`](../attributes-registry/db.md) | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | Recommended: [2] | +| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [3] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | +| [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | +| [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | @@ -70,6 +70,21 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +`http.request.method` 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 | +|---|---| +| `CONNECT` | CONNECT method. | +| `DELETE` | DELETE method. | +| `GET` | GET method. | +| `HEAD` | HEAD method. | +| `OPTIONS` | OPTIONS method. | +| `PATCH` | PATCH method. | +| `POST` | POST method. | +| `PUT` | PUT method. | +| `TRACE` | TRACE method. | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ## Example diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 8cbc9d41a1..47b8acd2c5 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -14,10 +14,10 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.name`](database-spans.md) | string | The HBase namespace. [1] | `mynamespace` | Conditionally Required: If applicable. | +| [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | Conditionally Required: If applicable. | **[1]:** For HBase the `db.name` should be set to the HBase namespace. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index ef76976e27..10fdbb785e 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -14,10 +14,10 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.mongodb.collection` | string | The collection being accessed within the database stated in `db.name`. | `customers`; `products` | Required | +| [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | Required | ## Example diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 4873f48d11..763e7a1b12 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -14,11 +14,11 @@ described on this page. ## Connection-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.jdbc.driver_classname`](database-spans.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | +| [`db.jdbc.driver_classname`](../attributes-registry/db.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | +| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). diff --git a/docs/database/redis.md b/docs/database/redis.md index 85efb0104f..2614e494fa 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -14,11 +14,11 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | Conditionally Required: If other than the default database (`0`). | -| [`db.statement`](database-spans.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | Recommended: [2] | +| [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | Conditionally Required: If other than the default database (`0`). | +| [`db.statement`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | Recommended: [2] | **[1]:** For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. diff --git a/docs/database/sql.md b/docs/database/sql.md index 2bda71546a..6483e36374 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -12,10 +12,10 @@ described on this page. ## Call-level attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | Recommended | +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | Recommended | **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/model/registry/db.yaml b/model/registry/db.yaml new file mode 100644 index 0000000000..3ec2d84c66 --- /dev/null +++ b/model/registry/db.yaml @@ -0,0 +1,424 @@ +groups: + - id: registry.db + prefix: db + type: attribute_group + brief: > + This document defines the attributes used to describe telemetry in the context of databases. + attributes: + - id: cassandra.coordinator.dc + type: string + brief: > + The data center of the coordinating node for a query. + examples: 'us-west-2' + tag: tech-specific-cassandra + - id: cassandra.coordinator.id + type: string + brief: > + The ID of the coordinating node for a query. + examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + tag: tech-specific-cassandra + - id: cassandra.consistency_level + brief: > + The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + type: + members: + - id: all + value: 'all' + - id: each_quorum + value: 'each_quorum' + - id: quorum + value: 'quorum' + - id: local_quorum + value: 'local_quorum' + - id: one + value: 'one' + - id: two + value: 'two' + - id: three + value: 'three' + - id: local_one + value: 'local_one' + - id: any + value: 'any' + - id: serial + value: 'serial' + - id: local_serial + value: 'local_serial' + tag: tech-specific-cassandra + - id: cassandra.idempotence + type: boolean + brief: > + Whether or not the query is idempotent. + tag: tech-specific-cassandra + - id: cassandra.page_size + type: int + brief: > + The fetch size used for paging, i.e. how many rows will be returned at once. + examples: [5000] + tag: tech-specific-cassandra + - id: cassandra.speculative_execution_count + type: int + brief: > + The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + examples: [0, 2] + tag: tech-specific-cassandra + - id: cassandra.table + type: string + brief: The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + note: > + This mirrors the db.sql.table attribute but references cassandra rather than sql. + It is not recommended to attempt any client-side parsing of + `db.statement` just to get this property, but it should be set if + it is provided by the library being instrumented. + If the operation is acting upon an anonymous table, or more than one table, this + value MUST NOT be set. + examples: 'mytable' + tag: tech-specific-cassandra + - id: connection_string + type: string + brief: > + The connection string used to connect to the database. + It is recommended to remove embedded credentials. + examples: 'Server=(localdb)\v11.0;Integrated Security=true;' + tag: db-generic + - id: cosmosdb.client_id + type: string + brief: Unique Cosmos client instance id. + examples: '3ba4827d-4422-483f-b59f-85b74211c11d' + tag: tech-specific-cosmosdb + - id: cosmosdb.connection_mode + type: + allow_custom_values: false + members: + - id: gateway + value: 'gateway' + brief: Gateway (HTTP) connections mode + - id: direct + value: 'direct' + brief: Direct connection. + brief: Cosmos client connection mode. + tag: tech-specific-cosmosdb + - id: cosmosdb.container + type: string + brief: Cosmos DB container name. + examples: 'anystring' + tag: tech-specific-cosmosdb + - id: cosmosdb.operation_type + type: + allow_custom_values: true + members: + - id: invalid + value: 'Invalid' + - id: create + value: 'Create' + - id: patch + value: 'Patch' + - id: read + value: 'Read' + - id: read_feed + value: 'ReadFeed' + - id: delete + value: 'Delete' + - id: replace + value: 'Replace' + - id: execute + value: 'Execute' + - id: query + value: 'Query' + - id: head + value: 'Head' + - id: head_feed + value: 'HeadFeed' + - id: upsert + value: 'Upsert' + - id: batch + value: 'Batch' + - id: query_plan + value: 'QueryPlan' + - id: execute_javascript + value: 'ExecuteJavaScript' + brief: CosmosDB Operation Type. + tag: tech-specific-cosmosdb + - id: cosmosdb.request_charge + type: double + brief: RU consumed for that operation + examples: [46.18, 1.0] + tag: tech-specific-cosmosdb + - id: cosmosdb.request_content_length + type: int + brief: Request payload size in bytes + tag: tech-specific-cosmosdb + - id: cosmosdb.status_code + type: int + brief: Cosmos DB status code. + examples: [200, 201] + tag: tech-specific-cosmosdb + - id: cosmosdb.sub_status_code + type: int + brief: Cosmos DB sub status code. + examples: [1000, 1002] + tag: tech-specific-cosmosdb + - id: elasticsearch.cluster.name + type: string + brief: > + Represents the identifier of an Elasticsearch cluster. + examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + tag: tech-specific-elasticsearch + - id: elasticsearch.node.name + type: string + brief: > + Represents the human-readable identifier of the node/instance to which a request was routed. + examples: ["instance-0000000001"] + tag: tech-specific-elasticsearch + - id: elasticsearch.path_parts + type: template[string] + brief: > + A dynamic value in the url path. + note: > + Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format + `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD + reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) + in order to map the path part values to their names. + examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] + tag: tech-specific-elasticsearch + - id: jdbc.driver_classname + type: string + brief: > + The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. + examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] + tag: tech-specific-jdbc + - id: mongodb.collection + type: string + brief: > + The MongoDB collection being accessed within the database stated in `db.name`. + examples: [ 'customers', 'products' ] + tag: tech-specific-mongodb + - id: mssql.instance_name + type: string + note: > + If setting a `db.mssql.instance_name`, `server.port` is no longer + required (but still recommended if non-standard). + brief: > + The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + connecting to. This name is used to determine the port of a named instance. + examples: 'MSSQLSERVER' + tag: tech-specific-mssql + - id: name + type: string + brief: > + This attribute is used to report the name of the database being accessed. + For commands that switch the database, this should be set to the target database + (even if the command fails). + note: > + In some SQL databases, the database name to be used is called "schema name". + In case there are multiple layers that could be considered for database name + (e.g. Oracle instance name and schema name), + the database name to be used is the more specific layer (e.g. Oracle schema name). + examples: [ 'customers', 'main' ] + tag: db-generic + - id: operation + type: string + brief: > + The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) + such as `findAndModify`, or the SQL keyword. + note: > + When setting this to an SQL keyword, it is not recommended to + attempt any client-side parsing of `db.statement` just to get this + property, but it should be set if the operation name is provided by + the library being instrumented. + If the SQL statement has an ambiguous operation, or performs more + than one operation, this value may be omitted. + examples: ['findAndModify', 'HMSET', 'SELECT'] + tag: db-generic + - id: redis.database_index + type: int + brief: > + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. + To be used instead of the generic `db.name` attribute. + examples: [0, 1, 15] + tag: tech-specific-redis + - id: sql.table + type: string + brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). + note: > + It is not recommended to attempt any client-side parsing of + `db.statement` just to get this property, but it should be set if + it is provided by the library being instrumented. + If the operation is acting upon an anonymous table, or more than one table, this + value MUST NOT be set. + examples: ['public.users', 'customers'] + tag: tech-specific-sql + - id: statement + type: string + brief: > + The database statement being executed. + examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] + tag: db-generic + - id: system + brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + type: + allow_custom_values: true + members: + - id: other_sql + value: 'other_sql' + brief: 'Some other SQL database. Fallback only. See notes.' + - id: mssql + value: 'mssql' + brief: 'Microsoft SQL Server' + - id: mssqlcompact + value: 'mssqlcompact' + brief: 'Microsoft SQL Server Compact' + - id: mysql + value: 'mysql' + brief: 'MySQL' + - id: oracle + value: 'oracle' + brief: 'Oracle Database' + - id: db2 + value: 'db2' + brief: 'IBM Db2' + - id: postgresql + value: 'postgresql' + brief: 'PostgreSQL' + - id: redshift + value: 'redshift' + brief: 'Amazon Redshift' + - id: hive + value: 'hive' + brief: 'Apache Hive' + - id: cloudscape + value: 'cloudscape' + brief: 'Cloudscape' + - id: hsqldb + value: 'hsqldb' + brief: 'HyperSQL DataBase' + - id: progress + value: 'progress' + brief: 'Progress Database' + - id: maxdb + value: 'maxdb' + brief: 'SAP MaxDB' + - id: hanadb + value: 'hanadb' + brief: 'SAP HANA' + - id: ingres + value: 'ingres' + brief: 'Ingres' + - id: firstsql + value: 'firstsql' + brief: 'FirstSQL' + - id: edb + value: 'edb' + brief: 'EnterpriseDB' + - id: cache + value: 'cache' + brief: 'InterSystems Caché' + - id: adabas + value: 'adabas' + brief: 'Adabas (Adaptable Database System)' + - id: firebird + value: 'firebird' + brief: 'Firebird' + - id: derby + value: 'derby' + brief: 'Apache Derby' + - id: filemaker + value: 'filemaker' + brief: 'FileMaker' + - id: informix + value: 'informix' + brief: 'Informix' + - id: instantdb + value: 'instantdb' + brief: 'InstantDB' + - id: interbase + value: 'interbase' + brief: 'InterBase' + - id: mariadb + value: 'mariadb' + brief: 'MariaDB' + - id: netezza + value: 'netezza' + brief: 'Netezza' + - id: pervasive + value: 'pervasive' + brief: 'Pervasive PSQL' + - id: pointbase + value: 'pointbase' + brief: 'PointBase' + - id: sqlite + value: 'sqlite' + brief: 'SQLite' + - id: sybase + value: 'sybase' + brief: 'Sybase' + - id: teradata + value: 'teradata' + brief: 'Teradata' + - id: vertica + value: 'vertica' + brief: 'Vertica' + - id: h2 + value: 'h2' + brief: 'H2' + - id: coldfusion + value: 'coldfusion' + brief: 'ColdFusion IMQ' + - id: cassandra + value: 'cassandra' + brief: 'Apache Cassandra' + - id: hbase + value: 'hbase' + brief: 'Apache HBase' + - id: mongodb + value: 'mongodb' + brief: 'MongoDB' + - id: redis + value: 'redis' + brief: 'Redis' + - id: couchbase + value: 'couchbase' + brief: 'Couchbase' + - id: couchdb + value: 'couchdb' + brief: 'CouchDB' + - id: cosmosdb + value: 'cosmosdb' + brief: 'Microsoft Azure Cosmos DB' + - id: dynamodb + value: 'dynamodb' + brief: 'Amazon DynamoDB' + - id: neo4j + value: 'neo4j' + brief: 'Neo4j' + - id: geode + value: 'geode' + brief: 'Apache Geode' + - id: elasticsearch + value: 'elasticsearch' + brief: 'Elasticsearch' + - id: memcached + value: 'memcached' + brief: 'Memcached' + - id: cockroachdb + value: 'cockroachdb' + brief: 'CockroachDB' + - id: opensearch + value: 'opensearch' + brief: 'OpenSearch' + - id: clickhouse + value: 'clickhouse' + brief: 'ClickHouse' + - id: spanner + value: 'spanner' + brief: 'Cloud Spanner' + - id: trino + value: 'trino' + brief: 'Trino' + tag: db-generic + - id: user + type: string + brief: > + Username for accessing the database. + examples: ['readonly_user', 'reporting_user'] + tag: db-generic diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 7540e58c15..ed4f57161a 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -1,233 +1,33 @@ groups: - id: db - prefix: db type: span brief: > This document defines the attributes used to perform database client calls. span_kind: client attributes: - - id: system + - ref: db.system tag: connection-level - brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. requirement_level: required - type: - allow_custom_values: true - members: - - id: other_sql - value: 'other_sql' - brief: 'Some other SQL database. Fallback only. See notes.' - - id: mssql - value: 'mssql' - brief: 'Microsoft SQL Server' - - id: mssqlcompact - value: 'mssqlcompact' - brief: 'Microsoft SQL Server Compact' - - id: mysql - value: 'mysql' - brief: 'MySQL' - - id: oracle - value: 'oracle' - brief: 'Oracle Database' - - id: db2 - value: 'db2' - brief: 'IBM Db2' - - id: postgresql - value: 'postgresql' - brief: 'PostgreSQL' - - id: redshift - value: 'redshift' - brief: 'Amazon Redshift' - - id: hive - value: 'hive' - brief: 'Apache Hive' - - id: cloudscape - value: 'cloudscape' - brief: 'Cloudscape' - - id: hsqldb - value: 'hsqldb' - brief: 'HyperSQL DataBase' - - id: progress - value: 'progress' - brief: 'Progress Database' - - id: maxdb - value: 'maxdb' - brief: 'SAP MaxDB' - - id: hanadb - value: 'hanadb' - brief: 'SAP HANA' - - id: ingres - value: 'ingres' - brief: 'Ingres' - - id: firstsql - value: 'firstsql' - brief: 'FirstSQL' - - id: edb - value: 'edb' - brief: 'EnterpriseDB' - - id: cache - value: 'cache' - brief: 'InterSystems Caché' - - id: adabas - value: 'adabas' - brief: 'Adabas (Adaptable Database System)' - - id: firebird - value: 'firebird' - brief: 'Firebird' - - id: derby - value: 'derby' - brief: 'Apache Derby' - - id: filemaker - value: 'filemaker' - brief: 'FileMaker' - - id: informix - value: 'informix' - brief: 'Informix' - - id: instantdb - value: 'instantdb' - brief: 'InstantDB' - - id: interbase - value: 'interbase' - brief: 'InterBase' - - id: mariadb - value: 'mariadb' - brief: 'MariaDB' - - id: netezza - value: 'netezza' - brief: 'Netezza' - - id: pervasive - value: 'pervasive' - brief: 'Pervasive PSQL' - - id: pointbase - value: 'pointbase' - brief: 'PointBase' - - id: sqlite - value: 'sqlite' - brief: 'SQLite' - - id: sybase - value: 'sybase' - brief: 'Sybase' - - id: teradata - value: 'teradata' - brief: 'Teradata' - - id: vertica - value: 'vertica' - brief: 'Vertica' - - id: h2 - value: 'h2' - brief: 'H2' - - id: coldfusion - value: 'coldfusion' - brief: 'ColdFusion IMQ' - - id: cassandra - value: 'cassandra' - brief: 'Apache Cassandra' - - id: hbase - value: 'hbase' - brief: 'Apache HBase' - - id: mongodb - value: 'mongodb' - brief: 'MongoDB' - - id: redis - value: 'redis' - brief: 'Redis' - - id: couchbase - value: 'couchbase' - brief: 'Couchbase' - - id: couchdb - value: 'couchdb' - brief: 'CouchDB' - - id: cosmosdb - value: 'cosmosdb' - brief: 'Microsoft Azure Cosmos DB' - - id: dynamodb - value: 'dynamodb' - brief: 'Amazon DynamoDB' - - id: neo4j - value: 'neo4j' - brief: 'Neo4j' - - id: geode - value: 'geode' - brief: 'Apache Geode' - - id: elasticsearch - value: 'elasticsearch' - brief: 'Elasticsearch' - - id: memcached - value: 'memcached' - brief: 'Memcached' - - id: cockroachdb - value: 'cockroachdb' - brief: 'CockroachDB' - - id: opensearch - value: 'opensearch' - brief: 'OpenSearch' - - id: clickhouse - value: 'clickhouse' - brief: 'ClickHouse' - - id: spanner - value: 'spanner' - brief: 'Cloud Spanner' - - id: trino - value: 'trino' - brief: 'Trino' - - id: connection_string + + - ref: db.connection_string tag: connection-level - type: string - brief: > - The connection string used to connect to the database. - It is recommended to remove embedded credentials. - examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - - id: user + - ref: db.user tag: connection-level - type: string - brief: > - Username for accessing the database. - examples: ['readonly_user', 'reporting_user'] - - id: jdbc.driver_classname + - ref: db.jdbc.driver_classname tag: connection-level-tech-specific - type: string - brief: > - The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. - examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - - id: name + - ref: db.name tag: call-level - type: string requirement_level: conditionally_required: If applicable. - brief: > - This attribute is used to report the name of the database being accessed. - For commands that switch the database, this should be set to the target database - (even if the command fails). - note: > - In some SQL databases, the database name to be used is called "schema name". - In case there are multiple layers that could be considered for database name - (e.g. Oracle instance name and schema name), - the database name to be used is the more specific layer (e.g. Oracle schema name). - examples: [ 'customers', 'main' ] - - id: statement + - ref: db.statement tag: call-level - type: string requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. - brief: > - The database statement being executed. - examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] - - id: operation + - ref: db.operation tag: call-level - type: string requirement_level: conditionally_required: If `db.statement` is not applicable. - brief: > - The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) - such as `findAndModify`, or the SQL keyword. - note: > - When setting this to an SQL keyword, it is not recommended to - attempt any client-side parsing of `db.statement` just to get this - property, but it should be set if the operation name is provided by - the library being instrumented. - If the SQL statement has an ambiguous operation, or performs more - than one operation, this value may be omitted. - examples: ['findAndModify', 'HMSET', 'SELECT'] - ref: server.address tag: connection-level brief: > @@ -248,25 +48,15 @@ groups: tag: connection-level - id: db.mssql - prefix: db.mssql type: span extends: db brief: > Connection-level attributes for Microsoft SQL Server attributes: - - id: instance_name + - ref: db.mssql.instance_name tag: connection-level-tech-specific - type: string - note: > - If setting a `db.mssql.instance_name`, `server.port` is no longer - required (but still recommended if non-standard). - brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) - connecting to. This name is used to determine the port of a named instance. - examples: 'MSSQLSERVER' - id: db.cassandra - prefix: db.cassandra type: span extends: db brief: > @@ -278,79 +68,22 @@ groups: The keyspace name in Cassandra. examples: ["mykeyspace"] note: For Cassandra the `db.name` should be set to the Cassandra keyspace name. - - id: page_size - type: int + - ref: db.cassandra.page_size tag: call-level-tech-specific-cassandra - brief: > - The fetch size used for paging, i.e. how many rows will be returned at once. - examples: [5000] - - id: consistency_level + - ref: db.cassandra.consistency_level tag: call-level-tech-specific-cassandra - brief: > - The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). - type: - members: - - id: all - value: 'all' - - id: each_quorum - value: 'each_quorum' - - id: quorum - value: 'quorum' - - id: local_quorum - value: 'local_quorum' - - id: one - value: 'one' - - id: two - value: 'two' - - id: three - value: 'three' - - id: local_one - value: 'local_one' - - id: any - value: 'any' - - id: serial - value: 'serial' - - id: local_serial - value: 'local_serial' - - id: table - type: string + - ref: db.cassandra.table tag: call-level-tech-specific-cassandra - requirement_level: recommended - brief: The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). - note: > - This mirrors the db.sql.table attribute but references cassandra rather than sql. - It is not recommended to attempt any client-side parsing of - `db.statement` just to get this property, but it should be set if - it is provided by the library being instrumented. - If the operation is acting upon an anonymous table, or more than one table, this - value MUST NOT be set. - examples: 'mytable' - - id: idempotence - type: boolean + - ref: db.cassandra.idempotence tag: call-level-tech-specific-cassandra - brief: > - Whether or not the query is idempotent. - - id: speculative_execution_count - type: int + - ref: db.cassandra.speculative_execution_count tag: call-level-tech-specific-cassandra - brief: > - The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. - examples: [0, 2] - - id: coordinator.id - type: string + - ref: db.cassandra.coordinator.id tag: call-level-tech-specific-cassandra - brief: > - The ID of the coordinating node for a query. - examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' - - id: coordinator.dc - type: string + - ref: db.cassandra.coordinator.dc tag: call-level-tech-specific-cassandra - brief: > - The data center of the coordinating node for a query. - examples: 'us-west-2' - id: db.hbase - prefix: db.hbase type: span extends: db brief: > @@ -364,7 +97,6 @@ groups: note: For HBase the `db.name` should be set to the HBase namespace. - id: db.couchdb - prefix: db.couchdb type: span extends: db brief: > @@ -383,21 +115,15 @@ groups: [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). - id: db.redis - prefix: db.redis type: span extends: db brief: > Call-level attributes for Redis attributes: - - id: database_index - type: int + - ref: db.redis.database_index requirement_level: conditionally_required: If other than the default database (`0`). tag: call-level-tech-specific - brief: > - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. - To be used instead of the generic `db.name` attribute. - examples: [0, 1, 15] - ref: db.statement tag: call-level-tech-specific brief: > @@ -408,22 +134,16 @@ groups: If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. - id: db.mongodb - prefix: db.mongodb type: span extends: db brief: > Call-level attributes for MongoDB attributes: - - id: collection - type: string + - ref: db.mongodb.collection requirement_level: required tag: call-level-tech-specific - brief: > - The collection being accessed within the database stated in `db.name`. - examples: [ 'customers', 'products' ] - id: db.elasticsearch - prefix: db.elasticsearch type: span extends: db brief: > @@ -431,13 +151,16 @@ groups: attributes: - ref: http.request.method requirement_level: required + tag: call-level-tech-specific - ref: db.operation requirement_level: required brief: The endpoint identifier for the request. examples: [ 'search', 'ml.close_job', 'cat.aliases' ] + tag: call-level-tech-specific - ref: url.full requirement_level: required examples: [ 'https://localhost:9200/index/_search?q=user.id:kimchy' ] + tag: call-level-tech-specific - ref: db.statement requirement_level: recommended: > @@ -445,59 +168,34 @@ groups: sensitive information. brief: The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. examples: [ '"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"' ] + tag: call-level-tech-specific - ref: server.address + tag: call-level-tech-specific - ref: server.port - - id: cluster.name - type: string + tag: call-level-tech-specific + - ref: db.elasticsearch.cluster.name requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. tag: call-level-tech-specific - brief: > - Represents the identifier of an Elasticsearch cluster. - examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] - - id: node.name - type: string + - ref: db.elasticsearch.node.name requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. tag: call-level-tech-specific - brief: > - Represents the human-readable identifier of the node/instance to which a request was routed. - examples: ["instance-0000000001"] - - id: path_parts - type: template[string] + - ref: db.elasticsearch.path_parts requirement_level: conditionally_required: when the url has dynamic values tag: call-level-tech-specific - brief: > - A dynamic value in the url path. - note: > - Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format - `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD - reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) - in order to map the path part values to their names. - examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - id: db.sql - prefix: 'db.sql' type: span extends: 'db' brief: > Call-level attributes for SQL databases attributes: - - id: table + - ref: db.sql.table tag: call-level-tech-specific - type: string - requirement_level: recommended - brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). - note: > - It is not recommended to attempt any client-side parsing of - `db.statement` just to get this property, but it should be set if - it is provided by the library being instrumented. - If the operation is acting upon an anonymous table, or more than one table, this - value MUST NOT be set. - examples: ['public.users', 'customers'] - id: db.cosmosdb type: span @@ -506,47 +204,12 @@ groups: brief: > Call-level attributes for Cosmos DB. attributes: - - id: client_id - type: string - brief: Unique Cosmos client instance id. - examples: '3ba4827d-4422-483f-b59f-85b74211c11d' - - id: operation_type - type: - allow_custom_values: true - members: - - id: invalid - value: 'Invalid' - - id: create - value: 'Create' - - id: patch - value: 'Patch' - - id: read - value: 'Read' - - id: read_feed - value: 'ReadFeed' - - id: delete - value: 'Delete' - - id: replace - value: 'Replace' - - id: execute - value: 'Execute' - - id: query - value: 'Query' - - id: head - value: 'Head' - - id: head_feed - value: 'HeadFeed' - - id: upsert - value: 'Upsert' - - id: batch - value: 'Batch' - - id: query_plan - value: 'QueryPlan' - - id: execute_javascript - value: 'ExecuteJavaScript' - brief: CosmosDB Operation Type. + - ref: db.cosmosdb.client_id + tag: call-level-tech-specific + - ref: db.cosmosdb.operation_type requirement_level: conditionally_required: when performing one of the operations in this list + tag: call-level-tech-specific - ref: user_agent.original brief: 'Full user-agent string is generated by Cosmos DB SDK' note: > @@ -561,46 +224,29 @@ groups: Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). Default value is "NS". examples: ['cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|'] - - id: connection_mode - type: - allow_custom_values: false - members: - - id: gateway - value: 'gateway' - brief: Gateway (HTTP) connections mode - - id: direct - value: 'direct' - brief: Direct connection. - brief: Cosmos client connection mode. + tag: call-level-tech-specific + - ref: db.cosmosdb.connection_mode requirement_level: conditionally_required: if not `direct` (or pick gw as default) - - id: container - type: string - brief: Cosmos DB container name. + tag: call-level-tech-specific + - ref: db.cosmosdb.container requirement_level: conditionally_required: if available - examples: 'anystring' - - id: request_content_length - type: int - brief: Request payload size in bytes - - id: status_code - type: int - brief: Cosmos DB status code. - examples: [200, 201] + tag: call-level-tech-specific + - ref: db.cosmosdb.request_content_length + tag: call-level-tech-specific + - ref: db.cosmosdb.status_code requirement_level: conditionally_required: if response was received - - id: sub_status_code - type: int - brief: Cosmos DB sub status code. - examples: [1000, 1002] + tag: call-level-tech-specific + - ref: db.cosmosdb.sub_status_code requirement_level: conditionally_required: when response was received and contained sub-code. - - id: request_charge - type: double - brief: RU consumed for that operation - examples: [46.18, 1.0] + tag: call-level-tech-specific + - ref: db.cosmosdb.request_charge requirement_level: conditionally_required: when available + tag: call-level-tech-specific - id: db.tech type: span From 8962dbeedaaa0c99358231426f810f46eda9dcde Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 17 Nov 2023 00:57:45 -0800 Subject: [PATCH 280/482] Remove misleading pluralization wording related to count metrics (#488) Co-authored-by: Alexander Wert --- CHANGELOG.md | 3 +++ docs/general/metrics.md | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21cbd4c1bb..deffa3d7c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ release. ### Fixes +- Remove misleading pluralization wording related to count metrics + ([#488](https://github.com/open-telemetry/semantic-conventions/pull/488)) + ## v1.23.0 (2023-11-03) This release marks the first where the core of HTTP semantic conventions have diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 058a12e636..74699fbad0 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -124,12 +124,10 @@ should be pluralized, even if only a single data point is recorded. If the value being recorded represents the count of concepts signified by the namespace then the metric should be named `count` (within its namespace). -The pluralization rule does not apply in this case. -For example if we have a namespace `system.processes` which contains all metrics related +For example if we have a namespace `system.process` which contains all metrics related to the processes then to represent the count of the processes we can have a metric named -`system.processes.count`. The suffix `count` here indicates that it is the count of -`system.processes`. +`system.process.count`. #### Do not use `total` From b5b1e6a020e47ec7d3361a8293d7d291034a598e Mon Sep 17 00:00:00 2001 From: Armin Ruech <7052238+arminru@users.noreply.github.com> Date: Fri, 17 Nov 2023 16:45:33 +0100 Subject: [PATCH 281/482] [CI] Run checks.yml on all branches (#540) --- .github/workflows/checks.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 4ae744dcbe..a387a9db22 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -2,9 +2,7 @@ name: Checks on: push: - branches: [ main ] pull_request: - branches: [ main ] jobs: markdownlint: From dccfffc9bfc5480099bdcac4b99c700410112e3b Mon Sep 17 00:00:00 2001 From: Anna Levenberg Date: Sun, 19 Nov 2023 05:06:31 -0500 Subject: [PATCH 282/482] docs(messaging): add gcp_pubsub ordering key attribute (#528) Co-authored-by: Alexander Wert --- CHANGELOG.md | 4 +++- CONTRIBUTING.md | 8 ++++---- docs/attributes-registry/messaging.md | 1 + docs/messaging/gcp-pubsub.md | 9 +++++++++ model/registry/messaging.yaml | 5 +++++ model/trace/messaging.yaml | 10 ++++++++++ 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deffa3d7c7..64ba5be8b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ release. ([#503](https://github.com/open-telemetry/semantic-conventions/pull/503)) - Add Semantic conventions for TLS/SSL encrypted communication. ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) +- Add `messaging.gcp_pubsub.message.ordering_key` attribute. + ([#528](https://github.com/open-telemetry/semantic-conventions/pull/528)) ### Fixes @@ -123,7 +125,7 @@ stabilized. - Remove experimental Kafka metrics ([#338](https://github.com/open-telemetry/semantic-conventions/pull/338)) - Adds `session.id` and session.md to general docs and model -([#215](https://github.com/open-telemetry/semantic-conventions/pull/215)) + ([#215](https://github.com/open-telemetry/semantic-conventions/pull/215)) - Add `container.labels.` attributes. ([#125](https://github.com/open-telemetry/semantic-conventions/pull/125)) - Add `cluster.name` and `node.name` attributes to Elasticsearch semantic conventions. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e4d9addaa..7efad36fa2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -161,14 +161,14 @@ make misspell-correction A PR (pull request) is considered to be **ready to merge** when: -* It has received at least two approvals from the [code +- It has received at least two approvals from the [code owners](./.github/CODEOWNERS) (if approvals are from only one company, they won't count). -* There is no `request changes` from the [code owners](./.github/CODEOWNERS). -* It has been at least two working days since the last modification (except for +- There is no `request changes` from the [code owners](./.github/CODEOWNERS). +- It has been at least two working days since the last modification (except for the trivial updates, such like typo, cosmetic, rebase, etc.). This gives people reasonable time to review. -* Trivial changes (typos, cosmetic changes, CI improvements, etc.) don't have to +- Trivial changes (typos, cosmetic changes, CI improvements, etc.) don't have to wait for two days. Any [maintainer](./README.md#contributing) can merge the PR once it is **ready diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index fe5523c85d..626d8cc59f 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -16,6 +16,7 @@ | `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | | `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | | `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | +| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | | `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | | `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [5] | `myKey` | diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 848f144fc3..08027ce032 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -10,4 +10,13 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub `messaging.system` MUST be set to `"gcp_pubsub"`. +## Span attributes + +For Google Cloud Pub/Sub, the following additional attributes are defined: + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | Conditionally Required: If the message type has an ordering key set. | + + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 64dc6fe5a0..c7ba8fd457 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -202,6 +202,11 @@ groups: brief: > Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' + - id: gcp_pubsub.message.ordering_key + type: string + brief: > + The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. + examples: 'ordering_key' - id: system brief: > An identifier for the messaging system being used. See below for a list of well-known identifiers. diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index c14b92dfa7..9163de0b4b 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -170,3 +170,13 @@ groups: tag: tech-specific-rocketmq - ref: messaging.rocketmq.consumption_model tag: tech-specific-rocketmq + - id: messaging.gcp_pubsub + type: attribute_group + extends: messaging + brief: > + Attributes for Google Cloud Pub/Sub + attributes: + - ref: messaging.gcp_pubsub.message.ordering_key + tag: tech-specific-gcp-pubsub + requirement_level: + conditionally_required: If the message type has an ordering key set. From 126059d99dc29fd9a59893091f56500d4b9674b7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 20 Nov 2023 07:45:22 -0800 Subject: [PATCH 283/482] Rename metrics `jvm.memory.usage` to `jvm.memory.used` and `jvm.memory.usage_after_last_gc` to `jvm.memory.used_after_last_gc` (#536) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/runtime/jvm-metrics.md | 20 ++++++++++---------- model/metrics/jvm-metrics.yaml | 8 ++++---- schema-next.yaml | 4 ++++ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64ba5be8b1..0e6f2f2257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ release. ([#495](https://github.com/open-telemetry/semantic-conventions/issues/495)) - Changed `messaging.system` attribute type to an open enum ([#517](https://github.com/open-telemetry/semantic-conventions/pull/517)) +- Rename metrics `jvm.memory.usage` to `jvm.memory.used` and `jvm.memory.usage_after_last_gc` + to `jvm.memory.used_after_last_gc` + ([#536](https://github.com/open-telemetry/semantic-conventions/pull/536)) ### Features diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 4e7825c857..41e2d38ac4 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -13,10 +13,10 @@ This document describes semantic conventions for JVM metrics in OpenTelemetry. - [JVM Memory](#jvm-memory) - * [Metric: `jvm.memory.usage`](#metric-jvmmemoryusage) + * [Metric: `jvm.memory.used`](#metric-jvmmemoryused) * [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) - * [Metric: `jvm.memory.usage_after_last_gc`](#metric-jvmmemoryusage_after_last_gc) + * [Metric: `jvm.memory.used_after_last_gc`](#metric-jvmmemoryused_after_last_gc) - [JVM Garbage Collection](#jvm-garbage-collection) * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) - [JVM Threads](#jvm-threads) @@ -43,18 +43,18 @@ This document describes semantic conventions for JVM metrics in OpenTelemetry. **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.memory.*` -### Metric: `jvm.memory.usage` +### Metric: `jvm.memory.used` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.memory.usage` | UpDownCounter | `By` | Measure of memory used. | +| `jvm.memory.used` | UpDownCounter | `By` | Measure of memory used. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | @@ -124,18 +124,18 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | `non_heap` | Non-heap memory | -### Metric: `jvm.memory.usage_after_last_gc` +### Metric: `jvm.memory.used_after_last_gc` This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getCollectionUsage--). - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `jvm.memory.usage_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | +| `jvm.memory.used_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index c837145a8c..ba1f560453 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -26,9 +26,9 @@ groups: Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - - id: metric.jvm.memory.usage + - id: metric.jvm.memory.used type: metric - metric_name: jvm.memory.usage + metric_name: jvm.memory.used extends: attributes.jvm.memory brief: "Measure of memory used." instrument: updowncounter @@ -50,9 +50,9 @@ groups: instrument: updowncounter unit: "By" - - id: metric.jvm.memory.usage_after_last_gc + - id: metric.jvm.memory.used_after_last_gc type: metric - metric_name: jvm.memory.usage_after_last_gc + metric_name: jvm.memory.used_after_last_gc extends: attributes.jvm.memory brief: "Measure of memory used, as measured after the most recent garbage collection event on this pool." instrument: updowncounter diff --git a/schema-next.yaml b/schema-next.yaml index 4f618de046..ae84e381af 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,10 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + # https://github.com/open-telemetry/semantic-conventions/pull/536 + - rename_metrics: + jvm.memory.usage: jvm.memory.used + jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc 1.23.0: metrics: changes: From 04c8e49dc4fd359c1fd42e2a37c2d685ea9cfeb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Thallis?= Date: Tue, 21 Nov 2023 09:58:45 -0300 Subject: [PATCH 284/482] Use new partition attribute path (#547) --- docs/messaging/kafka.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 4bd6c4da57..ffb30d89c2 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -81,7 +81,7 @@ Process CB: | Span Rcv2 | | `messaging.client_id` | | `"5"` | `"5"` | `"5"` | `"8"` | | `messaging.kafka.message.key` | `"myKey"` | `"myKey"` | `"myKey"` | `"anotherKey"` | `"anotherKey"` | | `messaging.kafka.consumer.group` | | `"my-group"` | `"my-group"` | | `"another-group"` | -| `messaging.kafka.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | +| `messaging.kafka.destination.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | | `messaging.kafka.message.offset` | `"12"` | `"12"` | `"12"` | `"32"` | `"32"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md From 34cc9485be987bb65e1ed01bf3d8d549e2f74a27 Mon Sep 17 00:00:00 2001 From: Braydon Kains <93549768+braydonk@users.noreply.github.com> Date: Wed, 22 Nov 2023 05:25:58 -0500 Subject: [PATCH 285/482] system: shared IO direction attributes (#530) Co-authored-by: Alexander Wert --- docs/attributes-registry/network.md | 8 ++++++ docs/system/system-metrics.md | 32 ++++++++++----------- model/metrics/system-metrics.yaml | 44 +++++++---------------------- model/registry/disk.yaml | 17 +++++++++++ model/registry/network.yaml | 10 +++++++ 5 files changed, 61 insertions(+), 50 deletions(-) create mode 100644 model/registry/disk.yaml diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 77f00acedd..a6c5907728 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -16,6 +16,7 @@ These attributes may be used for any network related operation. | `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | | `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | | `network.connection.type` | string | The internet connection type. | `wifi` | +| `network.io.direction` | string | The network IO operation direction. | `transmit` | | `network.local.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | `network.local.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local port number of the network connection. | `65123` | | `network.peer.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | @@ -73,6 +74,13 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `unavailable` | unavailable | | `unknown` | unknown | +`network.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + `network.transport` 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 | diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index d5848d424d..f33a871e4a 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -359,10 +359,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | -`system.disk.direction` MUST be one of the following: +`disk.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -383,10 +383,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | -`system.disk.direction` MUST be one of the following: +`disk.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -435,10 +435,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | -`system.disk.direction` MUST be one of the following: +`disk.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -459,10 +459,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.disk.direction` | string | The disk operation direction | `read` | Recommended | -`system.disk.direction` MUST be one of the following: +`disk.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -575,10 +575,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.network.direction` | string | | `transmit` | Recommended | -`system.network.direction` MUST be one of the following: +`network.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -599,10 +599,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.network.direction` | string | | `transmit` | Recommended | -`system.network.direction` MUST be one of the following: +`network.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -629,10 +629,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.network.direction` | string | | `transmit` | Recommended | -`system.network.direction` MUST be one of the following: +`network.io.direction` MUST be one of the following: | Value | Description | |---|---| @@ -653,10 +653,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.network.direction` | string | | `transmit` | Recommended | -`system.network.direction` MUST be one of the following: +`network.io.direction` MUST be one of the following: | Value | Description | |---|---| diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index d3c761b0b9..d411115ea8 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -213,22 +213,6 @@ groups: - ref: system.paging.direction # system.disk.* metrics and attribute group - - id: attributes.system.disk - prefix: system.disk - type: attribute_group - brief: "Describes System Disk metric attributes" - attributes: - - id: direction - type: - allow_custom_values: false - members: - - id: read - value: 'read' - - id: write - value: 'write' - brief: "The disk operation direction" - examples: ["read"] - - id: metric.system.disk.io type: metric metric_name: system.disk.io @@ -237,7 +221,7 @@ groups: unit: "By" attributes: - ref: system.device - - ref: system.disk.direction + - ref: disk.io.direction - id: metric.system.disk.operations type: metric @@ -247,7 +231,7 @@ groups: unit: "{operation}" attributes: - ref: system.device - - ref: system.disk.direction + - ref: disk.io.direction - id: metric.system.disk.io_time type: metric @@ -278,7 +262,7 @@ groups: - Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" perf counter (similar for Writes) attributes: - ref: system.device - - ref: system.disk.direction + - ref: disk.io.direction - id: metric.system.disk.merged type: metric @@ -288,7 +272,7 @@ groups: unit: "{operation}" attributes: - ref: system.device - - ref: system.disk.direction + - ref: disk.io.direction # system.filesystem.* metrics and attribute group - id: attributes.system.filesystem @@ -362,21 +346,13 @@ groups: - ref: system.filesystem.mountpoint # system.network.* metrics and attribute group + + # System-specific network attributes - id: attributes.system.network prefix: system.network type: attribute_group brief: "Describes Network metric attributes" attributes: - - id: direction - type: - allow_custom_values: false - members: - - id: transmit - value: 'transmit' - - id: receive - value: 'receive' - brief: "" - examples: ["transmit"] - id: state type: allow_custom_values: false @@ -422,7 +398,7 @@ groups: from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2) attributes: - ref: system.device - - ref: system.network.direction + - ref: network.io.direction - id: metric.system.network.packets type: metric @@ -432,7 +408,7 @@ groups: unit: "{packet}" attributes: - ref: system.device - - ref: system.network.direction + - ref: network.io.direction - id: metric.system.network.errors type: metric @@ -448,7 +424,7 @@ groups: from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). attributes: - ref: system.device - - ref: system.network.direction + - ref: network.io.direction - id: metric.system.network.io type: metric @@ -458,7 +434,7 @@ groups: unit: "By" attributes: - ref: system.device - - ref: system.network.direction + - ref: network.io.direction - id: metric.system.network.connections type: metric diff --git a/model/registry/disk.yaml b/model/registry/disk.yaml new file mode 100644 index 0000000000..90d6fb27d2 --- /dev/null +++ b/model/registry/disk.yaml @@ -0,0 +1,17 @@ +groups: + - id: registry.disk + prefix: disk + type: attribute_group + brief: > + These attributes may be used for any disk related operation. + attributes: + - id: io.direction + type: + allow_custom_values: false + members: + - id: read + value: 'read' + - id: write + value: 'write' + brief: "The disk IO operation direction." + examples: ["read"] diff --git a/model/registry/network.yaml b/model/registry/network.yaml index 27b072a08c..7715506bcc 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -182,3 +182,13 @@ groups: brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' note: The value SHOULD be normalized to lowercase. examples: ['ipv4', 'ipv6'] + - id: io.direction + type: + allow_custom_values: false + members: + - id: transmit + value: 'transmit' + - id: receive + value: 'receive' + brief: "The network IO operation direction." + examples: ["transmit"] From b56abb47dffa6e1c4d51cd9e25a7bf1495a793dd Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 22 Nov 2023 08:25:27 -0800 Subject: [PATCH 286/482] Remove Oct 1 mention from `OTEL_SEMCONV_STABILITY_OPT_IN` (#541) Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 2 ++ docs/database/database-spans.md | 3 +-- docs/http/README.md | 3 +-- docs/http/http-metrics.md | 3 +-- docs/http/http-spans.md | 3 +-- docs/messaging/messaging-spans.md | 3 +-- docs/rpc/rpc-metrics.md | 3 +-- docs/rpc/rpc-spans.md | 3 +-- 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e6f2f2257..fe2a62e63b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ release. - Remove misleading pluralization wording related to count metrics ([#488](https://github.com/open-telemetry/semantic-conventions/pull/488)) +- Remove no longer relevant Oct 1 mention from `OTEL_SEMCONV_STABILITY_OPT_IN` + ([#541](https://github.com/open-telemetry/semantic-conventions/pull/541)) ## v1.23.0 (2023-11-03) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index b6cf27a20f..8a1d7055f7 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -41,8 +41,7 @@ linkTitle: Client Calls > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. **Span kind:** MUST always be `CLIENT`. diff --git a/docs/http/README.md b/docs/http/README.md index c76f1367cb..c4ae8a10d2 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -37,8 +37,7 @@ and various HTTP versions like 1.1, 2 and SPDY. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. Semantic conventions for HTTP are defined for the following signals: diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index f9cde0544c..eae37608ed 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -50,8 +50,7 @@ operations. By adding HTTP attributes to metric events it allows for finely tune > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. ## HTTP Server diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index a991bf0984..98bc63d4ba 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -61,8 +61,7 @@ and various HTTP versions like 1.1, 2 and SPDY. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. ## Name diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 19cfbc43e1..8dc249dfb2 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -59,8 +59,7 @@ > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. ## Definitions diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 5e28b81bdc..106e2e6c4a 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -59,8 +59,7 @@ metrics can be filtered for finer grain analysis. > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. ## Metric instruments diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 7e50888583..c3a9554350 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -49,8 +49,7 @@ This document defines how to describe remote procedure calls > * Note: `http/dup` has higher precedence than `http` in case both values are present > * SHOULD maintain (security patching at a minimum) the existing major version > for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version (stable -> next major version SHOULD NOT be released prior to October 1, 2023). +> * SHOULD drop the environment variable in the next major version. ## Common remote procedure call conventions From 9d9990cfe82a823fd8d79fb5b452fbad2fc6894e Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 23 Nov 2023 05:24:22 -0600 Subject: [PATCH 287/482] Add registry md file for disk attributes (#555) Signed-off-by: ChrsMark --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/disk.md | 19 +++++++++++++++++++ docs/system/system-metrics.md | 8 ++++---- 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 docs/attributes-registry/disk.md diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index c8a0702d3e..2e483c4eda 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -34,6 +34,7 @@ Currently, the following namespaces exist: * [DB](db.md) (database) * [Destination](destination.md) * [Device](device.md) +* [Disk](disk.md) * [Error](error.md) * [Host](host.md) * [HTTP](http.md) diff --git a/docs/attributes-registry/disk.md b/docs/attributes-registry/disk.md new file mode 100644 index 0000000000..a983873365 --- /dev/null +++ b/docs/attributes-registry/disk.md @@ -0,0 +1,19 @@ + + +# Disk + +## Disk Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | + +`disk.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index f33a871e4a..d39384babc 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -359,7 +359,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | `disk.io.direction` MUST be one of the following: @@ -383,7 +383,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | `disk.io.direction` MUST be one of the following: @@ -435,7 +435,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | `disk.io.direction` MUST be one of the following: @@ -459,7 +459,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | Recommended | +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | | `system.device` | string | The device identifier | `(identifier)` | Recommended | `disk.io.direction` MUST be one of the following: From 12dfe6a3210b19c41a9bb840bc1f0b5796f3bef2 Mon Sep 17 00:00:00 2001 From: Patrick Housley Date: Fri, 24 Nov 2023 05:34:00 -0600 Subject: [PATCH 288/482] Merging events domain and name (#473) Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> Co-authored-by: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> Co-authored-by: Joao Grassi Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/general/events.md | 31 ++++++------------------------- docs/mobile/events.md | 15 +++++++++------ model/logs/events.yaml | 26 ++++++-------------------- model/logs/mobile-events.yaml | 7 +++---- 5 files changed, 26 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe2a62e63b..bfe047e7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ release. - Rename metrics `jvm.memory.usage` to `jvm.memory.used` and `jvm.memory.usage_after_last_gc` to `jvm.memory.used_after_last_gc` ([#536](https://github.com/open-telemetry/semantic-conventions/pull/536)) +- BREAKING: Change `event.name` definition to include `namespace` and remove `event.domain` from log event attributes. + ([#473](https://github.com/open-telemetry/semantic-conventions/pull/473)) ### Features diff --git a/docs/general/events.md b/docs/general/events.md index 3ca2c7cd89..8fcd24cf8a 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -17,20 +17,10 @@ The following semantic conventions for events are defined: ## General event attributes -Events are recorded as LogRecords that are shaped -in a special way: Event LogRecords have the attributes `event.domain` -and `event.name` (and possibly other LogRecord attributes). - -The `event.domain` attribute is used to logically separate events from different -systems. For example, to record Events from browser apps, mobile apps and -Kubernetes, we could use `browser`, `device` and `k8s` as the domain for their -Events. This provides a clean separation of semantics for events in each of the -domains. - -Within a particular domain, the `event.name` attribute identifies the event. -Events with same domain and name are structurally similar to one another. For -example, some domains could have well-defined schema for their events based on -event names. +Events are recorded as LogRecords that are shaped in a special way: Event +LogRecords have the attribute `event.name` that uniquely identifies the event. +Events with same `event.name` are structurally similar to one another. Events +may also have other LogRecord attributes. When recording events from an existing system as OpenTelemetry Events, it is possible that the existing system does not have the equivalent of a name or @@ -43,18 +33,9 @@ that identify the class of Events but not the instance of the Event. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `event.domain` | string | The domain identifies the business context for the events. [1] | `browser` | Required | -| `event.name` | string | The name identifies the event. | `click`; `exception` | Required | - -**[1]:** Events across different domains may have same `event.name`, yet be unrelated events. - -`event.domain` 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. +| `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | Required | -| Value | Description | -|---|---| -| `browser` | Events from browser apps | -| `device` | Events from mobile apps | -| `k8s` | Events from Kubernetes | +**[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/mobile/events.md b/docs/mobile/events.md index df020e2c04..70a5d6fdc3 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -2,8 +2,9 @@ **Status**: [Experimental][DocumentStatus] -This document defines semantic conventions for instrumentations that emit events on mobile platforms. -All mobile events MUST set `event.domain` as `device`. +This document defines semantic conventions for instrumentations that emit +events on mobile platforms. All mobile events MUST use a namespace of +`device` in the `event.name` property. @@ -15,13 +16,15 @@ All mobile events MUST set `event.domain` as `device`. ## Lifecycle instrumentation -This section defines how to apply semantic conventions when instrumenting application lifecycle. -This event is meant to be used in conjunction with `os.name` [resource semantic convention](/docs/resource/os.md) to identify the mobile operating system (e.g. Android, iOS). +This section defines how to apply semantic conventions when instrumenting +application lifecycle. This event is meant to be used in conjunction with +`os.name` [resource semantic convention](/docs/resource/os.md) to identify the +mobile operating system (e.g. Android, iOS). ### iOS -The event name MUST be `app.lifecycle`. +The event name MUST be `device.app.lifecycle`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| @@ -43,7 +46,7 @@ The event name MUST be `app.lifecycle`. ### Android -The event name MUST be `app.lifecycle`. +The event name MUST be `device.app.lifecycle`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| diff --git a/model/logs/events.yaml b/model/logs/events.yaml index aed530cb1c..3942d432fd 100644 --- a/model/logs/events.yaml +++ b/model/logs/events.yaml @@ -9,24 +9,10 @@ groups: type: string requirement_level: required brief: > - The name identifies the event. - examples: ['click', 'exception'] - - id: domain - brief: > - The domain identifies the business context for the events. - type: - allow_custom_values: true - members: - - id: browser - value: 'browser' - brief: 'Events from browser apps' - - id: device - value: 'device' - brief: 'Events from mobile apps' - - id: k8s - value: 'k8s' - brief: 'Events from Kubernetes' - requirement_level: required + Identifies the class / type of event. note: > - Events across different domains may have same `event.name`, yet be - unrelated events. + Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md). + Notably, event names are namespaced to avoid collisions and provide a clean + separation of semantics for events in separate domains like browser, mobile, and + kubernetes. + examples: ['browser.mouse.click', 'device.app.lifecycle'] diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index 797851cb48..d6f49e70c5 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -2,9 +2,9 @@ groups: - id: ios.lifecycle.events type: event prefix: ios - name: app.lifecycle + name: device.app.lifecycle brief: > - This event represents an occurrence of a lifecycle transition on the iOS platform. `event.domain` MUST be `device`. + This event represents an occurrence of a lifecycle transition on the iOS platform. attributes: - id: state requirement_level: "required" @@ -41,10 +41,9 @@ groups: - id: android.lifecycle.events type: event prefix: android - name: app.lifecycle + name: device.app.lifecycle brief: > This event represents an occurrence of a lifecycle transition on the Android platform. - `event.domain` MUST be `device`. attributes: - id: state requirement_level: required From 0c6d5e1e5afb725fb30099e8319efc05e5398a2d Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Fri, 24 Nov 2023 14:08:44 +0100 Subject: [PATCH 289/482] Improve visibility of used spec version in the semconv repo (#558) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CONTRIBUTING.md | 2 ++ README.md | 19 +++++++++---------- .../tools/update_specification_version.sh | 5 +++++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7efad36fa2..2ab5ce406e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,8 @@ key, but non-obvious, aspects: defined in a schema file. As part of any contribution, you should include attribute changes defined in the `schema-next.yaml` file. For details, please read [the schema specification](https://opentelemetry.io/docs/specs/otel/schemas/). +- Links to the specification repository MUST point to a tag and **not** to the `main` branch. + The tag version MUST match with the one defined in [README](README.md). - After creating a pull request, please update the [CHANGELOG](CHANGELOG.md) file with a description of your changes. diff --git a/README.md b/README.md index dd38f511dc..4584d9d648 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ -# OpenTelemetry Semantic Conventions +# OpenTelemetry Icon OpenTelemetry Semantic Conventions -Welcome to the new repository! +[![Checks](https://github.com/open-telemetry/semantic-conventions/workflows/Checks/badge.svg?branch=main)](https://github.com/open-telemetry/semantic-conventions/actions?query=workflow%3A%22Checks%22+branch%3Amain) +[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/open-telemetry/semantic-conventions.svg?logo=opentelemetry&&color=f5a800&label=Latest%20release)](https://github.com/open-telemetry/semantic-conventions/releases/latest) +[![Specification Version](https://img.shields.io/badge/OTel_specification_version-v1.26.0-blue?logo=opentelemetry&color=f5a800)](https://github.com/open-telemetry/opentelemetry-specification/releases/tag/v1.26.0) -This is currently a direct copy/filter-branch of the Specification repository -with only semantic conventions included. - -This repository is currently using [this specification version][SpecificationVersion]. +Semantic Conventions define a common set of (semantic) attributes which +provide meaning to data when collecting, producing and consuming it. ## Read the docs -The documentation currently resides in the [docs](docs/README.md) folder. +The human-readable version of the semantic conventions resides in the [docs](docs/README.md) folder. +Major parts of these Markdown documents are generated from the YAML definitions located in the [model](model/README.md) folder. ## Contributing @@ -34,6 +35,4 @@ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs - [Josh Suereth](https://github.com/jsuereth), Google - [Reiley Yang](https://github.com/reyang), Microsoft -_Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)._ - -[SpecificationVersion]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0 +_Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer). diff --git a/internal/tools/update_specification_version.sh b/internal/tools/update_specification_version.sh index 86cd140b88..765c6c6f88 100755 --- a/internal/tools/update_specification_version.sh +++ b/internal/tools/update_specification_version.sh @@ -12,6 +12,9 @@ LATEST_SPECIFICATION_VERSION="v1.26.0" # The specific pattern we look for when replacing URLs SPECIFICATION_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/tree/" SPECIFICATION_BLOB_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/blob/" +# The specific pattern we look for updating the Badge with the spec version +SPECIFICATION_BADGE_PREFIX="https://img.shields.io/badge/OTel_specification_version-" +SPECIFICATION_BADGE_RELEASE_TAG_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/releases/tag/" fix_file() { @@ -19,6 +22,8 @@ fix_file() { sed -i \ -e "s,${SPECIFICATION_URL_PREFIX}${PREVIOUS_SPECIFICATION_VERSION},${SPECIFICATION_URL_PREFIX}${LATEST_SPECIFICATION_VERSION},g" \ -e "s,${SPECIFICATION_BLOB_URL_PREFIX}${PREVIOUS_SPECIFICATION_VERSION},${SPECIFICATION_URL_PREFIX}${LATEST_SPECIFICATION_VERSION},g" \ + -e "s,${SPECIFICATION_BADGE_PREFIX}${PREVIOUS_SPECIFICATION_VERSION},${SPECIFICATION_BADGE_PREFIX}${LATEST_SPECIFICATION_VERSION},g" \ + -e "s,${SPECIFICATION_BADGE_RELEASE_TAG_PREFIX}${PREVIOUS_SPECIFICATION_VERSION},${SPECIFICATION_BADGE_RELEASE_TAG_PREFIX}${LATEST_SPECIFICATION_VERSION},g" \ "$1" } From fe200c01bcf589b30f2ae9b81152d69252d8ea21 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Fri, 24 Nov 2023 14:37:17 +0100 Subject: [PATCH 290/482] Fix links still pointing to spec repo main branch (#556) --- docs/faas/aws-lambda.md | 2 +- docs/messaging/messaging-spans.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 50dba92033..e0f7800a39 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -66,7 +66,7 @@ contain an incomplete trace context which indicates X-Ray isn’t enabled. The e `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 the X-Ray Span Link is not desired. -**Note**: When instrumenting a Java AWS Lambda, instrumentation SHOULD first try to parse an OpenTelemetry `Context` out of the system property `com.amazonaws.xray.traceHeader` using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md) before checking and attempting to parse the environment variable above. +**Note**: When instrumenting a Java AWS Lambda, instrumentation SHOULD first try to parse an OpenTelemetry `Context` out of the system property `com.amazonaws.xray.traceHeader` using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) before checking and attempting to parse the environment variable above. [Span Link]: https://opentelemetry.io/docs/concepts/signals/traces/#span-links diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 8dc249dfb2..eb1d1ffce6 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -210,7 +210,7 @@ The following operations related to messages are defined for these semantic conv ### Span kind -[Span kinds](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind) +[Span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind) SHOULD be set according to the following table, based on the operation a span describes. | Operation name | Span kind| @@ -221,7 +221,7 @@ SHOULD be set according to the following table, based on the operation a span de | `deliver` | `CONSUMER` | For cases not covered by the table above, the span kind should be set according -to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind), +to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind), e. g. it should be set to CLIENT for the "Publish" span if its context is not used as creation context and if the "Publish" span models a synchronous call to the intermediary. From fc73453d045378e9d3f017a0241415b0ace1d2a6 Mon Sep 17 00:00:00 2001 From: Alexander Kaplan Date: Mon, 27 Nov 2023 00:01:28 -0800 Subject: [PATCH 291/482] Expanding k8s.pod resource to include pod labels (#494) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/attributes-registry/k8s.md | 1 + docs/resource/k8s.md | 1 + model/registry/k8s.yaml | 5 +++++ model/resource/k8s.yaml | 1 + 5 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfe047e7bc..e27d9b938e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ release. ### Features +- Adds `labels` attribute to `k8s.pod` resource + ([#494](https://github.com/open-telemetry/semantic-conventions/pull/494)) - Add `code.stacktrace` attribute ([#435](https://github.com/open-telemetry/semantic-conventions/pull/435)) - Add `http.flavor` and `http.user_agent` to list of deprecated attributes diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index 5778085ae8..9becbbf729 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -20,6 +20,7 @@ | `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | Recommended | | `k8s.node.name` | string | The name of the Node. | `node-1` | Recommended | | `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | +| `k8s.pod.labels.` | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | Recommended | | `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | | `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | | `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index 2c68757953..f5ed62b723 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -91,6 +91,7 @@ containers on your cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`k8s.pod.labels.`](../attributes-registry/k8s.md) | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | Recommended | | [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | | [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index c42744cb21..9c453fb691 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -64,6 +64,11 @@ groups: brief: > The name of the Pod. examples: ['opentelemetry-pod-autoconf'] + - id: pod.labels + type: template[string] + brief: > + The labels placed on the Pod, the `` being the label name, the value being the label value. + examples: ['k8s.pod.labels.app=my-app', 'k8s.pod.labels.mycompany.io/arch=x64', 'k8s.pod.labels.data='] - id: container.name type: string brief: > diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index 20947c8a93..f0752f0f09 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -33,6 +33,7 @@ groups: attributes: - ref: k8s.pod.uid - ref: k8s.pod.name + - ref: k8s.pod.labels - id: k8s.container prefix: k8s.container From efd9345199e986e61488def054a33f193acf7298 Mon Sep 17 00:00:00 2001 From: Ariel Valentin Date: Thu, 30 Nov 2023 02:22:16 -0600 Subject: [PATCH 292/482] feat: Add MySQL instance address attribute (#345) Co-authored-by: Alexander Wert --- docs/attributes-registry/db.md | 1 + docs/database/database-spans.md | 1 + model/registry/db.yaml | 8 ++++++++ model/trace/database.yaml | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 1964f71282..c178bbe971 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -23,6 +23,7 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | +| `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | | `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 8a1d7055f7..b352e48252 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -64,6 +64,7 @@ Some database systems may allow a connection to switch to a different `db.user`, | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.connection_string`](../attributes-registry/db.md) | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: If different from the `server.address` | | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 3ec2d84c66..a17c1046d4 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -422,3 +422,11 @@ groups: Username for accessing the database. examples: ['readonly_user', 'reporting_user'] tag: db-generic + - id: instance.id + tag: db-generic + type: string + brief: > + An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. + This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. + The client may obtain this value in databases like MySQL using queries like `select @@hostname`. + examples: 'mysql-e26b99z.example.com' diff --git a/model/trace/database.yaml b/model/trace/database.yaml index ed4f57161a..9df75ee20f 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -46,6 +46,10 @@ groups: tag: connection-level - ref: network.type tag: connection-level + - ref: db.instance.id + tag: connection-level + requirement_level: + recommended: If different from the `server.address` - id: db.mssql type: span From f51df2fdbcadef64686da1d037b09707403ab260 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 30 Nov 2023 08:06:23 -0800 Subject: [PATCH 293/482] Define messaging metrics and add `error.type` attribute to spans (#163) --- CHANGELOG.md | 2 + docs/messaging/README.md | 1 + docs/messaging/messaging-metrics.md | 182 ++++++++++++++++++++++++++++ docs/messaging/messaging-spans.md | 100 +++++++++------ model/messaging-common.yaml | 23 ++++ model/metrics/messaging.yaml | 62 ++++++++++ model/trace/messaging.yaml | 10 +- 7 files changed, 335 insertions(+), 45 deletions(-) create mode 100644 docs/messaging/messaging-metrics.md create mode 100644 model/messaging-common.yaml create mode 100644 model/metrics/messaging.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index e27d9b938e..201ae39221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ release. ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) - Add `messaging.gcp_pubsub.message.ordering_key` attribute. ([#528](https://github.com/open-telemetry/semantic-conventions/pull/528)) +- Add messaging metrics + ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) ### Fixes diff --git a/docs/messaging/README.md b/docs/messaging/README.md index 39b488e05e..5308786270 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -14,6 +14,7 @@ This document defines semantic conventions for messaging systems spans, metrics Semantic conventions for messaging systems are defined for the following signals: * [Messaging Spans](messaging-spans.md): Semantic Conventions for messaging *spans*. +* [Messaging Metrics](messaging-metrics.md): Semantic Conventions for messaging *metrics*. Technology specific semantic conventions are defined for the following messaging systems: diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md new file mode 100644 index 0000000000..b2f7046bdd --- /dev/null +++ b/docs/messaging/messaging-metrics.md @@ -0,0 +1,182 @@ +# Semantic Conventions for Messaging Metrics + +**Status**: [Experimental][DocumentStatus] + + + + + +- [Common attributes](#common-attributes) +- [Producer metrics](#producer-metrics) + * [Metric: `messaging.publish.duration`](#metric-messagingpublishduration) + * [Metric: `messaging.publish.messages`](#metric-messagingpublishmessages) +- [Consumer metrics](#consumer-metrics) + * [Metric: `messaging.receive.duration`](#metric-messagingreceiveduration) + * [Metric: `messaging.receive.messages`](#metric-messagingreceivemessages) + * [Metric: `messaging.deliver.duration`](#metric-messagingdeliverduration) + * [Metric: `messaging.deliver.messages`](#metric-messagingdelivermessages) + + + +## Common attributes + +All messaging metrics share the same set of attributes: + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | Conditionally Required: [4] | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | Conditionally Required: if available. | +| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `3.1.1` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | Recommended | + +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2]:** If and only if the messaging operation has failed. + +**[3]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + +**[4]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. + +**[5]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + +**[6]:** The value SHOULD be normalized to lowercase. + +**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[8]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[9]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + +`messaging.system` 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 | +|---|---| +| `activemq` | Apache ActiveMQ | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | +| `azure_eventgrid` | Azure Event Grid | +| `azure_eventhubs` | Azure Event Hubs | +| `azure_servicebus` | Azure Service Bus | +| `gcp_pubsub` | Google Cloud Pub/Sub | +| `jms` | Java Message Service | +| `kafka` | Apache Kafka | +| `rabbitmq` | RabbitMQ | +| `rocketmq` | Apache RocketMQ | + + +## Producer metrics + +### Metric: `messaging.publish.duration` + +This metric is [required][MetricRequired]. + +When this metric is reported alongside a messaging publish span, the metric value SHOULD be the same as the corresponding span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.publish.duration` | Histogram | `s` | Measures the duration of publish operation. | + + +### Metric: `messaging.publish.messages` + +This metric is [required][MetricRequired] when the messaging system supports batch publishing. It's [opt-in][MetricOptIn] when the messaging system does not support batch publishing, since the message count can be derived from the `messaging.publish.duration` histogram. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.publish.messages` | Counter | `{message}` | Measures the number of published messages. | + + +> The need to report `messaging.publish.messages` depends on the messaging system capabilities and not application scenarios or client library limitations. For example, RabbitMQ does not support batch publishing and corresponding instrumentations don't need to report `messaging.publish.messages`. Kafka supports both, single and batch publishing, and instrumentations MUST report `messaging.publish.messages` counter regardless of application scenarios or APIs available in the client library. + +## Consumer metrics + +### Metric: `messaging.receive.duration` + +This metric is [required][MetricRequired] for operations that are initiated by the application code (pull-based). + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + +When this metric is reported alongside a messaging receive span, the metric value SHOULD be the same as the corresponding span duration. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.receive.duration` | Histogram | `s` | Measures the duration of receive operation. | + + +### Metric: `messaging.receive.messages` + +This metric is [required][MetricRequired] for batch receive operations. It's [opt-in][MetricOptIn] when the messaging system does not support batch receive since the message count can be derived from the `messaging.receive.duration` histogram. + +_Note: The need to report `messaging.receive.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.receive.messages` | Counter | `{message}` | Measures the number of received messages. | + + +### Metric: `messaging.deliver.duration` + +This metric is [required][MetricRequired] for operations are not initiated by the application code (push-based deliver). + +When this metric is reported alongside a messaging deliver span, the metric value SHOULD be the same as the corresponding span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.deliver.duration` | Histogram | `s` | Measures the duration of deliver operation. | + + +### Metric: `messaging.deliver.messages` + +This metric is [required][MetricRequired] for batch delivery operations. It's [opt-in][MetricOptIn] when the messaging system does not support batch delivery since the message count can be derived from the `messaging.deliver.duration` histogram. + +_Note: The need to report `messaging.deliver.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `messaging.deliver.messages` | Counter | `{message}` | Measures the number of delivered messages. | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/document-status.md +[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#required +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#opt-in diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index eb1d1ffce6..7562e2972b 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -1,4 +1,4 @@ -# Messaging Systems +# Semantic Conventions for Messaging Spans **Status**: [Experimental][DocumentStatus] @@ -275,72 +275,100 @@ messages were received). For each message it accounts for, the "Deliver" or | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | Conditionally Required: [2] | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | +| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | Conditionally Required: [4] | | [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | -| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [3] | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [4] | `MyQueue`; `MyTopic` | Conditionally Required: [5] | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [6] | `/customers/{customerId}` | Conditionally Required: [7] | -| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [8] | -| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [9] | `1439` | Recommended: [10] | -| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [11] | -| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended: [13] | -| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [14] | -| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [15] | `publish` | Required | +| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [5] | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | Conditionally Required: [7] | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | Conditionally Required: [9] | +| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [10] | +| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [11] | `1439` | Recommended: [12] | +| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [13] | +| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | Recommended: [15] | +| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [16] | +| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [17] | `publish` | Required | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [16] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [17] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [18] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [19] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [20] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [18] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [19] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [20] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [21] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [22] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [23] | `80`; `8080`; `443` | Recommended | -**[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. -**[2]:** If the span describes an operation on a batch of messages. +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. -**[3]:** If value is `true`. When missing, the value is assumed to be `false`. +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[4]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2]:** If and only if the messaging operation has failed. + +**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + +**[4]:** If the span describes an operation on a batch of messages. + +**[5]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. -**[5]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[6]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[7]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[8]:** If value is `true`. When missing, the value is assumed to be `false`. +**[10]:** If value is `true`. When missing, the value is assumed to be `false`. -**[9]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[11]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[10]:** Only if span represents operation on a single message. +**[12]:** Only if span represents operation on a single message. -**[11]:** Only if span represents operation on a single message. +**[13]:** Only if span represents operation on a single message. -**[12]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[13]:** Only if span represents operation on a single message. +**[15]:** Only if span represents operation on a single message. -**[14]:** Only for spans that represent an operation on a single message. +**[16]:** Only for spans that represent an operation on a single message. -**[15]:** If a custom value is used, it MUST be of low cardinality. +**[17]:** If a custom value is used, it MUST be of low cardinality. -**[16]:** The value SHOULD be normalized to lowercase. +**[18]:** The value SHOULD be normalized to lowercase. -**[17]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[19]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[18]:** The value SHOULD be normalized to lowercase. +**[20]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[19]:** The value SHOULD be normalized to lowercase. +**[21]:** The value SHOULD be normalized to lowercase. + +**[22]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[23]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[20]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | `messaging.operation` 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. diff --git a/model/messaging-common.yaml b/model/messaging-common.yaml new file mode 100644 index 0000000000..07ef5f4a78 --- /dev/null +++ b/model/messaging-common.yaml @@ -0,0 +1,23 @@ +groups: + - id: messaging.attributes.common + type: attribute_group + brief: "Common messaging attributes." + prefix: messaging + attributes: + - ref: messaging.system + requirement_level: required + - ref: error.type + examples: ['amqp:decode-error', 'KAFKA_STORAGE_ERROR', 'channel-error'] + requirement_level: + conditionally_required: If and only if the messaging operation has failed. + - ref: server.address + note: > + This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + requirement_level: + conditionally_required: If available. + - ref: server.port + - ref: network.protocol.name + examples: ['amqp', 'mqtt'] + tag: connection-level + - ref: network.protocol.version + tag: connection-level diff --git a/model/metrics/messaging.yaml b/model/metrics/messaging.yaml new file mode 100644 index 0000000000..2d2f2a29ef --- /dev/null +++ b/model/metrics/messaging.yaml @@ -0,0 +1,62 @@ +groups: + - id: metric.messaging.attributes + type: attribute_group + brief: "Common messaging metrics attributes." + extends: messaging.attributes.common + attributes: + - ref: messaging.destination.name + requirement_level: + conditionally_required: if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. + - ref: messaging.destination.template + requirement_level: + conditionally_required: if available. + + # durations + - id: metric.messaging.publish.duration + type: metric + metric_name: messaging.publish.duration + brief: "Measures the duration of publish operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + - id: metric.messaging.receive.duration + type: metric + metric_name: messaging.receive.duration + brief: "Measures the duration of receive operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + - id: metric.messaging.deliver.duration + type: metric + metric_name: messaging.deliver.duration + brief: "Measures the duration of deliver operation." + instrument: histogram + unit: "s" + extends: metric.messaging.attributes + + # counters + - id: metric.messaging.publish.messages + type: metric + metric_name: messaging.publish.messages + brief: "Measures the number of published messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes + + - id: metric.messaging.receive.messages + type: metric + metric_name: messaging.receive.messages + brief: "Measures the number of received messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes + + - id: metric.messaging.deliver.messages + type: metric + metric_name: messaging.deliver.messages + brief: "Measures the number of delivered messages." + instrument: counter + unit: "{message}" + extends: metric.messaging.attributes diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 9163de0b4b..be7a4441c7 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -52,9 +52,8 @@ groups: brief: > This document defines general attributes used in messaging systems. + extends: messaging.attributes.common attributes: - - ref: messaging.system - requirement_level: required - ref: messaging.operation requirement_level: required - ref: messaging.batch.message_count @@ -90,10 +89,6 @@ groups: requirement_level: recommended: Only if span represents operation on a single message. - ref: server.address - note: > - This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. - requirement_level: - conditionally_required: If available. - ref: network.peer.address tag: connection-level - ref: network.peer.port @@ -104,9 +99,6 @@ groups: tag: connection-level - ref: network.type tag: connection-level - - ref: network.protocol.name - examples: ['amqp', 'mqtt'] - - ref: network.protocol.version - id: messaging.rabbitmq type: attribute_group From c29eeaa41912ab746ed7ce3b0d2eed7aad863ac1 Mon Sep 17 00:00:00 2001 From: Braydon Kains <93549768+braydonk@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:36:21 -0500 Subject: [PATCH 294/482] Add io direction attributes to Changelog (#570) Co-authored-by: Josh Suereth --- CHANGELOG.md | 3 +++ schema-next.yaml | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 201ae39221..3a1287a81a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ release. ([#536](https://github.com/open-telemetry/semantic-conventions/pull/536)) - BREAKING: Change `event.name` definition to include `namespace` and remove `event.domain` from log event attributes. ([#473](https://github.com/open-telemetry/semantic-conventions/pull/473)) +- BREAKING: Change `system.disk.io.direction` and `system.network.io.direction` + to global attributes `disk.io.direction` and `network.io.direction` + ([#530](https://github.com/open-telemetry/semantic-conventions/pull/530)) ### Features diff --git a/schema-next.yaml b/schema-next.yaml index ae84e381af..834bff8780 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -6,6 +6,11 @@ versions: - rename_metrics: jvm.memory.usage: jvm.memory.used jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc + # https://github.com/open-telemetry/semantic-conventions/pull/530 + - rename_attributes: + attribute_map: + system.network.io.direction: network.io.direction + system.disk.io.direction: disk.io.direction 1.23.0: metrics: changes: From ed7d3e0f939cbdcd6c0b6093d157d3f5e8bbc9bd Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 30 Nov 2023 17:40:50 +0100 Subject: [PATCH 295/482] Add changelog entry for #345 (#567) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a1287a81a..bc899cc299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ release. ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) - Add `messaging.gcp_pubsub.message.ordering_key` attribute. ([#528](https://github.com/open-telemetry/semantic-conventions/pull/528)) +- Add `db.instance.id` attribute. + ([#345](https://github.com/open-telemetry/semantic-conventions/pull/345)) - Add messaging metrics ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) From 40839cbd53939126b213f2b50921b92a107719e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Dec 2023 08:59:18 +0100 Subject: [PATCH 296/482] .NET runtime process resource attributes (#561) --- CHANGELOG.md | 3 +++ docs/resource/process.md | 36 +++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc899cc299..9f429e5cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,9 @@ release. ([#21](https://github.com/open-telemetry/semantic-conventions/pull/21)) - Add `messaging.gcp_pubsub.message.ordering_key` attribute. ([#528](https://github.com/open-telemetry/semantic-conventions/pull/528)) +- Define how to set `process.runtime.name`, `process.runtime.version`, + `process.runtime.description` for .NET runtime. + ([#561](https://github.com/open-telemetry/semantic-conventions/pull/561)) - Add `db.instance.id` attribute. ([#345](https://github.com/open-telemetry/semantic-conventions/pull/345)) - Add messaging metrics diff --git a/docs/resource/process.md b/docs/resource/process.md index b3817f34df..fb6a3a58f2 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -85,7 +85,7 @@ Example: ### Go Runtimes -Go Runtimes should fill in the as follows: +Go Runtimes SHOULD fill in the as follows: - `process.runtime.name` - Fill in an interpretation of Go's [`runtime.Compiler`](https://pkg.go.dev/runtime#Compiler) constant, according to the following rule: If the value is `gc`, fill in `go`. Otherwise, fill in the exact value of `runtime.Compiler`. @@ -116,7 +116,7 @@ Examples for some Go compilers/runtimes: ### Java runtimes -Java instrumentation should fill in the values by copying from system properties. +Java instrumentation SHOULD fill in the values by copying from system properties. - `process.runtime.name` - Fill in the value of `java.runtime.name` as is - `process.runtime.version` - Fill in the value of `java.runtime.version` as is @@ -138,7 +138,7 @@ Examples for some Java runtimes ### JavaScript runtimes -JavaScript instrumentation should fill in the values by copying from built-in runtime constants. +JavaScript instrumentation SHOULD fill in the values by copying from built-in runtime constants. - `process.runtime.name`: - When the runtime is Node.js, fill in the constant value `nodejs`. @@ -156,17 +156,31 @@ Examples for some JavaScript runtimes ### .NET Runtimes -TODO(): Confirm the contents here +.NET instrumentation SHOULD fill in the values by following values: -| Value | Description | -| --- | --- | -| `dotnet-core` | .NET Core, .NET 5+ | -| `dotnet-framework` | .NET Framework | -| `mono` | Mono | +- `process.runtime.name` - Fill in the value by the name of runtime. +- `process.runtime.version` - Fill in the value of `System.Environment.Version` for .NET, + determine version based on the [registry values](https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed#query-the-registry-using-code) + for .NET Framework +- `process.runtime.description` - Fill in the values of `System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription`. + +`process.runtime.name` has the following list of well-known values. If one of them applies, then the respective value SHOULD be used, otherwise a custom value SHOULD be used. + +- .NET Framework +- .NET +- .NET Core +- .NET Native + +Examples for some .NET runtimes + +| Name | `process.runtime.name` | `process.runtime.version` | `process.runtime.description` | +| --- | --- | --- | --- | +| .NET Framework | .NET Framework | 4.8 | .NET Framework 4.8.9195.0 | +| .NET | .NET | 7.0.14 | .NET 7.0.14 | ### Python Runtimes -Python instrumentation should fill in the values as follows: +Python instrumentation SHOULD fill in the values as follows: - `process.runtime.name` - Fill in the value of [`sys.implementation.name`][py_impl] @@ -207,7 +221,7 @@ Pypy provided a CPython-compatible version in `sys.implementation.version` inste ### Ruby Runtimes -Ruby instrumentation should fill in the values by copying from built-in runtime constants. +Ruby instrumentation SHOULD fill in the values by copying from built-in runtime constants. - `process.runtime.name` - Fill in the value of `RUBY_ENGINE` as is - `process.runtime.version` - Fill in the value of `RUBY_VERSION` as is From eff308695042468f59415d6e0a2c2ecc31c70075 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 6 Dec 2023 06:04:53 -0800 Subject: [PATCH 297/482] Cherry-pick 1.23.1 schema file (and release notes) to main (#585) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 12 ++ schemas/1.23.1 | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 306 insertions(+) create mode 100644 schemas/1.23.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f429e5cb4..a80ebaa7fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,18 @@ release. - Remove no longer relevant Oct 1 mention from `OTEL_SEMCONV_STABILITY_OPT_IN` ([#541](https://github.com/open-telemetry/semantic-conventions/pull/541)) +## v1.23.1 (2023-11-17) + +### Breaking + +### Features + +### Fixes + +- [backport to 1.23.x] Temp fix for separation of resource and semantic attributes + ([#524](https://github.com/open-telemetry/semantic-conventions/pull/524)) via + ([#537](https://github.com/open-telemetry/semantic-conventions/pull/537)) + ## v1.23.0 (2023-11-03) This release marks the first where the core of HTTP semantic conventions have diff --git a/schemas/1.23.1 b/schemas/1.23.1 new file mode 100644 index 0000000000..3662ca07b5 --- /dev/null +++ b/schemas/1.23.1 @@ -0,0 +1,294 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.23.1 +versions: + 1.23.1: + 1.23.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + thread.daemon: jvm.thread.daemon + apply_to_metrics: + - jvm.thread.count + 1.22.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size + # https://github.com/open-telemetry/opentelemetry-specification/pull/374 + - rename_attributes: + attribute_map: + http.resend_count: http.request.resend_count + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit + process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.usage + - jvm.buffer.limit + - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version + 1.21.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3336 + - rename_attributes: + attribute_map: + messaging.kafka.client_id: messaging.client_id + messaging.rocketmq.client_id: messaging.client_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3402 + - rename_attributes: + attribute_map: + # net.peer.(name|port) attributes were usually populated on client side + # so they should be usually translated to server.(address|port) + # net.host.* attributes were only populated on server side + net.host.name: server.address + net.host.port: server.port + # was only populated on client side + net.sock.peer.name: server.socket.domain + # net.sock.peer.(addr|port) mapping is not possible + # since they applied to both client and server side + # were only populated on server side + net.sock.host.addr: server.socket.address + net.sock.host.port: server.socket.port + http.client_ip: client.address + # https://github.com/open-telemetry/opentelemetry-specification/pull/3426 + - rename_attributes: + attribute_map: + net.protocol.name: network.protocol.name + net.protocol.version: network.protocol.version + net.host.connection.type: network.connection.type + net.host.connection.subtype: network.connection.subtype + net.host.carrier.name: network.carrier.name + net.host.carrier.mcc: network.carrier.mcc + net.host.carrier.mnc: network.carrier.mnc + net.host.carrier.icc: network.carrier.icc + # https://github.com/open-telemetry/opentelemetry-specification/pull/3355 + - rename_attributes: + attribute_map: + http.method: http.request.method + http.status_code: http.response.status_code + http.scheme: url.scheme + http.url: url.full + http.request_content_length: http.request.body.size + http.response_content_length: http.response.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/53 + - rename_metrics: + process.runtime.jvm.cpu.utilization: process.runtime.jvm.cpu.recent_utilization + 1.20.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3272 + - rename_attributes: + attribute_map: + net.app.protocol.name: net.protocol.name + net.app.protocol.version: net.protocol.version + 1.19.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3209 + - rename_attributes: + attribute_map: + faas.execution: faas.invocation_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3188 + - rename_attributes: + attribute_map: + faas.id: cloud.resource_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + http.user_agent: user_agent.original + resources: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + browser.user_agent: user_agent.original + 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: From fe0a3d7298c7c2c1fae352461e3e7d0a9b321d82 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 11 Dec 2023 08:06:09 -0800 Subject: [PATCH 298/482] Add .NET metrics (#283) --- .github/CODEOWNERS | 5 + CHANGELOG.md | 2 + docs/dotnet/README.md | 22 + docs/dotnet/dotnet-aspnetcore-metrics.md | 243 +++++++++++ docs/dotnet/dotnet-dns-metrics.md | 60 +++ docs/dotnet/dotnet-http-metrics.md | 232 ++++++++++ docs/dotnet/dotnet-kestrel-metrics.md | 452 ++++++++++++++++++++ docs/dotnet/dotnet-signalr-metrics.md | 88 ++++ model/metrics/dotnet/dotnet-aspnetcore.yaml | 177 ++++++++ model/metrics/dotnet/dotnet-http.yaml | 149 +++++++ model/metrics/dotnet/dotnet-kestrel.yaml | 120 ++++++ model/metrics/dotnet/dotnet-signalr.yaml | 59 +++ 12 files changed, 1609 insertions(+) create mode 100644 docs/dotnet/README.md create mode 100644 docs/dotnet/dotnet-aspnetcore-metrics.md create mode 100644 docs/dotnet/dotnet-dns-metrics.md create mode 100644 docs/dotnet/dotnet-http-metrics.md create mode 100644 docs/dotnet/dotnet-kestrel-metrics.md create mode 100644 docs/dotnet/dotnet-signalr-metrics.md create mode 100644 model/metrics/dotnet/dotnet-aspnetcore.yaml create mode 100644 model/metrics/dotnet/dotnet-http.yaml create mode 100644 model/metrics/dotnet/dotnet-kestrel.yaml create mode 100644 model/metrics/dotnet/dotnet-signalr.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 72eac076ba..3556a7bbe4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -74,3 +74,8 @@ /model/registry/container.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers /model/registry/oci.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers +# .NET semantic conventions approvers +/model/metrics/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers + +# TODO - Add semconv area experts diff --git a/CHANGELOG.md b/CHANGELOG.md index a80ebaa7fc..83e2c7c260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,8 @@ release. ([#345](https://github.com/open-telemetry/semantic-conventions/pull/345)) - Add messaging metrics ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) +- Add .NET 8.0 metrics for HTTP client, ASP.NET Core, SignalR server and Kestrel. + ([#283](https://github.com/open-telemetry/semantic-conventions/pull/283)) ### Fixes diff --git a/docs/dotnet/README.md b/docs/dotnet/README.md new file mode 100644 index 0000000000..1bc9673359 --- /dev/null +++ b/docs/dotnet/README.md @@ -0,0 +1,22 @@ + + +# Semantic Conventions for .NET metrics + +**Status**: [Stable][DocumentStatus] + +This article documents semantic conventions for metrics emitted by the .NET runtime and individual components in the .NET ecosystem. + +The following metrics are currently supported: + +* [ASP.NET Core](dotnet-aspnetcore-metrics.md): Semantic Conventions for ASP.NET Core routing, exceptions, and rate-limiting *metrics*. +* [DNS](dotnet-dns-metrics.md): Semantic Conventions for client-side DNS lookups associated with *metrics*. +* [HTTP](dotnet-http-metrics.md): Semantic Conventions for HTTP client and server *metrics*. +* [Kestrel](dotnet-kestrel-metrics.md): Semantic Conventions for Kestrel web server *metrics*. +* [SignalR](dotnet-signalr-metrics.md): Semantic Conventions for SignalR server *metrics*. + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md new file mode 100644 index 0000000000..e217a1664c --- /dev/null +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -0,0 +1,243 @@ + + +# Semantic Conventions for ASP.NET Core metrics + +**Status**: [Stable][DocumentStatus] + +This article defines semantic conventions for ASP.NET Core metrics. + + + +- [Server](#server) +- [Routing](#routing) + * [Metric: `aspnetcore.routing.match_attempts`](#metric-aspnetcoreroutingmatch_attempts) +- [Exceptions](#exceptions) + * [Metric: `aspnetcore.diagnostics.exceptions`](#metric-aspnetcorediagnosticsexceptions) +- [Rate-limiting](#rate-limiting) + * [Metric: `aspnetcore.rate_limiting.active_request_leases`](#metric-aspnetcorerate_limitingactive_request_leases) + * [Metric: `aspnetcore.rate_limiting.request_lease.duration`](#metric-aspnetcorerate_limitingrequest_leaseduration) + * [Metric: `aspnetcore.rate_limiting.queued_requests`](#metric-aspnetcorerate_limitingqueued_requests) + * [Metric: `aspnetcore.rate_limiting.request.time_in_queue`](#metric-aspnetcorerate_limitingrequesttime_in_queue) + * [Metric: `aspnetcore.rate_limiting.requests`](#metric-aspnetcorerate_limitingrequests) + + + +## Server + +## Routing + +All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. + +### Metric: `aspnetcore.routing.match_attempts` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.routing.match_attempts` | Counter | `{match_attempt}` | Number of requests that were attempted to be matched to an endpoint. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Routing`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | Conditionally Required: if and only if a route was successfully matched. | +| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | Required | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: if and only if a route was successfully matched. | + +**[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](/docs/http/http-spans.md#http-server-definitions) if there is one. + +`aspnetcore.routing.match_status` 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 | +|---|---| +| `success` | Match succeeded | +| `failure` | Match failed | + + +## Exceptions + +Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. + +### Metric: `aspnetcore.diagnostics.exceptions` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.diagnostics.exceptions` | Counter | `{exception}` | Number of exceptions caught by exception handling middleware. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Diagnostics`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | Required | +| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | Conditionally Required: [1] | +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [2] | `System.OperationCanceledException`; `Contoso.MyException` | Required | + +**[1]:** if and only if the exception was handled by this handler. + +**[2]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +`aspnetcore.diagnostics.exception.result` MUST be one of the following: + +| Value | Description | +|---|---| +| `handled` | Exception was handled by the exception handling middleware. | +| `unhandled` | Exception was not handled by the exception handling middleware. | +| `skipped` | Exception handling was skipped because the response had started. | +| `aborted` | Exception handling didn't run because the request was aborted. | + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + + +## Rate-limiting + +All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting` meter. + +### Metric: `aspnetcore.rate_limiting.active_request_leases` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.rate_limiting.active_request_leases` | UpDownCounter | `{request}` | Number of requests that are currently active on the server that hold a rate limiting lease. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | + +**[1]:** if the matched endpoint for the request had a rate-limiting policy. + + +### Metric: `aspnetcore.rate_limiting.request_lease.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.rate_limiting.request_lease.duration` | Histogram | `s` | The duration of rate limiting lease held by requests on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | + +**[1]:** if the matched endpoint for the request had a rate-limiting policy. + + +### Metric: `aspnetcore.rate_limiting.queued_requests` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.rate_limiting.queued_requests` | UpDownCounter | `{request}` | Number of requests that are currently queued, waiting to acquire a rate limiting lease. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | + +**[1]:** if the matched endpoint for the request had a rate-limiting policy. + + +### Metric: `aspnetcore.rate_limiting.request.time_in_queue` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.rate_limiting.request.time_in_queue` | Histogram | `s` | The time the request spent in a queue waiting to acquire a rate limiting lease. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | + +**[1]:** if the matched endpoint for the request had a rate-limiting policy. + +`aspnetcore.rate_limiting.result` 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 | +|---|---| +| `acquired` | Lease was acquired | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | +| `global_limiter` | Lease request was rejected by the global limiter | +| `request_canceled` | Lease request was canceled | + + +### Metric: `aspnetcore.rate_limiting.requests` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `aspnetcore.rate_limiting.requests` | Counter | `{request}` | Number of requests that tried to acquire a rate limiting lease. [1] | + +**[1]:** Requests could be: + +* Rejected by global or endpoint rate limiting policies +* Canceled while waiting for the lease. + +Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | + +**[1]:** if the matched endpoint for the request had a rate-limiting policy. + +`aspnetcore.rate_limiting.result` 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 | +|---|---| +| `acquired` | Lease was acquired | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | +| `global_limiter` | Lease request was rejected by the global limiter | +| `request_canceled` | Lease request was canceled | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-dns-metrics.md b/docs/dotnet/dotnet-dns-metrics.md new file mode 100644 index 0000000000..c0bb6b7aa3 --- /dev/null +++ b/docs/dotnet/dotnet-dns-metrics.md @@ -0,0 +1,60 @@ + + +# Semantic Conventions for DNS metrics emitted by .NET + +**Status**: [Stable][DocumentStatus] + +This article defines semantic conventions for DNS metrics emitted by .NET. + + + +- [DNS metrics](#dns-metrics) + * [Metric: `dns.lookup.duration`](#metric-dnslookupduration) + + + +## DNS metrics + +### Metric: `dns.lookup.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. [1] | + +**[1]:** Meter name: `System.Net.NameResolution`; Added in: .NET 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `dot.net` | Required | +| [`error.type`](../attributes-registry/error.md) | string | One of the resolution errors or the full name of exception type. [2] | `host_not_found`; `no_recovery`; `System.Net.Sockets.SocketException` | Conditionally Required: if and only if an error has occurred. | + +**[1]:** The name being queried. +If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. + +**[2]:** The following errors codes are reported: + +- "host_not_found" +- "try_again" +- "address_family_not_supported" +- "no_recovery" + +See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) +for more details. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-http-metrics.md b/docs/dotnet/dotnet-http-metrics.md new file mode 100644 index 0000000000..ee7cb4d399 --- /dev/null +++ b/docs/dotnet/dotnet-http-metrics.md @@ -0,0 +1,232 @@ + + +# Semantic Conventions for HTTP client and server metrics emitted by .NET + +**Status**: [Stable][DocumentStatus] + +This article defines semantic conventions for HTTP metrics emitted by .NET components and runtime. + + + +- [HTTP client](#http-client) + * [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) + * [Metric: `http.client.open_connections`](#metric-httpclientopen_connections) + * [Metric: `http.client.connection.duration`](#metric-httpclientconnectionduration) + * [Metric: `http.client.request.time_in_queue`](#metric-httpclientrequesttime_in_queue) + * [Metric: `http.client.active_requests`](#metric-httpclientactive_requests) +- [HTTP server](#http-server) + * [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) + * [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) + + + +## HTTP client + +All Http client metrics are reported by the `System.Net.Http` meter. + +### Metric: `http.client.request.duration` + +Client request duration measures the time it takes to receive response headers and doesn't include time to read the response body. + +This metric follows the common [http.client.request.duration](../http/http-metrics.md#metric-httpclientrequestduration) definition. + +Notes: + +- Meter name is `System.Net.Http` +- Metric added in .NET 8.0 +- When the `error.type` attribute is reported, it contains one of [HTTP Request errors](https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror) in snake_case, a full exception type, or a string representation of received status code. +- `network.protocol.name` is not reported and should always be assumed to match `http`. +- `server.port` is not reported when it matches a default one for provided scheme (`443` for `https` and `80` for `http`) +- `url.scheme` is always reported. + +### Metric: `http.client.open_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client. [1] | + +**[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | +| [`network.peer.address`](../attributes-registry/network.md) | string | Remote IP address of the socket connection. | `10.1.2.80` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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] | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | + +**[1]:** HTTP 1.0 and 1.1 requests share connections in the connection pool and are both reported as version `1.1`. So, the `network.protocol.version` value reported on connection metrics is different than the one reported on request-level metrics or spans for HTTP 1.0 requests. + +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[4]:** If not the default (`80` for `http` scheme, `443` for `https`). + +`http.connection.state` MUST be one of the following: + +| Value | Description | +|---|---| +| `active` | active state. | +| `idle` | idle state. | + + +### Metric: `http.client.connection.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.connection.duration` | Histogram | `s` | The duration of the successfully established outbound HTTP connections. [1] | + +**[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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] | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | + +**[1]:** HTTP 1.0 and 1.1 requests share connections in the connection pool and are both reported as version `1.1`. So, the `network.protocol.version` value reported on connection metrics is different than the one reported on request-level metrics or spans for HTTP 1.0 requests. + +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[4]:** If not the default (`80` for `http` scheme, `443` for `https`). + + +### Metric: `http.client.request.time_in_queue` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.request.time_in_queue` | Histogram | `s` | The amount of time requests spent on a queue waiting for an available connection. [1] | + +**[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [2] | `1.1`; `2`; `3` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | + +**[1]:** HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). +If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. It's not possible at the moment to override the list of known HTTP methods. + +**[2]:** HTTP 1.0 and 1.1 requests share connections in the connection pool and are both reported as version `1.1`. So, the `network.protocol.version` value reported on connection metrics is different than the one reported on request-level metrics or spans for HTTP 1.0 requests. + +**[3]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[5]:** If not the default (`80` for `http` scheme, `443` for `https`). + +`http.request.method` 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 | +|---|---| +| `CONNECT` | CONNECT method. | +| `DELETE` | DELETE method. | +| `GET` | GET method. | +| `HEAD` | HEAD method. | +| `OPTIONS` | OPTIONS method. | +| `PATCH` | PATCH method. | +| `POST` | POST method. | +| `PUT` | PUT method. | +| `TRACE` | TRACE method. | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | + + +### Metric: `http.client.active_requests` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. [1] | + +**[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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] | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | + +**[1]:** HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). +If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. It's not possible at the moment to override the list of known HTTP methods. + +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[4]:** If not the default (`80` for `http` scheme, `443` for `https`). + +`http.request.method` 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 | +|---|---| +| `CONNECT` | CONNECT method. | +| `DELETE` | DELETE method. | +| `GET` | GET method. | +| `HEAD` | HEAD method. | +| `OPTIONS` | OPTIONS method. | +| `PATCH` | PATCH method. | +| `POST` | POST method. | +| `PUT` | PUT method. | +| `TRACE` | TRACE method. | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | + + +## HTTP server + +All HTTP server metrics are reported by the `Microsoft.AspNetCore.Hosting` meter. + +### Metric: `http.server.request.duration` + +Measures time to last byte. This metric follows the common [http.server.request.duration](../http/http-metrics.md#metric-httpserverrequestduration) definition. + +Notes: + +- Meter name is `Microsoft.AspNetCore.Hosting` +- Metric added in ASP.NET Core 8.0 +- Opt-in `server.address` and `server.port` attributes are not reported +- Additional attributes: + + - The `aspnetcore.request.is_unhandled` boolean attribute is reported when the request was **not** handled by the application pipeline. It's skipped otherwise. + +### Metric: `http.server.active_requests` + +Measures the number of HTTP requests that are currently active on the server. This metric follows the common [http.server.active_requests](../http/http-metrics.md#metric-httpserveractive_requests) definition. + +Notes: + +- Meter name is `Microsoft.AspNetCore.Hosting` +- Opt-in `server.address` and `server.port` attributes are not reported +- Metric added in ASP.NET Core 8.0 + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md new file mode 100644 index 0000000000..96f400ab19 --- /dev/null +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -0,0 +1,452 @@ + + +# Semantic Conventions for Kestrel web server metrics + +**Status**: [Stable][DocumentStatus] + +This article defines semantic conventions for Kestrel web server. + + + +- [Kestrel endpoint](#kestrel-endpoint) +- [Metric: `kestrel.active_connections`](#metric-kestrelactive_connections) +- [Metric: `kestrel.connection.duration`](#metric-kestrelconnectionduration) +- [Metric: `kestrel.rejected_connections`](#metric-kestrelrejected_connections) +- [Metric: `kestrel.queued_connections`](#metric-kestrelqueued_connections) +- [Metric: `kestrel.queued_requests`](#metric-kestrelqueued_requests) +- [Metric: `kestrel.upgraded_connections`](#metric-kestrelupgraded_connections) +- [Metric: `kestrel.tls_handshake.duration`](#metric-kestreltls_handshakeduration) +- [Metric: `kestrel.active_tls_handshakes`](#metric-kestrelactive_tls_handshakes) + + + +## Kestrel endpoint + +Kestrel endpoint is represented with [`System.Net.EndPoint`](https://learn.microsoft.com/dotnet/api/system.net.endpoint) class, which does not always provide information about server address or port. + +Instrumentation supports `IPEndPoint`, `UnixDomainSocketEndPoint`, and `NamedPipeEndPoint` and sets the `server.address`, `server.port` (for IP endpoint), `network.type`, and `network.transport` attributes from the corresponding endpoint on Kestrel metrics. + +In case instrumentation does not recognize `EndPoint` implementation, it sets the `server.address` attribute to `endpoint.ToString()` value and `network.transport` value to corresponding `endpoint.AddressFamily` property. + +## Metric: `kestrel.active_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.connection.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [3] | `1.1`; `2` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Recommended | +| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | Recommended | + +**[1]:** Captures the exception type when a connection fails. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[4]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[5]:** The value SHOULD be normalized to lowercase. + +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.rejected_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.rejected_connections` | Counter | `{connection}` | Number of connections rejected by the server. [1] | + +**[1]:** Connections are rejected when the currently active count exceeds the value configured with `MaxConcurrentConnections`. +Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.queued_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.queued_connections` | UpDownCounter | `{connection}` | Number of connections that are currently queued and are waiting to start. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.queued_requests` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.queued_requests` | UpDownCounter | `{request}` | Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [2] | `1.1`; `2` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[3]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[4]:** The value SHOULD be normalized to lowercase. + +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.upgraded_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.upgraded_connections` | UpDownCounter | `{connection}` | Number of connections that are currently upgraded (WebSockets). . [1] | + +**[1]:** The counter only tracks HTTP/1.1 connections. + +Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.tls_handshake.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.tls_handshake.duration` | Histogram | `s` | The duration of TLS handshakes on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | Recommended | +| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | Recommended | + +**[1]:** Captures the exception type when a TLS handshake fails. + +**[2]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[3]:** The value SHOULD be normalized to lowercase. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +## Metric: `kestrel.active_tls_handshakes` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `kestrel.active_tls_handshakes` | UpDownCounter | `{handshake}` | Number of TLS handshakes that are currently in progress on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | + +**[1]:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[2]:** The value SHOULD be normalized to lowercase. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`network.transport` 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 | +|---|---| +| `tcp` | TCP | +| `udp` | UDP | +| `pipe` | Named or anonymous pipe. | +| `unix` | Unix domain socket | + +`network.type` 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 | +|---|---| +| `ipv4` | IPv4 | +| `ipv6` | IPv6 | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md new file mode 100644 index 0000000000..dc2b04ed06 --- /dev/null +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -0,0 +1,88 @@ + + +# Semantic Conventions for SignalR server metrics + +**Status**: [Stable][DocumentStatus] + +This article defines semantic conventions for SignalR metrics emitted by .NET components and runtime. + + + +- [Metric: `signalr.server.connection.duration`](#metric-signalrserverconnectionduration) +- [Metric: `signalr.server.active_connections`](#metric-signalrserveractive_connections) + + + +## Metric: `signalr.server.connection.duration` + +this metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `signalr.server.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | + +`signalr.connection.status` MUST be one of the following: + +| Value | Description | +|---|---| +| `normal_closure` | The connection was closed normally. | +| `timeout` | The connection was closed due to a timeout. | +| `app_shutdown` | The connection was closed because the app is shutting down. | + +`signalr.transport` 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 | +|---|---| +| `server_sent_events` | ServerSentEvents protocol | +| `long_polling` | LongPolling protocol | +| `web_sockets` | WebSockets protocol | + + +## Metric: `signalr.server.active_connections` + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `signalr.server.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | + +**[1]:** Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | + +`signalr.connection.status` MUST be one of the following: + +| Value | Description | +|---|---| +| `normal_closure` | The connection was closed normally. | +| `timeout` | The connection was closed due to a timeout. | +| `app_shutdown` | The connection was closed because the app is shutting down. | + +`signalr.transport` 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 | +|---|---| +| `server_sent_events` | ServerSentEvents protocol | +| `long_polling` | LongPolling protocol | +| `web_sockets` | WebSockets protocol | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/metrics/dotnet/dotnet-aspnetcore.yaml b/model/metrics/dotnet/dotnet-aspnetcore.yaml new file mode 100644 index 0000000000..8369e068d5 --- /dev/null +++ b/model/metrics/dotnet/dotnet-aspnetcore.yaml @@ -0,0 +1,177 @@ +groups: + - id: aspnetcore + prefix: aspnetcore + type: attribute_group + brief: ASP.NET Core attributes + attributes: + - id: rate_limiting.policy + type: string + brief: Rate limiting policy name. + examples: ["fixed", "sliding", "token"] + requirement_level: + conditionally_required: if the matched endpoint for the request had a rate-limiting policy. + - id: rate_limiting.result + type: + allow_custom_values: true + members: + - id: acquired + value: 'acquired' + brief: "Lease was acquired" + - id: endpoint_limiter + value: 'endpoint_limiter' + brief: "Lease request was rejected by the endpoint limiter" + - id: global_limiter + value: 'global_limiter' + brief: "Lease request was rejected by the global limiter" + - id: request_canceled + value: 'request_canceled' + brief: "Lease request was canceled" + brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason + examples: ["acquired", "request_canceled"] + requirement_level: required + - id: routing.is_fallback + type: boolean + brief: A value that indicates whether the matched route is a fallback route. + examples: [true] + requirement_level: + conditionally_required: If and only if a route was successfully matched. + - id: diagnostics.handler.type + type: string + brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) + implementation that handled the exception. + examples: ["Contoso.MyHandler"] + requirement_level: + conditionally_required: if and only if the exception was handled by this handler. + - id: request.is_unhandled + type: boolean + brief: Flag indicating if request was handled by the application pipeline. + examples: [true] + requirement_level: + conditionally_required: if and only if the request was not handled. + + # routing + - id: metric.aspnetcore.routing.match_attempts + type: metric + metric_name: aspnetcore.routing.match_attempts + brief: Number of requests that were attempted to be matched to an endpoint. + instrument: counter + unit: "{match_attempt}" + note: | + Meter name: `Microsoft.AspNetCore.Routing`; Added in: ASP.NET Core 8.0 + attributes: + - ref: http.route + requirement_level: + conditionally_required: if and only if a route was successfully matched. + - ref: aspnetcore.routing.is_fallback + requirement_level: + conditionally_required: if and only if a route was successfully matched. + - id: aspnetcore.routing.match_status + type: + allow_custom_values: true + members: + - id: success + value: 'success' + brief: 'Match succeeded' + - id: failure + value: 'failure' + brief: 'Match failed' + requirement_level: required + brief: Match result - success or failure + examples: ["success", "failure"] + + # diagnostics + - id: metric.aspnetcore.diagnostics.exceptions + type: metric + metric_name: aspnetcore.diagnostics.exceptions + brief: Number of exceptions caught by exception handling middleware. + instrument: counter + unit: "{exception}" + note: | + Meter name: `Microsoft.AspNetCore.Diagnostics`; Added in: ASP.NET Core 8.0 + attributes: + - ref: error.type + brief: The full name of exception type. + examples: ['System.OperationCanceledException', 'Contoso.MyException'] + requirement_level: required + - ref: aspnetcore.diagnostics.handler.type + - id: aspnetcore.diagnostics.exception.result + type: + members: + - id: handled + value: 'handled' + brief: "Exception was handled by the exception handling middleware." + - id: unhandled + value: 'unhandled' + brief: "Exception was not handled by the exception handling middleware." + - id: skipped + value: 'skipped' + brief: "Exception handling was skipped because the response had started." + - id: aborted + value: 'aborted' + brief: "Exception handling didn't run because the request was aborted." + requirement_level: required + brief: ASP.NET Core exception middleware handling result + examples: ["handled", "unhandled"] + + # rate_limiting + - id: metric.aspnetcore.rate_limiting.active_request_leases + type: metric + metric_name: aspnetcore.rate_limiting.active_request_leases + brief: Number of requests that are currently active on the server that hold a rate limiting lease. + instrument: updowncounter + unit: "{request}" + note: | + Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + attributes: + - ref: aspnetcore.rate_limiting.policy + + - id: metric.aspnetcore.rate_limiting.request_lease.duration + type: metric + metric_name: aspnetcore.rate_limiting.request_lease.duration + brief: The duration of rate limiting lease held by requests on the server. + instrument: histogram + unit: "s" + note: | + Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + attributes: + - ref: aspnetcore.rate_limiting.policy + + - id: metric.aspnetcore.rate_limiting.request.time_in_queue + type: metric + metric_name: aspnetcore.rate_limiting.request.time_in_queue + brief: The time the request spent in a queue waiting to acquire a rate limiting lease. + instrument: histogram + unit: "s" + note: | + Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + attributes: + - ref: aspnetcore.rate_limiting.policy + - ref: aspnetcore.rate_limiting.result + + - id: metric.aspnetcore.rate_limiting.queued_requests + type: metric + metric_name: aspnetcore.rate_limiting.queued_requests + brief: Number of requests that are currently queued, waiting to acquire a rate limiting lease. + instrument: updowncounter + unit: "{request}" + note: | + Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + attributes: + - ref: aspnetcore.rate_limiting.policy + + - id: metric.aspnetcore.rate_limiting.requests + type: metric + metric_name: aspnetcore.rate_limiting.requests + brief: Number of requests that tried to acquire a rate limiting lease. + instrument: counter + unit: "{request}" + note: | + Requests could be: + + * Rejected by global or endpoint rate limiting policies + * Canceled while waiting for the lease. + + Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + attributes: + - ref: aspnetcore.rate_limiting.policy + - ref: aspnetcore.rate_limiting.result diff --git a/model/metrics/dotnet/dotnet-http.yaml b/model/metrics/dotnet/dotnet-http.yaml new file mode 100644 index 0000000000..9a326bb5d7 --- /dev/null +++ b/model/metrics/dotnet/dotnet-http.yaml @@ -0,0 +1,149 @@ +groups: + - id: metric.dotnet.dns.lookup.duration + type: metric + metric_name: dns.lookup.duration + brief: Measures the time taken to perform a DNS lookup. + instrument: histogram + unit: "s" + note: | + Meter name: `System.Net.NameResolution`; Added in: .NET 8.0 + attributes: + - id: dns.question.name + type: string + brief: The name being queried. + requirement_level: required + examples: ["www.example.com", "dot.net"] + note: > + The name being queried. + + If the name field contains non-printable + characters (below 32 or above 126), those characters should be represented + as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. + Tabs, carriage returns, and line feeds should be converted to \t, \r, and + \n respectively. + - ref: error.type + brief: One of the resolution errors or the full name of exception type. + requirement_level: + conditionally_required: if and only if an error has occurred. + note: | + The following errors codes are reported: + + - "host_not_found" + - "try_again" + - "address_family_not_supported" + - "no_recovery" + + See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) + for more details. + examples: ["host_not_found", "no_recovery", "System.Net.Sockets.SocketException"] + + - id: dotnet.http.client.common.attributes + type: attribute_group + brief: "Common HTTP client attributes" + attributes: + - ref: url.scheme + examples: ['http', 'https', 'ftp'] + - ref: server.address + 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: > + If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then + `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + - ref: server.port + requirement_level: + conditionally_required: If not the 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. + + - id: dotnet.http.client.connection.attributes + type: attribute_group + brief: "Common HTTP client attributes" + extends: dotnet.http.client.common.attributes + attributes: + - ref: network.protocol.version + brief: HTTP protocol version of the connection in the connection pool. + note: > + HTTP 1.0 and 1.1 requests share connections in the connection pool and are both reported as version `1.1`. + So, the `network.protocol.version` value reported on connection metrics is different than the one reported + on request-level metrics or spans for HTTP 1.0 requests. + examples: ["1.1", "2", "3"] + + - id: dotnet.http.client.request.attributes + type: attribute_group + brief: "Common HTTP client attributes" + extends: dotnet.http.client.common.attributes + attributes: + - ref: http.request.method + note: > + HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + + If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. + It's not possible at the moment to override the list of known HTTP methods. + + - id: metric.dotnet.http.client.open_connections + type: metric + metric_name: http.client.open_connections + brief: "Number of outbound HTTP connections that are currently active or idle on the client." + instrument: updowncounter + unit: "{connection}" + note: > + Meter name: `System.Net.Http`; Added in: .NET 8.0 + extends: dotnet.http.client.connection.attributes + attributes: + - id: http.connection.state + type: + members: + - id: active + value: "active" + brief: 'active state.' + - id: idle + value: "idle" + brief: 'idle state.' + brief: State of the HTTP connection in the HTTP connection pool. + requirement_level: required + examples: ["active", "idle"] + - ref: network.peer.address + brief: Remote IP address of the socket connection. + examples: ["10.1.2.80"] + + - id: metric.dotnet.http.client.connection.duration + type: metric + metric_name: http.client.connection.duration + brief: "The duration of the successfully established outbound HTTP connections." + instrument: histogram + unit: "s" + note: > + Meter name: `System.Net.Http`; Added in: .NET 8.0 + extends: dotnet.http.client.connection.attributes + attributes: + - ref: network.peer.address + + - id: metric.dotnet.http.client.active_requests + type: metric + metric_name: http.client.active_requests + brief: "Number of active HTTP requests." + instrument: updowncounter + unit: "{request}" + note: > + Meter name: `System.Net.Http`; Added in: .NET 8.0 + extends: dotnet.http.client.request.attributes + + - id: metric.dotnet.http.client.request.time_in_queue + type: metric + metric_name: http.client.request.time_in_queue + brief: "The amount of time requests spent on a queue waiting for an available connection." + instrument: histogram + unit: "s" + note: > + Meter name: `System.Net.Http`; Added in: .NET 8.0 + extends: dotnet.http.client.connection.attributes + attributes: + - ref: http.request.method + note: > + HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + + If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. + It's not possible at the moment to override the list of known HTTP methods. diff --git a/model/metrics/dotnet/dotnet-kestrel.yaml b/model/metrics/dotnet/dotnet-kestrel.yaml new file mode 100644 index 0000000000..e04714a9b5 --- /dev/null +++ b/model/metrics/dotnet/dotnet-kestrel.yaml @@ -0,0 +1,120 @@ +groups: + - id: common.kestrel.attributes + type: attribute_group + brief: 'Common kestrel attributes' + attributes: + - ref: server.address + - ref: server.port + - ref: network.type + requirement_level: + recommended: if the transport is `tcp` or `udp` + - ref: network.transport + examples: ['tcp', 'unix'] + + - id: metric.kestrel.active_connections + type: metric + metric_name: kestrel.active_connections + brief: Number of connections that are currently active on the server. + instrument: updowncounter + unit: "{connection}" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + + - id: metric.kestrel.connection.duration + type: metric + metric_name: kestrel.connection.duration + brief: The duration of connections on the server. + instrument: histogram + unit: "s" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + attributes: + - ref: network.protocol.name + examples: ['http', 'web_sockets'] + - ref: network.protocol.version + examples: ["1.1", "2"] + - ref: tls.protocol.version + - ref: error.type + brief: The full name of exception type. + requirement_level: + conditionally_required: if and only if an error has occurred. + note: "Captures the exception type when a connection fails." + examples: ['System.OperationCanceledException', 'Contoso.MyException'] + + - id: metric.kestrel.rejected_connections + type: metric + metric_name: kestrel.rejected_connections + brief: Number of connections rejected by the server. + instrument: counter + unit: "{connection}" + note: | + Connections are rejected when the currently active count exceeds the value configured with `MaxConcurrentConnections`. + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + + - id: metric.kestrel.queued_connections + type: metric + metric_name: kestrel.queued_connections + brief: Number of connections that are currently queued and are waiting to start. + instrument: updowncounter + unit: "{connection}" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + + - id: metric.kestrel.queued_requests + type: metric + metric_name: kestrel.queued_requests + brief: Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start. + instrument: updowncounter + unit: "{request}" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + attributes: + - ref: network.protocol.name + examples: ['http', 'web_sockets'] + - ref: network.protocol.version + examples: ["1.1", "2"] + + - id: metric.kestrel.upgraded_connections + type: metric + metric_name: kestrel.upgraded_connections + brief: Number of connections that are currently upgraded (WebSockets). . + instrument: updowncounter + unit: "{connection}" + note: | + The counter only tracks HTTP/1.1 connections. + + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + + - id: metric.kestrel.tls_handshake.duration + type: metric + metric_name: kestrel.tls_handshake.duration + brief: The duration of TLS handshakes on the server. + instrument: histogram + unit: "s" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes + attributes: + - ref: tls.protocol.version + - ref: error.type + brief: The full name of exception type. + note: "Captures the exception type when a TLS handshake fails." + requirement_level: + conditionally_required: if and only if an error has occurred. + examples: ['System.OperationCanceledException', 'Contoso.MyException'] + + - id: metric.kestrel.active_tls_handshakes + type: metric + metric_name: kestrel.active_tls_handshakes + brief: Number of TLS handshakes that are currently in progress on the server. + instrument: updowncounter + unit: "{handshake}" + note: | + Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 + extends: common.kestrel.attributes diff --git a/model/metrics/dotnet/dotnet-signalr.yaml b/model/metrics/dotnet/dotnet-signalr.yaml new file mode 100644 index 0000000000..3333669c57 --- /dev/null +++ b/model/metrics/dotnet/dotnet-signalr.yaml @@ -0,0 +1,59 @@ +groups: + - id: signalr.common_attributes + prefix: signalr + type: attribute_group + brief: SignalR attributes + attributes: + - id: connection.status + type: + members: + - id: normal_closure + value: 'normal_closure' + brief: "The connection was closed normally." + - id: timeout + value: 'timeout' + brief: "The connection was closed due to a timeout." + - id: app_shutdown + value: 'app_shutdown' + brief: "The connection was closed because the app is shutting down." + brief: SignalR HTTP connection closure status. + examples: ["app_shutdown", "timeout"] + - id: transport + brief: "[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md)" + type: + allow_custom_values: true + members: + - id: server_sent_events + value: 'server_sent_events' + brief: "ServerSentEvents protocol" + - id: long_polling + value: 'long_polling' + brief: "LongPolling protocol" + - id: web_sockets + value: 'web_sockets' + brief: "WebSockets protocol" + examples: ["web_sockets", "long_polling"] + + - id: metric.signalr.server.connection.duration + type: metric + metric_name: signalr.server.connection.duration + brief: The duration of connections on the server. + instrument: histogram + unit: "s" + note: | + Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 + attributes: + - ref: signalr.connection.status + - ref: signalr.transport + + - id: metric.signalr.server.active_connections + type: metric + metric_name: signalr.server.active_connections + brief: Number of connections that are currently active on the server. + instrument: updowncounter + unit: "{connection}" + note: | + Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 + attributes: + - ref: signalr.connection.status + - ref: signalr.transport From 0f512d143d10e7956d736600988c51b9ee2a6730 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 12 Dec 2023 03:51:13 -0800 Subject: [PATCH 299/482] Editorial: update HTTP request duration metrics stability in yaml (to stable) (#587) --- CHANGELOG.md | 3 +++ model/metrics/http.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e2c7c260..17134a9a2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,9 @@ release. ([#488](https://github.com/open-telemetry/semantic-conventions/pull/488)) - Remove no longer relevant Oct 1 mention from `OTEL_SEMCONV_STABILITY_OPT_IN` ([#541](https://github.com/open-telemetry/semantic-conventions/pull/541)) +- Update stability definitions of HTTP client and server duration metrics to + be consistent with markdown. + ([#587](https://github.com/open-telemetry/semantic-conventions/pull/587)) ## v1.23.1 (2023-11-17) diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index 9e12896e88..a309994f2d 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -29,6 +29,7 @@ groups: brief: "Duration of HTTP server requests." instrument: histogram unit: "s" + stability: stable extends: metric_attributes.http.server - id: metric.http.server.active_requests @@ -92,6 +93,7 @@ groups: brief: "Duration of HTTP client requests." instrument: histogram unit: "s" + stability: stable extends: metric_attributes.http.client - id: metric.http.client.request.body.size From 9f267b1c625ae922bcfb46abbcc7d7758395dd2f Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 12 Dec 2023 11:19:00 -0800 Subject: [PATCH 300/482] Mark JVM metrics stable (#569) --- CHANGELOG.md | 2 ++ docs/runtime/jvm-metrics.md | 44 ++++++++++++++++++++-------------- model/metrics/jvm-metrics.yaml | 6 +++++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17134a9a2a..724ae34495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ release. ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) - Add .NET 8.0 metrics for HTTP client, ASP.NET Core, SignalR server and Kestrel. ([#283](https://github.com/open-telemetry/semantic-conventions/pull/283)) +- JVM metrics marked stable + ([#569](https://github.com/open-telemetry/semantic-conventions/pull/569)) ### Fixes diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 41e2d38ac4..eb72b18211 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -4,7 +4,7 @@ linkTitle: Runtime Environment # Semantic Conventions for JVM Metrics -**Status**: [Experimental][DocumentStatus] +**Status**: [Mixed][DocumentStatus] This document describes semantic conventions for JVM metrics in OpenTelemetry. @@ -29,7 +29,7 @@ This document describes semantic conventions for JVM metrics in OpenTelemetry. * [Metric: `jvm.cpu.time`](#metric-jvmcputime) * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) -- [Very experimental](#very-experimental) +- [Experimental](#experimental) * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) @@ -41,6 +41,8 @@ This document describes semantic conventions for JVM metrics in OpenTelemetry. ## JVM Memory +**Status**: [Stable][DocumentStatus] + **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.memory.*` ### Metric: `jvm.memory.used` @@ -57,8 +59,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -84,8 +86,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -111,8 +113,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -138,8 +140,8 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -153,6 +155,8 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d ## JVM Garbage Collection +**Status**: [Stable][DocumentStatus] + **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.gc.*` ### Metric: `jvm.gc.duration` @@ -174,8 +178,8 @@ of `[ 0.01, 0.1, 1, 10 ]`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | Recommended | -| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | Recommended | +| `jvm.gc.action` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | Recommended | +| `jvm.gc.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | Recommended | **[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). @@ -207,8 +211,8 @@ Note that this is the number of platform threads (as opposed to virtual threads) | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | Recommended | -| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | Recommended | +| `jvm.thread.daemon` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Whether the thread is daemon or not. | | Recommended | +| `jvm.thread.state` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
State of the thread. | `runnable`; `blocked` | Recommended | `jvm.thread.state` MUST be one of the following: @@ -270,6 +274,8 @@ This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https: ## JVM CPU +**Status**: [Stable][DocumentStatus] + **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.cpu.*` ### Metric: `jvm.cpu.time` @@ -321,9 +327,11 @@ Note that the JVM does not provide a definition of what "recent" means. -## Very experimental +## Experimental + +**Status**: [Experimental][DocumentStatus] -**Description:** Very experimental Java Virtual Machine (JVM) metrics captured under `jvm.` +**Description:** Experimental Java Virtual Machine (JVM) metrics captured under `jvm.` ### Metric: `jvm.memory.init` @@ -339,8 +347,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | Recommended | +| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | +| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index ba1f560453..4db5ecd934 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -5,6 +5,7 @@ groups: prefix: jvm.memory attributes: - id: type + stability: stable type: allow_custom_values: false members: @@ -18,6 +19,7 @@ groups: brief: The type of memory. examples: ["heap", "non_heap"] - id: pool.name + stability: stable type: string requirement_level: recommended brief: Name of the memory pool. @@ -67,6 +69,7 @@ groups: prefix: jvm.gc attributes: - id: name + stability: stable type: string requirement_level: recommended brief: Name of the garbage collector. @@ -75,6 +78,7 @@ groups: Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). - id: action + stability: stable type: string requirement_level: recommended brief: Name of the garbage collector action. @@ -91,10 +95,12 @@ groups: unit: "{thread}" attributes: - id: jvm.thread.daemon + stability: stable type: boolean requirement_level: recommended brief: "Whether the thread is daemon or not." - id: jvm.thread.state + stability: stable requirement_level: recommended type: allow_custom_values: false From 2966241ecd00861057cef042456668d3acea4526 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Tue, 12 Dec 2023 11:29:55 -0800 Subject: [PATCH 301/482] Fix PPID abbreviation in process attributes description (#594) --- docs/attributes-registry/process.md | 2 +- docs/resource/process.md | 2 +- model/registry/process.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index edef9364bd..3405cb03c1 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -14,7 +14,7 @@ | `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | | `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | | `process.owner` | string | The username of the user that owns the process. | `root` | -| `process.parent_pid` | int | Parent Process identifier (PID). | `111` | +| `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | | `process.pid` | int | Process identifier (PID). | `1234` | | `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | | `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | diff --git a/docs/resource/process.md b/docs/resource/process.md index fb6a3a58f2..8156fbcd2a 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -33,7 +33,7 @@ | [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | | [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | | [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | Recommended | -| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PID). | `111` | Recommended | +| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | Recommended | | [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | Recommended | **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/model/registry/process.yaml b/model/registry/process.yaml index dd26c09b77..169b426538 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -13,7 +13,7 @@ groups: - id: parent_pid type: int brief: > - Parent Process identifier (PID). + Parent Process identifier (PPID). examples: [111] - id: executable.name type: string From 34184ace6c6a32cd56d2b1410b4454e699513ac2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 12 Dec 2023 16:28:55 -0800 Subject: [PATCH 302/482] Mark JVM metrics stable in yaml too (#603) --- model/metrics/jvm-metrics.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index 4db5ecd934..b28b175130 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -35,6 +35,7 @@ groups: brief: "Measure of memory used." instrument: updowncounter unit: "By" + stability: stable - id: metric.jvm.memory.committed type: metric @@ -43,6 +44,7 @@ groups: brief: "Measure of memory committed." instrument: updowncounter unit: "By" + stability: stable - id: metric.jvm.memory.limit type: metric @@ -51,6 +53,7 @@ groups: brief: "Measure of max obtainable memory." instrument: updowncounter unit: "By" + stability: stable - id: metric.jvm.memory.used_after_last_gc type: metric @@ -59,6 +62,7 @@ groups: brief: "Measure of memory used, as measured after the most recent garbage collection event on this pool." instrument: updowncounter unit: "By" + stability: stable - id: metric.jvm.gc.duration type: metric @@ -86,6 +90,7 @@ groups: note: > Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + stability: stable - id: metric.jvm.thread.count type: metric @@ -125,6 +130,7 @@ groups: brief: 'A thread that has exited is in this state.' brief: "State of the thread." examples: ["runnable", "blocked"] + stability: stable - id: metric.jvm.class.loaded type: metric @@ -132,6 +138,7 @@ groups: brief: "Number of classes loaded since JVM start." instrument: counter unit: "{class}" + stability: stable - id: metric.jvm.class.unloaded type: metric @@ -139,6 +146,7 @@ groups: brief: "Number of classes unloaded since JVM start." instrument: counter unit: "{class}" + stability: stable - id: metric.jvm.class.count type: metric @@ -146,6 +154,7 @@ groups: brief: "Number of classes currently loaded." instrument: updowncounter unit: "{class}" + stability: stable - id: metric.jvm.cpu.count type: metric @@ -153,6 +162,7 @@ groups: brief: "Number of processors available to the Java virtual machine." instrument: updowncounter unit: "{cpu}" + stability: stable - id: metric.jvm.cpu.time type: metric @@ -160,6 +170,7 @@ groups: brief: "CPU time used by the process as reported by the JVM." instrument: counter unit: "s" + stability: stable - id: metric.jvm.cpu.recent_utilization type: metric @@ -172,3 +183,4 @@ groups: [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). instrument: gauge unit: "1" + stability: stable From 2ec29a5f6f27b4032703e8492fb0a90499ae5e84 Mon Sep 17 00:00:00 2001 From: Dan Nelson <55757989+danelson@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:33:03 -0600 Subject: [PATCH 303/482] Clarify example for url.query (#601) --- docs/http/http-spans.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 98bc63d4ba..1193cf2cb0 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -388,7 +388,7 @@ The following attributes can be important for making sampling decisions and SHOU ### HTTP client-server example -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: +As an example, if a browser request for `https://example.com:8080/webshop/articles/4?s=1&t=2` is invoked from a host with IP 192.0.2.4, we may have the following Span on the client side: Span name: `GET` @@ -396,7 +396,7 @@ Span name: `GET` | :------------------- | :-------------------------------------------------------| | `http.request.method`| `"GET"` | | `network.protocol.version` | `"1.1"` | -| `url.full` | `"https://example.com:8080/webshop/articles/4?s=1"` | +| `url.full` | `"https://example.com:8080/webshop/articles/4?s=1&t=2"` | | `server.address` | `example.com` | | `server.port` | `8080` | | `network.peer.address` | `"192.0.2.5"` | @@ -412,7 +412,7 @@ Span name: `GET /webshop/articles/:article_id`. | `http.request.method`| `"GET"` | | `network.protocol.version` | `"1.1"` | | `url.path` | `"/webshop/articles/4"` | -| `url.query` | `"?s=1"` | +| `url.query` | `"s=1&t=2"` | | `server.address` | `"example.com"` | | `server.port` | `8080` | | `url.scheme` | `"https"` | From c190a04754fc355f6d13c0d83b481fd74193f30c Mon Sep 17 00:00:00 2001 From: Armin Ruech <7052238+arminru@users.noreply.github.com> Date: Wed, 13 Dec 2023 18:29:17 +0100 Subject: [PATCH 304/482] Fix formatting in README (#607) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4584d9d648..f2b46980c0 100644 --- a/README.md +++ b/README.md @@ -35,4 +35,4 @@ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs - [Josh Suereth](https://github.com/jsuereth), Google - [Reiley Yang](https://github.com/reyang), Microsoft -_Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer). +_Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)._ From bef6b4b39f8fc50c266742f56b23c7024a44bb68 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 13 Dec 2023 11:13:20 -0800 Subject: [PATCH 305/482] Use deprecated property instead of stability level (#588) --- CHANGELOG.md | 2 ++ docs/attributes-registry/http.md | 18 +++++++++--------- docs/attributes-registry/network.md | 26 +++++++++++++------------- model/registry/deprecated/http.yaml | 18 +++++++++--------- model/registry/deprecated/network.yaml | 26 +++++++++++++------------- 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 724ae34495..6eb1af72f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,8 @@ release. - Update stability definitions of HTTP client and server duration metrics to be consistent with markdown. ([#587](https://github.com/open-telemetry/semantic-conventions/pull/587)) +- Use `deprecated` property to mark attributes as deprecated instead of `stability` + ([#588](https://github.com/open-telemetry/semantic-conventions/pull/588)) ## v1.23.1 (2023-11-17) diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 2f9481a64c..8b7665bb9c 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -67,15 +67,15 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin | Attribute | Type | Description | Examples | |---|---|---|---| -| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0` | -| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | -| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | -| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | -| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | -| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | -| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | -| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | -| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | +| `http.flavor` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.name` instead. | `1.0` | +| `http.method` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | +| `http.request_content_length` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.request.header.content-length` instead. | `3495` | +| `http.response_content_length` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.response.header.content-length` instead. | `3495` | +| `http.scheme` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.scheme` instead. | `http`; `https` | +| `http.status_code` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.response.status_code` instead. | `200` | +| `http.target` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | +| `http.url` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | +| `http.user_agent` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | `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. diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index a6c5907728..9c388f4d75 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -103,19 +103,19 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | |---|---|---|---| -| `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | -| `net.host.port` | int | Deprecated, use `server.port`. | `8080` | -| `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | -| `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | -| `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | -| `net.protocol.version` | string | Deprecated, use `network.protocol.version`. | `3.1.1` | -| `net.sock.family` | string | Deprecated, use `network.transport` and `network.type`. | `inet` | -| `net.sock.host.addr` | string | Deprecated, use `network.local.address`. | `/var/my.sock` | -| `net.sock.host.port` | int | Deprecated, use `network.local.port`. | `8080` | -| `net.sock.peer.addr` | string | Deprecated, use `network.peer.address`. | `192.168.0.1` | -| `net.sock.peer.name` | string | Deprecated, no replacement at this time. | `/var/my.sock` | -| `net.sock.peer.port` | int | Deprecated, use `network.peer.port`. | `65531` | -| `net.transport` | string | Deprecated, use `network.transport`. | `ip_tcp` | +| `net.host.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`. | `example.com` | +| `net.host.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.port`. | `8080` | +| `net.peer.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | +| `net.peer.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | +| `net.protocol.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | +| `net.protocol.version` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.version`. | `3.1.1` | +| `net.sock.family` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.transport` and `network.type`. | `inet` | +| `net.sock.host.addr` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.local.address`. | `/var/my.sock` | +| `net.sock.host.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.local.port`. | `8080` | +| `net.sock.peer.addr` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.peer.address`. | `192.168.0.1` | +| `net.sock.peer.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | `/var/my.sock` | +| `net.sock.peer.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.peer.port`. | `65531` | +| `net.transport` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.transport`. | `ip_tcp` | `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. diff --git a/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index 9150328629..9c255eb9f2 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -7,37 +7,37 @@ groups: - id: method type: string brief: 'Deprecated, use `http.request.method` instead.' - stability: deprecated + deprecated: "Replaced by `http.request.method`." examples: ["GET", "POST", "HEAD"] - id: status_code type: int brief: 'Deprecated, use `http.response.status_code` instead.' - stability: deprecated + deprecated: "Replaced by `http.response.status_code`." examples: [200] - id: scheme type: string brief: 'Deprecated, use `url.scheme` instead.' - stability: deprecated + deprecated: "Replaced by `url.scheme` instead." examples: ['http', 'https'] - id: url type: string brief: 'Deprecated, use `url.full` instead.' - stability: deprecated + deprecated: "Replaced by `url.full`." examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target type: string brief: 'Deprecated, use `url.path` and `url.query` instead.' - stability: deprecated + deprecated: "Split to `url.path` and `url.query." examples: ['/search?q=OpenTelemetry#SemConv'] - id: request_content_length type: int brief: 'Deprecated, use `http.request.header.content-length` instead.' - stability: deprecated + deprecated: "Replaced by `http.request.header.content-length`." examples: 3495 - id: response_content_length type: int brief: 'Deprecated, use `http.response.header.content-length` instead.' - stability: deprecated + deprecated: "Replaced by `http.response.header.content-length`." examples: 3495 - id: flavor type: @@ -62,10 +62,10 @@ groups: value: 'QUIC' brief: 'QUIC protocol.' brief: 'Deprecated, use `network.protocol.name` instead.' - stability: deprecated + deprecated: "Replaced by `network.protocol.name`." - id: user_agent type: string brief: 'Deprecated, use `user_agent.original` instead.' examples: ['CERN-LineMode/2.15 libwww/2.17b3', 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] - stability: deprecated + deprecated: "Replaced by `user_agent.original`." diff --git a/model/registry/deprecated/network.yaml b/model/registry/deprecated/network.yaml index 19e9c22667..135373fa09 100644 --- a/model/registry/deprecated/network.yaml +++ b/model/registry/deprecated/network.yaml @@ -7,47 +7,47 @@ groups: attributes: - id: sock.peer.name type: string - stability: deprecated + deprecated: "Removed." brief: Deprecated, no replacement at this time. examples: ['/var/my.sock'] - id: sock.peer.addr type: string - stability: deprecated + deprecated: "Replaced by `network.peer.address`." brief: Deprecated, use `network.peer.address`. examples: ['192.168.0.1'] - id: sock.peer.port type: int - stability: deprecated + deprecated: "Replaced by `network.peer.port`." examples: [65531] brief: Deprecated, use `network.peer.port`. - id: peer.name type: string - stability: deprecated + deprecated: "Replaced by `server.address` on client spans and `client.address` on server spans." brief: Deprecated, use `server.address` on client spans and `client.address` on server spans. examples: ['example.com'] - id: peer.port type: int - stability: deprecated + deprecated: "Replaced by `server.port` on client spans and `client.port` on server spans." brief: Deprecated, use `server.port` on client spans and `client.port` on server spans. examples: [8080] - id: host.name type: string - stability: deprecated + deprecated: "Replaced by `server.address`." brief: Deprecated, use `server.address`. examples: ['example.com'] - id: host.port type: int - stability: deprecated + deprecated: "Replaced by `server.port`." brief: Deprecated, use `server.port`. examples: [8080] - id: sock.host.addr type: string - stability: deprecated + deprecated: "Replaced by `network.local.address`." brief: Deprecated, use `network.local.address`. examples: ['/var/my.sock'] - id: sock.host.port type: int - stability: deprecated + deprecated: "Replaced by `network.local.port`." brief: Deprecated, use `network.local.port`. examples: [8080] - id: transport @@ -71,16 +71,16 @@ groups: - id: other value: "other" brief: 'Something else (non IP-based).' - stability: deprecated + deprecated: "Replaced by `network.transport`." brief: Deprecated, use `network.transport`. - id: protocol.name type: string - stability: deprecated + deprecated: "Replaced by `network.protocol.name`." brief: Deprecated, use `network.protocol.name`. examples: ['amqp', 'http', 'mqtt'] - id: protocol.version type: string - stability: deprecated + deprecated: "Replaced by `network.protocol.version`." brief: Deprecated, use `network.protocol.version`. examples: '3.1.1' - id: sock.family @@ -96,5 +96,5 @@ groups: - id: unix value: 'unix' brief: "Unix domain socket path" - stability: deprecated + deprecated: "Split to `network.transport` and `network.type`." brief: Deprecated, use `network.transport` and `network.type`. From 176db0d28133169a35123157f6e73d4aded56e76 Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Thu, 14 Dec 2023 10:33:15 -0600 Subject: [PATCH 306/482] Replace AWS X-Ray Environment Span Link section (#354) Co-authored-by: Trask Stalnaker Co-authored-by: Josh Suereth --- CHANGELOG.md | 3 +++ docs/faas/aws-lambda.md | 58 ++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eb1af72f2..9c784b75c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ release. ## Unreleased +- Replace AWS X-Ray Environment Span Link section with AWS X-Ray Active Tracing Considerations + ([#354](https://github.com/open-telemetry/semantic-conventions/pull/354)) + ### Breaking - Update `jvm.gc.duration` histogram buckets to `[ 0.01, 0.1, 1, 10 ]` diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index e0f7800a39..c8a568b378 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -14,7 +14,9 @@ use cases. - [All triggers](#all-triggers) - * [AWS X-Ray Environment Span Link](#aws-x-ray-environment-span-link) + * [AWS X-Ray Active Tracing Considerations](#aws-x-ray-active-tracing-considerations) + + [`xray-lambda` Propagator Functionality](#xray-lambda-propagator-functionality) + + [`xray-lambda` Propagator Configuration](#xray-lambda-propagator-configuration) - [API Gateway](#api-gateway) - [SQS](#sqs) * [SQS Event](#sqs-event) @@ -54,21 +56,51 @@ and the [cloud resource conventions][cloud]. The following AWS Lambda-specific a [faasres]: /docs/resource/faas.md (FaaS resource conventions) [cloud]: /docs/resource/cloud.md (Cloud resource conventions) -### AWS X-Ray Environment Span Link +### AWS X-Ray Active Tracing Considerations -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](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md). If the -resulting `Context` is [valid](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#isvalid) then a [Span Link][] SHOULD be added to the new Span's -[start options](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/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 the X-Ray Span Link is not desired. +When [AWS X-Ray Active Tracing](https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html) is enabled for a Lambda, +the runtime will automatically generate a span based on configured sampling rates and propagate the span context +via the `_X_AMZN_TRACE_ID` environment variable (and the `com.amazonaws.xray.traceHeader` system property for Java Lambda functions). +This span context is encoded using the [X-Ray Tracing Header Format](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader). -**Note**: When instrumenting a Java AWS Lambda, instrumentation SHOULD first try to parse an OpenTelemetry `Context` out of the system property `com.amazonaws.xray.traceHeader` using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) before checking and attempting to parse the environment variable above. +Users MUST be able to [configure the propagator](#xray-lambda-propagator-configuration) to prioritize propagating this X-Ray "Active Tracing" span context. +(FYI: Users probably want this enabled if OpenTelemetry is configured to report spans to AWS X-Ray so their trace is linked together properly.) -[Span Link]: https://opentelemetry.io/docs/concepts/signals/traces/#span-links +#### `xray-lambda` Propagator Functionality + +SDK's that have instrumentation for AWS Lambda SHOULD provide an additional propagator alongside the X-Ray propagator +that can [be configured](#xray-lambda-propagator-configuration) via the `OTEL_PROPAGATORS` environment variable setting as `xray-lambda`. +This propagator ignores the provided carrier instance and instead attempts to propagate the span context from the `_X_AMZN_TRACE_ID` environment variable +(and the `com.amazonaws.xray.traceHeader` system property for Java Lambda functions with priority given to the system property if set). + +To avoid potential issues when extracting with an active span context, the `xray-lambda` propagator SHOULD check if the provided context already has an active span context. If found, the propagator SHOULD return the provided context unmodified. + +Example pseudo implementation: + +``` +extract(context, carrier) { + if (Span.fromContext(context).getSpanContext().isValid()) + return context + + traceHeader = getEnvironment("_X_AMZN_TRACE_ID"); + if (isEmptyOrNull(traceHeader)) + return context + + return xrayPropagator.extract(context, ["_X_AMZN_TRACE_ID": traceHeader]) +} +``` + +#### `xray-lambda` Propagator Configuration + +Since propagators are invoked in order, users would give priority to X-Ray's "Active Tracing" span context by setting the environment variable: + +`OTEL_PROPAGATORS=tracecontext,baggage,xray,xray-lambda` + +To avoid broken traces, if OpenTelemetry is reporting traces to another system besides AWS X-Ray, users should either omit `xray-lambda` or add it to the beginning: + +`OTEL_PROPAGATORS=xray-lambda,tracecontext,baggage,xray` + +*Note: The `xray-lambda` propagator can only `extract` context. The `inject` operation MUST be a no-op.* ## API Gateway From 165dae5c29a3fa447e0ac6de4b3bd120c93c34b8 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 14 Dec 2023 12:10:52 -0500 Subject: [PATCH 307/482] Migrate exception attributes to registry (#574) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 2 ++ docs/attributes-registry/README.md | 1 + docs/attributes-registry/exception.md | 37 ++++++++++++++++++++ docs/exceptions/exceptions-logs.md | 10 +++--- docs/exceptions/exceptions-spans.md | 14 ++++---- model/exception.yaml | 33 ------------------ model/registry/exception.yaml | 50 +++++++++++++++++++++++++++ model/trace/trace-exception.yaml | 24 +------------ 8 files changed, 103 insertions(+), 68 deletions(-) create mode 100644 docs/attributes-registry/exception.md delete mode 100644 model/exception.yaml create mode 100644 model/registry/exception.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c784b75c6..bd6fbe383f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ release. - Replace AWS X-Ray Environment Span Link section with AWS X-Ray Active Tracing Considerations ([#354](https://github.com/open-telemetry/semantic-conventions/pull/354)) +- Move Exceptions to attribute registry + ([#574](https://github.com/open-telemetry/semantic-conventions/pull/574)) ### Breaking diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 2e483c4eda..89818c8380 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -36,6 +36,7 @@ Currently, the following namespaces exist: * [Device](device.md) * [Disk](disk.md) * [Error](error.md) +* [Exception](exception.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/exception.md b/docs/attributes-registry/exception.md new file mode 100644 index 0000000000..e3874f51ba --- /dev/null +++ b/docs/attributes-registry/exception.md @@ -0,0 +1,37 @@ + + +# Exceptions + +## Exception Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | +| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | +| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | +| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | + +**[1]:** An exception is considered to have escaped (or left) the scope of a span, +if that span is ended while the exception is still logically "in flight". +This may be actually "in flight" in some languages (e.g. if the exception +is passed to a Context manager's `__exit__` method in Python) but will +usually be caught at the point of recording the exception in most languages. + +It is usually not possible to determine at the point where an exception is thrown +whether it will escape the scope of a span. +However, it is trivial to know that an exception +will escape, if one checks for an active exception just before ending the span, +as done in the [example for recording span exceptions](#recording-an-exception). + +It follows that an exception may still escape the scope of the span +even if the `exception.escaped` attribute was not set or set to false, +since the event might have been recorded at a time where it was not +clear whether the exception will escape. + + +### Recording An Exception + +The `exception.escaped` attribute has special semantics in the context of +a span. Please read the [details here](../exceptions/exceptions-spans.md#recording-an-exception). diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index db8f45c767..19c7c253dd 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -38,14 +38,14 @@ The table below indicates which attributes should be added to the | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | -| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | +| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | **Additional attribute requirements:** At least one of the following sets of attributes is required: -* `exception.type` -* `exception.message` +* [`exception.type`](../attributes-registry/exception.md) +* [`exception.message`](../attributes-registry/exception.md) ### Stacktrace Representation diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index 71f929a2a6..31f88edb53 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -48,10 +48,10 @@ The event name MUST be `exception`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | Recommended | -| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | -| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | +| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | Recommended | +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | +| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | **[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". @@ -63,7 +63,7 @@ It is usually not possible to determine at the point where an exception is throw whether it will escape the scope of a span. However, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span, -as done in the [example above](#recording-an-exception). +as done in the [example for recording span exceptions](#recording-an-exception). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, @@ -72,8 +72,8 @@ clear whether the exception will escape. **Additional attribute requirements:** At least one of the following sets of attributes is required: -* `exception.type` -* `exception.message` +* [`exception.type`](../attributes-registry/exception.md) +* [`exception.message`](../attributes-registry/exception.md) ### Stacktrace Representation diff --git a/model/exception.yaml b/model/exception.yaml deleted file mode 100644 index 9f47fb6700..0000000000 --- a/model/exception.yaml +++ /dev/null @@ -1,33 +0,0 @@ -groups: - - id: exception - type: span - prefix: exception - brief: > - This document defines the shared attributes used to - report a single exception associated with a span or log. - attributes: - - id: type - type: string - brief: > - The type of the exception (its fully-qualified class name, if applicable). - The dynamic type of the exception should be preferred over the static type - in languages that support it. - examples: ["java.net.ConnectException", "OSError"] - - id: message - type: string - brief: The exception message. - examples: ["Division by zero", "Can't convert 'int' object to str implicitly"] - - id: stacktrace - type: string - brief: > - A stacktrace as a string in the natural representation for the language runtime. - The representation is to be determined and documented by each language SIG. - examples: 'Exception in thread "main" java.lang.RuntimeException: Test exception\n - at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n - at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n - at com.example.GenerateTrace.main(GenerateTrace.java:5)' - - constraints: - - any_of: - - "exception.type" - - "exception.message" diff --git a/model/registry/exception.yaml b/model/registry/exception.yaml new file mode 100644 index 0000000000..8894b316a3 --- /dev/null +++ b/model/registry/exception.yaml @@ -0,0 +1,50 @@ +groups: + - id: registry.exception + type: attribute_group + prefix: exception + brief: > + This document defines the shared attributes used to + report a single exception associated with a span or log. + attributes: + - id: type + type: string + brief: > + The type of the exception (its fully-qualified class name, if applicable). + The dynamic type of the exception should be preferred over the static type + in languages that support it. + examples: ["java.net.ConnectException", "OSError"] + - id: message + type: string + brief: The exception message. + examples: ["Division by zero", "Can't convert 'int' object to str implicitly"] + - id: stacktrace + type: string + brief: > + A stacktrace as a string in the natural representation for the language runtime. + The representation is to be determined and documented by each language SIG. + examples: 'Exception in thread "main" java.lang.RuntimeException: Test exception\n + at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n + at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n + at com.example.GenerateTrace.main(GenerateTrace.java:5)' + - id: escaped + type: boolean + brief: > + SHOULD be set to true if the exception event is recorded at a point where + it is known that the exception is escaping the scope of the span. + note: |- + An exception is considered to have escaped (or left) the scope of a span, + if that span is ended while the exception is still logically "in flight". + This may be actually "in flight" in some languages (e.g. if the exception + is passed to a Context manager's `__exit__` method in Python) but will + usually be caught at the point of recording the exception in most languages. + + It is usually not possible to determine at the point where an exception is thrown + whether it will escape the scope of a span. + However, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span, + as done in the [example for recording span exceptions](#recording-an-exception). + + It follows that an exception may still escape the scope of the span + even if the `exception.escaped` attribute was not set or set to false, + since the event might have been recorded at a time where it was not + clear whether the exception will escape. diff --git a/model/trace/trace-exception.yaml b/model/trace/trace-exception.yaml index a11082ebd9..8de3abb818 100644 --- a/model/trace/trace-exception.yaml +++ b/model/trace/trace-exception.yaml @@ -9,29 +9,7 @@ groups: - ref: exception.type - ref: exception.message - ref: exception.stacktrace - - id: escaped - type: boolean - brief: > - SHOULD be set to true if the exception event is recorded at a point where - it is known that the exception is escaping the scope of the span. - note: |- - An exception is considered to have escaped (or left) the scope of a span, - if that span is ended while the exception is still logically "in flight". - This may be actually "in flight" in some languages (e.g. if the exception - is passed to a Context manager's `__exit__` method in Python) but will - usually be caught at the point of recording the exception in most languages. - - It is usually not possible to determine at the point where an exception is thrown - whether it will escape the scope of a span. - However, it is trivial to know that an exception - will escape, if one checks for an active exception just before ending the span, - as done in the [example above](#recording-an-exception). - - It follows that an exception may still escape the scope of the span - even if the `exception.escaped` attribute was not set or set to false, - since the event might have been recorded at a time where it was not - clear whether the exception will escape. - + - ref: exception.escaped constraints: - any_of: - "exception.type" From 73550a3038897df1e49b95fd5109895b5e3b7a91 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Fri, 15 Dec 2023 04:55:41 -0600 Subject: [PATCH 308/482] Add attribute for k8s pod annotations (#573) Signed-off-by: ChrsMark Co-authored-by: Alexander Wert --- CHANGELOG.md | 2 ++ docs/attributes-registry/k8s.md | 51 +++++++++++++++++---------------- docs/resource/k8s.md | 1 + model/registry/k8s.yaml | 5 ++++ model/resource/k8s.yaml | 2 ++ 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd6fbe383f..060ad26619 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ release. - Adds `labels` attribute to `k8s.pod` resource ([#494](https://github.com/open-telemetry/semantic-conventions/pull/494)) +- Adds `annotation` attribute to `k8s.pod` resource + ([#494](https://github.com/open-telemetry/semantic-conventions/pull/573)) - Add `code.stacktrace` attribute ([#435](https://github.com/open-telemetry/semantic-conventions/pull/435)) - Add `http.flavor` and `http.user_agent` to list of deprecated attributes diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index 9becbbf729..56db76720d 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -2,31 +2,32 @@ ## Kubernetes Resource Attributes - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | -| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | -| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | Recommended | -| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | Recommended | -| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | Recommended | -| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | Recommended | -| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | Recommended | -| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | Recommended | -| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | Recommended | -| `k8s.node.name` | string | The name of the Node. | `node-1` | Recommended | -| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | -| `k8s.pod.labels.` | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | Recommended | -| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | -| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | -| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | -| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | Recommended | -| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | +| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | +| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | +| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | +| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | +| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | +| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | +| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | +| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | +| `k8s.node.name` | string | The name of the Node. | `node-1` | +| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | +| `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | +| `k8s.pod.labels.` | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | +| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | +| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | +| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | +| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index f5ed62b723..d8f048fe5a 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -91,6 +91,7 @@ containers on your cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`k8s.pod.annotation.`](../attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | Opt-In | | [`k8s.pod.labels.`](../attributes-registry/k8s.md) | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | Recommended | | [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | | [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index 9c453fb691..e9cecc107e 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -69,6 +69,11 @@ groups: brief: > The labels placed on the Pod, the `` being the label name, the value being the label value. examples: ['k8s.pod.labels.app=my-app', 'k8s.pod.labels.mycompany.io/arch=x64', 'k8s.pod.labels.data='] + - id: pod.annotation + type: template[string] + brief: > + The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. + examples: [ 'k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true', 'k8s.pod.annotation.mycompany.io/arch=x64', 'k8s.pod.annotation.data=' ] - id: container.name type: string brief: > diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index f0752f0f09..6020d7904f 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -34,6 +34,8 @@ groups: - ref: k8s.pod.uid - ref: k8s.pod.name - ref: k8s.pod.labels + - ref: k8s.pod.annotation + requirement_level: opt_in - id: k8s.container prefix: k8s.container From b2e2c64b3f16b3d70b867cbaefc01936f23c1f4c Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Fri, 15 Dec 2023 12:30:17 +0100 Subject: [PATCH 309/482] [CONTRIBUTING.md] Add section about merging ECS conventions (#333) Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CONTRIBUTING.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ab5ce406e..0bfa90bc98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -199,5 +199,24 @@ to merge**. - Send staging tag as PR for review. - Create a tag `v{version}` on the merged PR and push remote. +## Merging existing ECS conventions + +The Elastic Common Schema (ECS) is being merged into OpenTelemetry Semantic +Conventions per [OTEP 222][otep222]. When adding a semantic convention that +exists in some form in ECS, consider the following guidelines: + +- Prefer using the existing ECS name when possible. In particular: + - If proposing a name that differs from the ECS convention, provide usage + data, user issue reports, feature requests, examples of prior work on a + different standard or comparable evidence about the alternatives. + - When no suitable alternatives are provided, altering an ECS name solely + for the purpose of complying with [Name Pluralization guidelines](docs/general/attribute-naming.md#name-pluralization-guidelines) + MAY BE avoided. +- Do not use an existing ECS name as a namespace. If the name must differ, use a + different namespace name to avoid clashes or avoid using the namespace + entirely. See the [ECS field reference] for existing namespaces. + [nvm]: https://github.com/nvm-sh/nvm/blob/master/README.md#installing-and-updating [stability guarantees]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/versioning-and-stability.md#semantic-conventions-stability +[otep222]: https://github.com/open-telemetry/oteps/pull/222 +[ECS field reference]: https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html From cafda7127683b7f667e27cdbd3220510b6f998c9 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 15 Dec 2023 10:36:02 -0800 Subject: [PATCH 310/482] Staging the 1.24.0 release (#613) --- CHANGELOG.md | 25 +++- schema-next.yaml | 22 ++-- schemas/1.24.0 | 306 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 339 insertions(+), 14 deletions(-) create mode 100644 schemas/1.24.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 060ad26619..b194683012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,17 +7,20 @@ release. ## Unreleased -- Replace AWS X-Ray Environment Span Link section with AWS X-Ray Active Tracing Considerations - ([#354](https://github.com/open-telemetry/semantic-conventions/pull/354)) -- Move Exceptions to attribute registry - ([#574](https://github.com/open-telemetry/semantic-conventions/pull/574)) +### Breaking + +### Features + +### Fixes + +## v1.24.0 (2023-12-15) ### Breaking - Update `jvm.gc.duration` histogram buckets to `[ 0.01, 0.1, 1, 10 ]` ([#317](https://github.com/open-telemetry/semantic-conventions/pull/317)) - BREAKING: Change type of `host.cpu.model.id` and `host.cpu.model.family` to string. - ([#495](https://github.com/open-telemetry/semantic-conventions/issues/495)) + ([#499](https://github.com/open-telemetry/semantic-conventions/pull/499)) - Changed `messaging.system` attribute type to an open enum ([#517](https://github.com/open-telemetry/semantic-conventions/pull/517)) - Rename metrics `jvm.memory.usage` to `jvm.memory.used` and `jvm.memory.usage_after_last_gc` @@ -28,11 +31,17 @@ release. - BREAKING: Change `system.disk.io.direction` and `system.network.io.direction` to global attributes `disk.io.direction` and `network.io.direction` ([#530](https://github.com/open-telemetry/semantic-conventions/pull/530)) +- BREAKING: Change `messaging.kafka.partition` to `messaging.kafka.destination.partition` + ([#547](https://github.com/open-telemetry/semantic-conventions/pull/547)) ### Features - Adds `labels` attribute to `k8s.pod` resource ([#494](https://github.com/open-telemetry/semantic-conventions/pull/494)) +- Change Erlang managed thread attribute to be the Erlang process + ([#491](https://github.com/open-telemetry/semantic-conventions/pull/491)) +- Add gcp_pubsub as a messaging system + ([#490](https://github.com/open-telemetry/semantic-conventions/pull/490)) - Adds `annotation` attribute to `k8s.pod` resource ([#494](https://github.com/open-telemetry/semantic-conventions/pull/573)) - Add `code.stacktrace` attribute @@ -52,8 +61,14 @@ release. ([#163](https://github.com/open-telemetry/semantic-conventions/pull/163)) - Add .NET 8.0 metrics for HTTP client, ASP.NET Core, SignalR server and Kestrel. ([#283](https://github.com/open-telemetry/semantic-conventions/pull/283)) +- Add system shared IO direction attributes + ([#530](https://github.com/open-telemetry/semantic-conventions/pull/530)) - JVM metrics marked stable ([#569](https://github.com/open-telemetry/semantic-conventions/pull/569)) +- Add attribute for k8s pod annotations + ([#573](https://github.com/open-telemetry/semantic-conventions/pull/573)) +- Replace AWS X-Ray Environment Span Link section with AWS X-Ray Active Tracing Considerations + ([#354](https://github.com/open-telemetry/semantic-conventions/pull/354)) ### Fixes diff --git a/schema-next.yaml b/schema-next.yaml index 834bff8780..d2ff748f49 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,15 +2,19 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: - # https://github.com/open-telemetry/semantic-conventions/pull/536 - - rename_metrics: - jvm.memory.usage: jvm.memory.used - jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc - # https://github.com/open-telemetry/semantic-conventions/pull/530 - - rename_attributes: - attribute_map: - system.network.io.direction: network.io.direction - system.disk.io.direction: disk.io.direction + 1.24.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/536 + - rename_metrics: + jvm.memory.usage: jvm.memory.used + jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc + # https://github.com/open-telemetry/semantic-conventions/pull/530 + - rename_attributes: + attribute_map: + system.network.io.direction: network.io.direction + system.disk.io.direction: disk.io.direction + 1.23.1: 1.23.0: metrics: changes: diff --git a/schemas/1.24.0 b/schemas/1.24.0 new file mode 100644 index 0000000000..f1de094f68 --- /dev/null +++ b/schemas/1.24.0 @@ -0,0 +1,306 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.24.0 +versions: + 1.24.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/536 + - rename_metrics: + jvm.memory.usage: jvm.memory.used + jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc + # https://github.com/open-telemetry/semantic-conventions/pull/530 + - rename_attributes: + attribute_map: + system.network.io.direction: network.io.direction + system.disk.io.direction: disk.io.direction + 1.23.1: + 1.23.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + thread.daemon: jvm.thread.daemon + apply_to_metrics: + - jvm.thread.count + 1.22.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size + # https://github.com/open-telemetry/opentelemetry-specification/pull/374 + - rename_attributes: + attribute_map: + http.resend_count: http.request.resend_count + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit + process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.usage + - jvm.buffer.limit + - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version + 1.21.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3336 + - rename_attributes: + attribute_map: + messaging.kafka.client_id: messaging.client_id + messaging.rocketmq.client_id: messaging.client_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3402 + - rename_attributes: + attribute_map: + # net.peer.(name|port) attributes were usually populated on client side + # so they should be usually translated to server.(address|port) + # net.host.* attributes were only populated on server side + net.host.name: server.address + net.host.port: server.port + # was only populated on client side + net.sock.peer.name: server.socket.domain + # net.sock.peer.(addr|port) mapping is not possible + # since they applied to both client and server side + # were only populated on server side + net.sock.host.addr: server.socket.address + net.sock.host.port: server.socket.port + http.client_ip: client.address + # https://github.com/open-telemetry/opentelemetry-specification/pull/3426 + - rename_attributes: + attribute_map: + net.protocol.name: network.protocol.name + net.protocol.version: network.protocol.version + net.host.connection.type: network.connection.type + net.host.connection.subtype: network.connection.subtype + net.host.carrier.name: network.carrier.name + net.host.carrier.mcc: network.carrier.mcc + net.host.carrier.mnc: network.carrier.mnc + net.host.carrier.icc: network.carrier.icc + # https://github.com/open-telemetry/opentelemetry-specification/pull/3355 + - rename_attributes: + attribute_map: + http.method: http.request.method + http.status_code: http.response.status_code + http.scheme: url.scheme + http.url: url.full + http.request_content_length: http.request.body.size + http.response_content_length: http.response.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/53 + - rename_metrics: + process.runtime.jvm.cpu.utilization: process.runtime.jvm.cpu.recent_utilization + 1.20.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3272 + - rename_attributes: + attribute_map: + net.app.protocol.name: net.protocol.name + net.app.protocol.version: net.protocol.version + 1.19.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3209 + - rename_attributes: + attribute_map: + faas.execution: faas.invocation_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3188 + - rename_attributes: + attribute_map: + faas.id: cloud.resource_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + http.user_agent: user_agent.original + resources: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + browser.user_agent: user_agent.original + 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: From fb485c9434439946ef63a2d62589ff50807cafe1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 19 Dec 2023 07:37:44 -0800 Subject: [PATCH 311/482] Editorial: change "J9" to "OpenJ9" (#611) Co-authored-by: Josh Suereth --- docs/runtime/jvm-metrics.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index eb72b18211..7c913815e2 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -283,7 +283,7 @@ This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https: This metric is [recommended][MetricRecommended]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuTime()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuTime()) on HotSpot -and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on J9. +and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on OpenJ9. | Name | Instrument Type | Unit (UCUM) | Description | @@ -313,7 +313,7 @@ Note that this is always an integer value (i.e. fractional or millicores are not This metric is [recommended][MetricRecommended]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()) on HotSpot -and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuLoad--) on J9. +and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuLoad--) on OpenJ9. Note that the JVM does not provide a definition of what "recent" means. @@ -364,7 +364,7 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle This metric is [Opt-In][MetricOptIn]. This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getSystemCpuLoad()) on Java version 8..13, [`com.sun.management.OperatingSystemMXBean#getCpuLoad()`](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()) on Java version 14+, -and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on J9. +and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on OpenJ9. | Name | Instrument Type | Unit (UCUM) | Description | From 705155140048f518406958bbb9b7283be4c95f26 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 20 Dec 2023 11:51:13 -0600 Subject: [PATCH 312/482] Rename system.processes.* namespace to system.process.* (#484) Signed-off-by: ChrsMark Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/system/system-metrics.md | 24 ++++++++++++------------ model/metrics/system-metrics.yaml | 16 ++++++++-------- schema-next.yaml | 11 +++++++++++ 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b194683012..6b62c84eb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ release. ### Breaking +- Rename `system.processes.*` namespace to `system.process.*` + ([#484](https://github.com/open-telemetry/semantic-conventions/pull/484)) + ### Features ### Fixes diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index d39384babc..59dd808491 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -52,8 +52,8 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam * [Metric: `system.network.io`](#metric-systemnetworkio) * [Metric: `system.network.connections`](#metric-systemnetworkconnections) - [Aggregate System Process Metrics](#aggregate-system-process-metrics) - * [Metric: `system.processes.count`](#metric-systemprocessescount) - * [Metric: `system.processes.created`](#metric-systemprocessescreated) + * [Metric: `system.process.count`](#metric-systemprocesscount) + * [Metric: `system.process.created`](#metric-systemprocesscreated) - [`system.{os}.` - OS Specific System Metrics](#systemos---os-specific-system-metrics) * [Metric: `system.linux.memory.available`](#metric-systemlinuxmemoryavailable) @@ -718,22 +718,22 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **Description:** System level aggregate process metrics captured under the namespace `system.process`. For metrics at the individual process level, see [process metrics](process-metrics.md). -### Metric: `system.processes.count` +### Metric: `system.process.count` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `system.processes.count` | UpDownCounter | `{process}` | Total number of processes in each state | +| `system.process.count` | UpDownCounter | `{process}` | Total number of processes in each state | - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `system.processes.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | Recommended | +| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | Recommended | -`system.processes.status` 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. +`system.process.status` 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 | |---|---| @@ -743,17 +743,17 @@ This metric is [recommended][MetricRecommended]. | `defunct` | defunct | -### Metric: `system.processes.created` +### Metric: `system.process.created` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `system.processes.created` | Counter | `{process}` | Total number of processes created over uptime of the host | +| `system.process.created` | Counter | `{process}` | Total number of processes created over uptime of the host | - + ## `system.{os}.` - OS Specific System Metrics diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index d411115ea8..9f288e87ff 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -447,9 +447,9 @@ groups: - ref: system.network.state - ref: network.transport - # system.processes.* metrics and attribute group - - id: attributes.system.processes - prefix: system.processes + # system.process.* metrics and attribute group + - id: attributes.system.process + prefix: system.process type: attribute_group brief: "Describes System Process metric attributes" attributes: @@ -470,18 +470,18 @@ groups: examples: ["running"] - - id: metric.system.processes.count + - id: metric.system.process.count type: metric - metric_name: system.processes.count + metric_name: system.process.count brief: "Total number of processes in each state" instrument: updowncounter unit: "{process}" attributes: - - ref: system.processes.status + - ref: system.process.status - - id: metric.system.processes.created + - id: metric.system.process.created type: metric - metric_name: system.processes.created + metric_name: system.process.created brief: "Total number of processes created over uptime of the host" instrument: counter unit: "{process}" diff --git a/schema-next.yaml b/schema-next.yaml index d2ff748f49..aca72805d2 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,17 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/484 + - rename_attributes: + attribute_map: + system.processes.status: system.process.status + apply_to_metrics: + - system.processes.count + - rename_metrics: + system.processes.count: system.process.count + system.processes.created: system.process.created 1.24.0: metrics: changes: From 9423bd3a0b3efb6b3664b574f094b54f03e83b31 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:31:26 -0600 Subject: [PATCH 313/482] Reflect service.*, telemetry.sdk.* stability in model (#620) --- docs/resource/README.md | 10 +++++----- model/resource/service.yaml | 2 ++ model/resource/telemetry.yaml | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/resource/README.md b/docs/resource/README.md index 5a12b18593..a77cbd2f69 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -82,8 +82,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `service.name` | string | Logical name of the service. [1] | `shoppingcart` | Required | -| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | Recommended | +| `service.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Logical name of the service. [1] | `shoppingcart` | Required | +| `service.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | Recommended | **[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. @@ -132,9 +132,9 @@ service.name = Shop.shoppingcart | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | Required | -| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | Required | -| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | Required | +| `telemetry.sdk.language` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The language of the telemetry SDK. | `cpp` | Required | +| `telemetry.sdk.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The name of the telemetry SDK as defined above. [1] | `opentelemetry` | Required | +| `telemetry.sdk.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The version string of the telemetry SDK. | `1.2.3` | Required | **[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the diff --git a/model/resource/service.yaml b/model/resource/service.yaml index e930b62194..05b2e02698 100644 --- a/model/resource/service.yaml +++ b/model/resource/service.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: name type: string + stability: stable requirement_level: required brief: > Logical name of the service. @@ -18,6 +19,7 @@ groups: examples: ["shoppingcart"] - id: version type: string + stability: stable brief: > The version string of the service API or implementation. The format is not defined by these conventions. examples: ["2.0.0", "a01dbef8a"] diff --git a/model/resource/telemetry.yaml b/model/resource/telemetry.yaml index 6966b4a853..9b57a7afd2 100644 --- a/model/resource/telemetry.yaml +++ b/model/resource/telemetry.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: sdk.name type: string + stability: stable requirement_level: required brief: > The name of the telemetry SDK as defined above. @@ -46,11 +47,13 @@ groups: value: "swift" - id: webjs value: "webjs" + stability: stable requirement_level: required brief: > The language of the telemetry SDK. - id: sdk.version type: string + stability: stable requirement_level: required brief: > The version string of the telemetry SDK. From 3a9d477cf596d2317a35becf952210e739d0c56a Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 4 Jan 2024 13:02:35 -0500 Subject: [PATCH 314/482] Stabilize exception semantic conventions. (#619) --- docs/attributes-registry/exception.md | 8 ++++---- docs/exceptions/exceptions-logs.md | 2 +- docs/exceptions/exceptions-spans.md | 2 +- model/registry/exception.yaml | 4 ++++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/attributes-registry/exception.md b/docs/attributes-registry/exception.md index e3874f51ba..e5d541c930 100644 --- a/docs/attributes-registry/exception.md +++ b/docs/attributes-registry/exception.md @@ -8,10 +8,10 @@ | Attribute | Type | Description | Examples | |---|---|---|---| -| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | -| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | -| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | -| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | +| `exception.escaped` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | +| `exception.message` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | +| `exception.stacktrace` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | +| `exception.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | **[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 19c7c253dd..11656ea1df 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -4,7 +4,7 @@ linkTitle: Logs # Semantic Conventions for Exceptions in Logs -**Status**: [Experimental][DocumentStatus] +**Status**: [Stable][DocumentStatus] This document defines semantic conventions for recording exceptions on [logs](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#emit-a-logrecord) and [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/event-api.md#emit-event) diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index 31f88edb53..18a91996a5 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -4,7 +4,7 @@ linkTitle: Spans # Semantic Conventions for Exceptions on Spans -**Status**: [Experimental][DocumentStatus] +**Status**: [Stable][DocumentStatus] This document defines semantic conventions for recording application exceptions associated with spans. diff --git a/model/registry/exception.yaml b/model/registry/exception.yaml index 8894b316a3..7e1b011889 100644 --- a/model/registry/exception.yaml +++ b/model/registry/exception.yaml @@ -8,6 +8,7 @@ groups: attributes: - id: type type: string + stability: stable brief: > The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type @@ -15,10 +16,12 @@ groups: examples: ["java.net.ConnectException", "OSError"] - id: message type: string + stability: stable brief: The exception message. examples: ["Division by zero", "Can't convert 'int' object to str implicitly"] - id: stacktrace type: string + stability: stable brief: > A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. @@ -28,6 +31,7 @@ groups: at com.example.GenerateTrace.main(GenerateTrace.java:5)' - id: escaped type: boolean + stability: stable brief: > SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. From 7d0c0a0fc5298362cffcd9b1d79c9a0716e58f52 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 8 Jan 2024 18:30:43 +0100 Subject: [PATCH 315/482] Refactoring: move browser to the registry (#605) Co-authored-by: Joao Grassi --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/browser.md | 24 +++++++++++++++ docs/resource/browser.md | 8 ++--- model/registry/browser.yaml | 47 +++++++++++++++++++++++++++++ model/resource/browser.yaml | 44 +++------------------------ 5 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 docs/attributes-registry/browser.md create mode 100644 model/registry/browser.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 89818c8380..ada3b9534f 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,6 +27,7 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Browser](browser.md) * [Client](client.md) * [Cloud](cloud.md) * [Code](code.md) diff --git a/docs/attributes-registry/browser.md b/docs/attributes-registry/browser.md new file mode 100644 index 0000000000..84366ea986 --- /dev/null +++ b/docs/attributes-registry/browser.md @@ -0,0 +1,24 @@ + + +# Browser + +## Browser Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | +| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | +| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | +| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | + +**[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). + +**[2]:** This value is intended to be taken from the Navigator API `navigator.language`. + +**[3]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. + +**[4]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. +The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. + diff --git a/docs/resource/browser.md b/docs/resource/browser.md index cec3fe9494..da7818bb5f 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -11,10 +11,10 @@ All of these attributes can be provided by the user agent itself in the form of | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | Recommended | -| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | -| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | Recommended | -| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | Recommended | +| [`browser.brands`](../attributes-registry/browser.md) | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | Recommended | +| [`browser.language`](../attributes-registry/browser.md) | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | +| [`browser.mobile`](../attributes-registry/browser.md) | boolean | A boolean that is true if the browser is running on a mobile device [3] | | Recommended | +| [`browser.platform`](../attributes-registry/browser.md) | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | Recommended | | [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | Recommended | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). diff --git a/model/registry/browser.yaml b/model/registry/browser.yaml new file mode 100644 index 0000000000..e9d0da5c93 --- /dev/null +++ b/model/registry/browser.yaml @@ -0,0 +1,47 @@ +groups: + - id: registry.browser + prefix: browser + type: resource + brief: > + The web browser attributes + attributes: + - id: brands + type: string[] + brief: 'Array of brand name and version separated by a space' + note: > + This value is intended to be taken from the + [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) + (`navigator.userAgentData.brands`). + examples: [ " Not A;Brand 99", "Chromium 99", "Chrome 99" ] + - id: platform + type: string + brief: 'The platform on which the browser is running' + note: > + This value is intended to be taken from the + [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) + (`navigator.userAgentData.platform`). If unavailable, the legacy + `navigator.platform` API SHOULD NOT be used instead and this attribute + SHOULD be left unset in order for the values to be consistent. + + The list of possible values is defined in the + [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). + Note that some (but not all) of these values can overlap with values + in the [`os.type` and `os.name` attributes](./os.md). + However, for consistency, the values in the `browser.platform` attribute + should capture the exact value that the user agent provides. + examples: ['Windows', 'macOS', 'Android'] + - id: mobile + type: boolean + brief: 'A boolean that is true if the browser is running on a mobile device' + note: > + This value is intended to be taken from the + [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) + (`navigator.userAgentData.mobile`). If unavailable, this attribute + SHOULD be left unset. + - id: language + type: string + brief: 'Preferred language of the user using the browser' + note: > + This value is intended to be taken from the Navigator API + `navigator.language`. + examples: ["en", "en-US", "fr", "fr-FR"] diff --git a/model/resource/browser.yaml b/model/resource/browser.yaml index 56830c1dde..0ec1a6e3aa 100644 --- a/model/resource/browser.yaml +++ b/model/resource/browser.yaml @@ -7,46 +7,10 @@ groups: The `browser.*` attributes MUST be used only for resources that represent applications running in a web browser (regardless of whether running on a mobile or desktop device). attributes: - - id: brands - type: string[] - brief: 'Array of brand name and version separated by a space' - note: > - This value is intended to be taken from the - [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) - (`navigator.userAgentData.brands`). - examples: [" Not A;Brand 99", "Chromium 99", "Chrome 99"] - - id: platform - type: string - brief: 'The platform on which the browser is running' - note: > - This value is intended to be taken from the - [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) - (`navigator.userAgentData.platform`). If unavailable, the legacy - `navigator.platform` API SHOULD NOT be used instead and this attribute - SHOULD be left unset in order for the values to be consistent. - - The list of possible values is defined in the - [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). - Note that some (but not all) of these values can overlap with values - in the [`os.type` and `os.name` attributes](./os.md). - However, for consistency, the values in the `browser.platform` attribute - should capture the exact value that the user agent provides. - examples: ['Windows', 'macOS', 'Android'] - - id: mobile - type: boolean - brief: 'A boolean that is true if the browser is running on a mobile device' - note: > - This value is intended to be taken from the - [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) - (`navigator.userAgentData.mobile`). If unavailable, this attribute - SHOULD be left unset. - - id: language - type: string - brief: 'Preferred language of the user using the browser' - note: > - This value is intended to be taken from the Navigator API - `navigator.language`. - examples: ["en", "en-US", "fr", "fr-FR"] + - ref: browser.brands + - ref: browser.platform + - ref: browser.mobile + - ref: browser.language - ref: user_agent.original brief: 'Full user-agent string provided by the browser' note: > From 1dd4fe343906a4735f50da471d63719dd0dfd922 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 Jan 2024 14:29:17 -0800 Subject: [PATCH 316/482] Add HTTP semantic convention stability migration guide (#612) --- .markdown_link_check_config.json | 2 +- docs/http/migration-guide.md | 223 +++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 docs/http/migration-guide.md diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index 48c1f6c392..efd4eb0d85 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -10,7 +10,7 @@ "replacement": "{{BASEURL}}/" }, { - "pattern": "^https://github.com/open-telemetry/semantic-conventions/(blob|tree)/[^/]+/docs/", + "pattern": "^https://github.com/open-telemetry/semantic-conventions/(blob|tree)/[^v][^/]*/docs/", "replacement": "LINK-CHECK-ERROR-USE-LOCAL-PATH-TO-DOC-PAGE-NOT-EXTERNAL-URL/" } ], diff --git a/docs/http/migration-guide.md b/docs/http/migration-guide.md new file mode 100644 index 0000000000..16336c73b3 --- /dev/null +++ b/docs/http/migration-guide.md @@ -0,0 +1,223 @@ +# HTTP semantic convention stability migration guide + +Due to the significant number of modifications and the extensive user base +affected by them, existing HTTP instrumentations published by +OpenTelemetry are required to implement a migration plan that will assist users in +transitioning to the stable HTTP semantic conventions. + +Specifically, when existing HTTP instrumentations published by OpenTelemetry are +updated to the stable HTTP semantic conventions, they: + +- SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` in + their existing major version, which accepts: + - `http` - emit the stable HTTP and networking conventions, and stop emitting + the old HTTP and networking conventions that the instrumentation emitted + previously. + - `http/dup` - emit both the old and the stable HTTP and networking + conventions, allowing for a phased rollout of the stable semantic + conventions. + - The default behavior (in the absence of one of these values) is to continue + emitting whatever version of the old HTTP and networking conventions the + instrumentation was emitting previously. +- Need to maintain (security patching at a minimum) their existing major version + for at least six months after it starts emitting both sets of conventions. +- May drop the environment variable in their next major version and emit only + the stable HTTP and networking conventions. + +## Summary of changes + +This section summarizes the changes made to the HTTP semantic conventions +from +[v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md) +to +[v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/README.md). + +### Common attributes across HTTP client and server spans + + +| Change | Comments | +| --- | --- | +| `http.method` → `http.request.method` | Now captures only 9 common HTTP methods by default (configurable) plus `_OTHER` | +| `http.status_code` → `http.response.status_code` | | +| `http.request.header.` | • Dash (`"-"`) to underscore (`"_"`) normalization in `` has been removed
• On HTTP server spans: now must be provided to sampler | +| `http.response.header.` | Dash (`"-"`) to underscore (`"_"`) normalization in `` has been removed | +| `http.request_content_length` → `http.request.body.size` | • Recommended → Opt-In
• _Not marked stable yet_ | +| `http.response_content_length` → `http.response.body.size` | • Recommended → Opt-In
• _Not marked stable yet_ | +| `user_agent.original` | • On HTTP client spans: Recommended → Opt-In
• On HTTP server spans: now must be provided to sampler
• See note if [migrating from <= v1.18.0](#migrating-from--v1180) | +| `net.protocol.name` → `network.protocol.name` | Recommended → Conditionally required if not `http` and `network.protocol.version` is set | +| `net.protocol.version` → `network.protocol.version` | • Examples fixed: `2.0` → `2` and `3.0` → `3`
• See note if [migrating from <= v1.19.0](#migrating-from--v1190) | +| `net.sock.family` | Removed | +| `net.sock.peer.addr` → `network.peer.address` | On HTTP server spans: if `http.client_ip` was unknown, then also `net.sock.peer.addr` → `client.address`; `client.address` must be provided to sampler | +| `net.sock.peer.port` → `network.peer.port` | Now captured even if same as `server.port` | +| `net.sock.peer.name` | Removed | +| New: `http.request.method_original` | Only captured when `http.request.method` is `_OTHER` | +| New: `error.type` | | + + +References: + +- [Common attributes v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md#common-attributes) +- [Common attributes v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#common-attributes) + +### HTTP client span attributes + + +| Change | Comments | +| --- | --- | +| `http.url` → `url.full` | | +| `http.resend_count` → `http.request.resend_count` | | +| `net.peer.name` → `server.address` | | +| `net.peer.port` → `server.port` | Now captured even when same as default port for scheme | + + +References: + +- [HTTP client span attributes v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md#http-client) +- [HTTP client span attributes v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#metric-httpserverrequestduration) + +### HTTP server span attributes + + +| Change | Comments | +| --- | --- | +| `http.route` | No change | +| `http.target` → `url.path` and `url.query` | Split into two separate attributes | +| `http.scheme` → `url.scheme` | Now factors in [X-Forwarded-Proto][], [Forwarded#proto][] headers | +| `http.client_ip` → `client.address` | If `http.client_ip` was unknown (i.e., no [X-Forwarded-For][], [Forwarded#for][] headers), then `net.sock.peer.addr` → `client.address`; now must be provided to sampler | +| `net.host.name` → `server.address` | Now based only on [Host][Host header], [:authority][HTTP/2 authority], [X-Forwarded-Host][], [Forwarded#host][] headers | +| `net.host.port` → `server.port` | Now based only on [Host][Host header], [:authority][HTTP/2 authority], [X-Forwarded-Host][X-Forwarded-Host], [Forwarded#host][] headers | + + +References: + +- [HTTP server span attributes v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md#http-server) +- [HTTP server span attributes v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#metric-httpserverrequestduration) + +### HTTP client and server span names + +The `{http.method}` portion of span names is replace by `HTTP` when +`{http.method}` is `_OTHER`. + +See note if [migrating from `<= v1.17.0`](#migrating-from--v1170). + +References: + +- [HTTP client and server span names v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md#name) +- [HTTP client and server span names v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#metric-httpserverrequestduration) + +### HTTP client duration metric + +Metric changes: + +- **Name**: `http.client.duration` → `http.client.request.duration` +- **Unit**: `ms` → `s` +- **Description**: `Measures the duration of inbound HTTP requests.` → + `Duration of HTTP server requests.` +- **Histogram buckets**: boundaries updated to reflect change from milliseconds + to seconds, and zero bucket boundary removed +- **Attributes**: see table below + + +| Attribute change | Comments | +| --- | --- | +| `http.method` → `http.request.method` | Now captures only 9 common HTTP methods by default plus `_OTHER` | +| `http.status_code` → `http.response.status_code` | | +| `net.peer.name` → `server.address` | | +| `net.peer.port` → `server.port` | Now captured even when same as default port for scheme | +| `net.sock.peer.addr` | Removed | +| `net.protocol.name` → `network.protocol.name` | Recommended → Conditionally required if not `http` and `network.protocol.version` is set | +| `net.protocol.version` → `network.protocol.version` | Examples fixed: `2.0` → `2` and `3.0` → `3`; see note if [migrating from `<= v1.19.0`](#migrating-from--v1190) | +| New: `error.type` | | + + +References: + +- [Metric `http.client.duration` v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md#metric-httpclientduration) +- [Metric `http.client.request.duration` v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-metrics.md#metric-httpserverrequestduration) + +### HTTP server duration metric + +Metric changes: + +- **Name**: `http.server.duration` → `http.server.request.duration` +- **Unit**: `ms` → `s` +- **Description**: `Measures the duration of inbound HTTP requests.` → + `Duration of HTTP server requests.` +- **Histogram buckets**: boundaries updated to reflect change from milliseconds + to seconds, and zero bucket boundary removed +- **Attributes**: see table below + + +| Attribute change | Comments | +| --- | --- | +| `http.route` | No change | +| `http.method` → `http.request.method` | Now captures only 9 common HTTP methods by default plus `_OTHER` | +| `http.status_code` → `http.response.status_code` | | +| `http.scheme` → `url.scheme` | Now factors in [`X-Forwarded-Proto` span][X-Forwarded-Proto], [`Forwarded#proto` span][Forwarded#proto] headers | +| `net.protocol.name` → `network.protocol.name` | Recommended → Conditionally required if not `http` and `network.protocol.version` is set | +| `net.protocol.version` → `network.protocol.version` | Examples fixed: `2.0` → `2` and `3.0` → `3`; see note if [migrating from `<= v1.19.0`](#migrating-from--v1190) | +| `net.host.name` → `server.address` | • Recommended → Opt-In (due to high-cardinality vulnerability since based on HTTP headers)
• Now based only on [`Host` span][Host header], [`:authority` span][HTTP/2 authority], [`X-Forwarded-Host` span][X-Forwarded-Host], [`Forwarded#host` span][Forwarded#host] headers | +| `net.host.port` → `server.port` | • Recommended → Opt-In (due to high-cardinality vulnerability since based on HTTP headers)
• Now based only on [`Host` span][Host header], [`:authority` span][HTTP/2 authority], [`X-Forwarded-Host` span][X-Forwarded-Host], [`Forwarded#host` span][Forwarded#host] headers | +| New: `error.type` | | + + +References: + +- [Metric `http.server.duration` v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration) +- [Metric `http.server.request.duration` v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-metrics.md#metric-httpserverrequestduration) + +## Migrating from a version prior to v1.20.0? + +In addition to the changes made to the HTTP semantic conventions +from +[v1.20.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/http.md) +to +[v1.23.1 (stable)](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/README.md), +there are additional changes if you are migrating to v1.23.1 from a version prior to v1.20.0. + +### Migrating from `<= v1.19.0` + +- `http.flavor` → `network.protocol.version` + - Examples fixed: `2.0` → `2` and `3.0` → `3` + +### Migrating from `<= v1.18.0` + +- `http.user_agent` → `user_agent.original` + +### Migrating from `<= v1.17.0` + +#### HTTP server span name + +- When `http.route` is available:
`{http.route}` → + `{summary} {http.route}` +- When `http.route` is not available:
`HTTP {http.method}` → + `{summary}` + +Where `{summary}` is `{http.method}`, unless `{http.method}` is `_OTHER`, in +which case `{summary}` is `HTTP`. + +#### HTTP client span name + +- `HTTP {http.method}` → `{summary}` + +Where `{summary}` is `{http.method}`, unless `{http.method}` is `_OTHER`, in +which case `{summary}` is `HTTP`. + +### Migrating from `<= v1.16.0` + +This document does not cover these versions. + +[Host header]: https://tools.ietf.org/html/rfc7230#section-5.4 +[HTTP/2 authority]: https://tools.ietf.org/html/rfc9113#section-8.3.1 +[Forwarded#for]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for +[Forwarded#proto]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto +[Forwarded#host]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host +[X-Forwarded-For]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For +[X-Forwarded-Proto]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto +[X-Forwarded-Host]: +https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host From 75f9d428a45f9e779b72c34d9ac3c00625b7472a Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Mon, 8 Jan 2024 14:31:40 -0800 Subject: [PATCH 317/482] Add a warning to the system semantic conventions (#579) --- docs/system/hardware-metrics.md | 11 +++++++++++ docs/system/process-metrics.md | 10 ++++++++++ docs/system/system-metrics.md | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index 904dd8c74d..09ba773b65 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -33,6 +33,17 @@ when creating instruments not explicitly defined in the specification. +> **Warning** +> Existing instrumentations and collector that are using +> [v1.21.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/system/hardware-metrics.md) +> (or prior): +> +> * SHOULD NOT adopt any breaking changes from document until the system +> semantic conventions are marked stable. Conventions include, but are not +> limited to, attributes, metric names, and unit of measure. +> * SHOULD introduce a control mechanism to allow users to opt-in to the new +> conventions once the migration plan is finalized. + ## Common hardware attributes All metrics in `hw.` instruments should be attached to a [Host Resource](/docs/resource/host.md) diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 4312631963..c619763717 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -25,6 +25,16 @@ metrics](/docs/runtime/README.md#metrics). +> **Warning** Existing instrumentations and collector that are using +> [v1.21.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/system/process-metrics.md) +> (or prior): +> +> * SHOULD NOT adopt any breaking changes from document until the system +> semantic conventions are marked stable. Conventions include, but are not +> limited to, attributes, metric names, and unit of measure. +> * SHOULD introduce a control mechanism to allow users to opt-in to the new +> conventions once the migration plan is finalized. + ## Metric Instruments ### Process diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 59dd808491..4f682cc030 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -59,6 +59,16 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam +> **Warning** Existing instrumentations and collector that are using +> [v1.21.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/system/system-metrics.md) +> (or prior): +> +> * SHOULD NOT adopt any breaking changes from document until the system +> semantic conventions are marked stable. Conventions include, but are not +> limited to, attributes, metric names, and unit of measure. +> * SHOULD introduce a control mechanism to allow users to opt-in to the new +> conventions once the migration plan is finalized. + ## Processor Metrics **Description:** System level processor metrics captured under the namespace `system.cpu`. From 73b488a672b916d3d2555450b6c9dbeb5a74e5a0 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Tue, 9 Jan 2024 18:50:08 +0200 Subject: [PATCH 318/482] Depluralize labels for pod and container resources (#625) Signed-off-by: ChrsMark Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/attributes-registry/container.md | 2 +- docs/attributes-registry/k8s.md | 2 +- docs/resource/container.md | 2 +- docs/resource/k8s.md | 2 +- model/registry/container.yaml | 4 ++-- model/registry/k8s.yaml | 6 +++--- model/resource/container.yaml | 2 +- model/resource/k8s.yaml | 2 +- schema-next.yaml | 5 +++++ 10 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b62c84eb6..4a4e19d2ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ release. - Rename `system.processes.*` namespace to `system.process.*` ([#484](https://github.com/open-telemetry/semantic-conventions/pull/484)) +- Depluralize labels for pod (`k8s.pod.labels.*`) and container (`container.labels.*`) resources + ([#625](https://github.com/open-telemetry/semantic-conventions/pull/625)) ### Features diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index 7cc959620b..d9f66e67f9 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -16,7 +16,7 @@ | `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | | `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | | `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | -| `container.labels.` | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | +| `container.label.` | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | | `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | | `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index 56db76720d..7c85db4516 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -21,7 +21,7 @@ | `k8s.node.name` | string | The name of the Node. | `node-1` | | `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | | `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | -| `k8s.pod.labels.` | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | +| `k8s.pod.label.` | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | | `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | | `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | | `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | diff --git a/docs/resource/container.md b/docs/resource/container.md index 1abdd5c277..7606ce6178 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -17,7 +17,7 @@ | [`container.image.name`](../attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | | [`container.image.repo_digests`](../attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | | [`container.image.tags`](../attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | -| [`container.labels.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.labels.app=nginx` | Recommended | +| [`container.label.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | Recommended | | [`container.name`](../attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | | [`container.runtime`](../attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | | [`oci.manifest.digest`](../attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [4] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | Recommended | diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index d8f048fe5a..1dd9a9fdee 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -92,7 +92,7 @@ containers on your cluster. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`k8s.pod.annotation.`](../attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | Opt-In | -| [`k8s.pod.labels.`](../attributes-registry/k8s.md) | string | The labels placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.labels.app=my-app`; `k8s.pod.labels.mycompany.io/arch=x64`; `k8s.pod.labels.data=` | Recommended | +| [`k8s.pod.label.`](../attributes-registry/k8s.md) | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | Recommended | | [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | | [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 0755d078af..4b11e772fd 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -79,8 +79,8 @@ groups: brief: > All the command arguments (including the command/executable itself) run by the container. [2] examples: [ 'otelcontribcol, --config, config.yaml' ] - - id: labels + - id: label type: template[string] brief: > Container labels, `` being the label name, the value being the label value. - examples: [ 'container.labels.app=nginx' ] + examples: [ 'container.label.app=nginx' ] diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index e9cecc107e..efda36e993 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -64,11 +64,11 @@ groups: brief: > The name of the Pod. examples: ['opentelemetry-pod-autoconf'] - - id: pod.labels + - id: pod.label type: template[string] brief: > - The labels placed on the Pod, the `` being the label name, the value being the label value. - examples: ['k8s.pod.labels.app=my-app', 'k8s.pod.labels.mycompany.io/arch=x64', 'k8s.pod.labels.data='] + The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. + examples: ['k8s.pod.label.app=my-app', 'k8s.pod.label.mycompany.io/arch=x64', 'k8s.pod.label.data='] - id: pod.annotation type: template[string] brief: > diff --git a/model/resource/container.yaml b/model/resource/container.yaml index 97923e440e..c0034ca7ca 100644 --- a/model/resource/container.yaml +++ b/model/resource/container.yaml @@ -18,5 +18,5 @@ groups: requirement_level: opt_in - ref: container.command_args requirement_level: opt_in - - ref: container.labels + - ref: container.label - ref: oci.manifest.digest diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index 6020d7904f..e61bf0cad1 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -33,7 +33,7 @@ groups: attributes: - ref: k8s.pod.uid - ref: k8s.pod.name - - ref: k8s.pod.labels + - ref: k8s.pod.label - ref: k8s.pod.annotation requirement_level: opt_in diff --git a/schema-next.yaml b/schema-next.yaml index aca72805d2..58de42a543 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -13,6 +13,11 @@ versions: - rename_metrics: system.processes.count: system.process.count system.processes.created: system.process.created + # https://github.com/open-telemetry/semantic-conventions/pull/625 + - rename_attributes: + attribute_map: + container.labels: container.label + k8s.pod.labels: k8s.pod.label 1.24.0: metrics: changes: From 7f35c490ca2361d9030c504bcda3213d6d102041 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Wed, 10 Jan 2024 03:25:30 -0600 Subject: [PATCH 319/482] Clarify that service.* conventions apply to all telemetry sources (#630) Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/resource/README.md | 4 ++-- model/resource/service.yaml | 7 ++++++- model/resource/service_experimental.yaml | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a4e19d2ca..70cc8db1d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ release. ### Fixes +- Clarify that `service.*` attributes apply to all telemetry sources. + ([#630](https://github.com/open-telemetry/semantic-conventions/pull/630)) + ## v1.24.0 (2023-12-15) ### Breaking diff --git a/docs/resource/README.md b/docs/resource/README.md index a77cbd2f69..1c0b63718f 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -77,7 +77,7 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **type:** `service` -**Description:** A service instance. +**Description:** A telemetry source. OpenTelemetry has adopted a broad interpretation such that every telemetry source is a service. Examples include, but are not limited to: web services, hosts, mobile applications, browser application, edge computing devices, functions as a service, databases, message brokers, etc. Specific types of telemetry sources may have additional conventions defining domain specific information, but the `service` conventions are applicable to all telemetry sources. | Attribute | Type | Description | Examples | Requirement Level | @@ -94,7 +94,7 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **type:** `service` -**Description:** Additions to service instance. +**Description:** Experimental additions to service. | Attribute | Type | Description | Examples | Requirement Level | diff --git a/model/resource/service.yaml b/model/resource/service.yaml index 05b2e02698..fc3d3a6c52 100644 --- a/model/resource/service.yaml +++ b/model/resource/service.yaml @@ -3,7 +3,12 @@ groups: prefix: service type: resource brief: > - A service instance. + A telemetry source. OpenTelemetry has adopted a broad interpretation such that every + telemetry source is a service. Examples include, but are not limited to: web services, + hosts, mobile applications, browser application, edge computing devices, functions as + a service, databases, message brokers, etc. Specific types of telemetry sources may have + additional conventions defining domain specific information, but the `service` + conventions are applicable to all telemetry sources. attributes: - id: name type: string diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index 43c869ee35..9103ac7531 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -3,7 +3,7 @@ groups: prefix: service type: resource brief: > - A service instance. + Experimental additions to service. attributes: - id: namespace type: string From efe8fa5dd2ef4e403500e81fdb5d47ac5f3aad5b Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:35:39 +0200 Subject: [PATCH 320/482] Add `azure_container_apps` to `cloud.platform` semantic conventions (#615) Co-authored-by: Joao Grassi --- CHANGELOG.md | 3 +++ docs/attributes-registry/cloud.md | 1 + docs/resource/cloud.md | 1 + model/registry/cloud.yaml | 3 +++ 4 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70cc8db1d1..59db03d7ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ release. ### Features +- Add `azure_container_apps` to `cloud.platform` semantic conventions + ([#615](https://github.com/open-telemetry/semantic-conventions/pull/615)) + ### Fixes - Clarify that `service.*` attributes apply to all telemetry sources. diff --git a/docs/attributes-registry/cloud.md b/docs/attributes-registry/cloud.md index a51ac490aa..1931f5a878 100644 --- a/docs/attributes-registry/cloud.md +++ b/docs/attributes-registry/cloud.md @@ -54,6 +54,7 @@ The following well-known definitions MUST be used if you set this attribute and | `aws_app_runner` | AWS App Runner | | `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | | `azure_vm` | Azure Virtual Machines | +| `azure_container_apps` | Azure Container Apps | | `azure_container_instances` | Azure Container Instances | | `azure_aks` | Azure Kubernetes Service | | `azure_functions` | Azure Functions | diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index c8ced8c2c3..8d047494b4 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -55,6 +55,7 @@ The following well-known definitions MUST be used if you set this attribute and | `aws_app_runner` | AWS App Runner | | `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | | `azure_vm` | Azure Virtual Machines | +| `azure_container_apps` | Azure Container Apps | | `azure_container_instances` | Azure Container Instances | | `azure_aks` | Azure Kubernetes Service | | `azure_functions` | Azure Functions | diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml index 2c669052e8..9835e09b62 100644 --- a/model/registry/cloud.yaml +++ b/model/registry/cloud.yaml @@ -125,6 +125,9 @@ groups: - id: azure_vm value: 'azure_vm' brief: Azure Virtual Machines + - id: azure_container_apps + value: 'azure_container_apps' + brief: Azure Container Apps - id: azure_container_instances value: 'azure_container_instances' brief: Azure Container Instances From aface154c238917b0e8179d59d5ccae8750a2460 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 10 Jan 2024 02:18:53 -0800 Subject: [PATCH 321/482] Update link check exclusion (#632) Co-authored-by: Joao Grassi --- .markdown_link_check_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index efd4eb0d85..8ee8073745 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -10,7 +10,7 @@ "replacement": "{{BASEURL}}/" }, { - "pattern": "^https://github.com/open-telemetry/semantic-conventions/(blob|tree)/[^v][^/]*/docs/", + "pattern": "^https://github.com/open-telemetry/semantic-conventions/(blob|tree)/main/docs/", "replacement": "LINK-CHECK-ERROR-USE-LOCAL-PATH-TO-DOC-PAGE-NOT-EXTERNAL-URL/" } ], From de9ef07a0a4621902a644067343b998f8bef3b34 Mon Sep 17 00:00:00 2001 From: Anna Levenberg Date: Wed, 10 Jan 2024 06:21:22 -0500 Subject: [PATCH 322/482] docs(messaging): add gcp async batch publish example (#545) Co-authored-by: Liudmila Molkova Co-authored-by: Alex Hong <9397363+hongalex@users.noreply.github.com> Co-authored-by: Johannes Tax Co-authored-by: Josh Suereth Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/messaging/gcp-pubsub.md | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59db03d7ac..4dfe18a4a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ release. - Add `azure_container_apps` to `cloud.platform` semantic conventions ([#615](https://github.com/open-telemetry/semantic-conventions/pull/615)) +- Add an example for gcp_pubsub asynchronous batch publish + ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)). ### Fixes diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 08027ce032..95acf97d64 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -19,4 +19,42 @@ For Google Cloud Pub/Sub, the following additional attributes are defined: | [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | Conditionally Required: If the message type has an ordering key set. | +## Examples + +### Asynchronous Batch Publish Example + +Given is a process P that asynchronously publishes 2 messages in a batch to a topic T on Pub/Sub. + +```mermaid +flowchart LR; + subgraph PRODUCER + direction LR + CA[Span Create A] + CB[Span Create B] + P[Span Publish A B] + end + CA-. link .-P; + CB-. link .-P; + + classDef producer fill:green + class P,CA,CB producer + classDef normal fill:green + class PA,PB,D1 normal + linkStyle 0,1 color:green,stroke:green +``` + +| Field or Attribute | Span Create A | Span Create B | Span Publish A B | +|-|-|-|-| +| Span name | `T create` | `T create` | `publish` | +| Parent | | | | +| Links | | | Span Create A, Span Create B | +| SpanKind | `PRODUCER` | `PRODUCER` | `CLIENT` | +| Status | `Ok` | `Ok` | `Ok` | +| `messaging.batch.message_count` | | | 2 | +| `messaging.destination.name` | `"T"` | `"T"` | `"T"` | +| `messaging.operation` | `"create"` | `"create"` | `"publish"` | +| `messaging.message.id` | `"a1"` | `"a2"` | | +| `messaging.message.envelope.size` | `1` | `1` | | +| `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md From e37eac79943586b6b4e18c8e0bb2d061d4850cb4 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Fri, 12 Jan 2024 14:01:13 -0300 Subject: [PATCH 323/482] Revert "Clarify that service.* conventions apply to all telemetry sources" (#638) --- CHANGELOG.md | 3 --- docs/resource/README.md | 4 ++-- model/resource/service.yaml | 7 +------ model/resource/service_experimental.yaml | 2 +- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dfe18a4a3..6f597bc797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,9 +23,6 @@ release. ### Fixes -- Clarify that `service.*` attributes apply to all telemetry sources. - ([#630](https://github.com/open-telemetry/semantic-conventions/pull/630)) - ## v1.24.0 (2023-12-15) ### Breaking diff --git a/docs/resource/README.md b/docs/resource/README.md index 1c0b63718f..a77cbd2f69 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -77,7 +77,7 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **type:** `service` -**Description:** A telemetry source. OpenTelemetry has adopted a broad interpretation such that every telemetry source is a service. Examples include, but are not limited to: web services, hosts, mobile applications, browser application, edge computing devices, functions as a service, databases, message brokers, etc. Specific types of telemetry sources may have additional conventions defining domain specific information, but the `service` conventions are applicable to all telemetry sources. +**Description:** A service instance. | Attribute | Type | Description | Examples | Requirement Level | @@ -94,7 +94,7 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **type:** `service` -**Description:** Experimental additions to service. +**Description:** Additions to service instance. | Attribute | Type | Description | Examples | Requirement Level | diff --git a/model/resource/service.yaml b/model/resource/service.yaml index fc3d3a6c52..05b2e02698 100644 --- a/model/resource/service.yaml +++ b/model/resource/service.yaml @@ -3,12 +3,7 @@ groups: prefix: service type: resource brief: > - A telemetry source. OpenTelemetry has adopted a broad interpretation such that every - telemetry source is a service. Examples include, but are not limited to: web services, - hosts, mobile applications, browser application, edge computing devices, functions as - a service, databases, message brokers, etc. Specific types of telemetry sources may have - additional conventions defining domain specific information, but the `service` - conventions are applicable to all telemetry sources. + A service instance. attributes: - id: name type: string diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index 9103ac7531..43c869ee35 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -3,7 +3,7 @@ groups: prefix: service type: resource brief: > - Experimental additions to service. + A service instance. attributes: - id: namespace type: string From 50e2eac498cf7b0e9d07148594350c67934550be Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Wed, 17 Jan 2024 17:25:10 +0100 Subject: [PATCH 324/482] Move messaging attributes in registry to system-specific sections (#643) --- docs/attributes-registry/messaging.md | 120 +++++++++++++++++--------- model/registry/messaging.yaml | 30 +++++++ 2 files changed, 109 insertions(+), 41 deletions(-) diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 626d8cc59f..c874710646 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -3,9 +3,19 @@ # Messaging -## Messaging Attributes + - +- [Generic Messaging Attributes](#generic-messaging-attributes) +- [GCP Pub/Sub Attributes](#gcp-pubsub-attributes) +- [Kafka Attributes](#kafka-attributes) +- [RabbitMQ Attributes](#rabbitmq-attributes) +- [RocketMQ Attributes](#rocketmq-attributes) + + + +## Generic Messaging Attributes + + | Attribute | Type | Description | Examples | |---|---|---|---| | `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | @@ -16,27 +26,11 @@ | `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | | `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | | `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | -| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | -| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | -| `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [5] | `myKey` | -| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | -| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | -| `messaging.message.body.size` | int | The size of the message body in bytes. [6] | `1439` | +| `messaging.message.body.size` | int | The size of the message body in bytes. [5] | `1439` | | `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | -| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [7] | `2738` | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | -| `messaging.operation` | string | A string identifying the kind of messaging operation. [8] | `publish` | -| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | -| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | -| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | -| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | -| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | -| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | -| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | -| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | -| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | -| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | +| `messaging.operation` | string | A string identifying the kind of messaging operation. [7] | `publish` | | `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -49,15 +43,13 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi **[4]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. -**[5]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. - -**[6]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[5]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[7]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[6]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[8]:** If a custom value is used, it MUST be of low cardinality. +**[7]:** If a custom value is used, it MUST be of low cardinality. `messaging.operation` 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. @@ -68,6 +60,67 @@ size should be used. | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | | `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +`messaging.system` 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 | +|---|---| +| `activemq` | Apache ActiveMQ | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | +| `azure_eventgrid` | Azure Event Grid | +| `azure_eventhubs` | Azure Event Hubs | +| `azure_servicebus` | Azure Service Bus | +| `gcp_pubsub` | Google Cloud Pub/Sub | +| `jms` | Java Message Service | +| `kafka` | Apache Kafka | +| `rabbitmq` | RabbitMQ | +| `rocketmq` | Apache RocketMQ | + + +## GCP Pub/Sub Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | + + +## Kafka Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | +| `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | +| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | +| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | + +**[1]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. + + +## RabbitMQ Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | + + +## RocketMQ Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | +| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | +| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | +| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | +| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | +| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | +| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | +| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | +| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | + `messaging.rocketmq.consumption_model` MUST be one of the following: | Value | Description | @@ -83,19 +136,4 @@ size should be used. | `fifo` | FIFO message | | `delay` | Delay message | | `transaction` | Transaction message | - -`messaging.system` 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 | -|---|---| -| `activemq` | Apache ActiveMQ | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `azure_eventgrid` | Azure Event Grid | -| `azure_eventhubs` | Azure Event Hubs | -| `azure_servicebus` | Azure Service Bus | -| `gcp_pubsub` | Google Cloud Pub/Sub | -| `jms` | Java Message Service | -| `kafka` | Apache Kafka | -| `rabbitmq` | RabbitMQ | -| `rocketmq` | Apache RocketMQ | diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index c7ba8fd457..6f638976a3 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -12,11 +12,13 @@ groups: When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. examples: [0, 1, 2] + tag: messaging-generic - id: client_id type: string brief: > A unique identifier for the client that consumes or produces a message. examples: ['client-5', 'myhost@8742@s8083jm'] + tag: messaging-generic - id: destination.name type: string brief: 'The message destination name' @@ -24,6 +26,7 @@ groups: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] + tag: messaging-generic - id: destination.template type: string brief: Low cardinality representation of the messaging destination name @@ -34,15 +37,19 @@ groups: the underlying template is of low cardinality and can be effectively used for grouping and aggregation. examples: ['/customers/{customerId}'] + tag: messaging-generic - id: destination.anonymous type: boolean brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' + tag: messaging-generic - id: destination.temporary type: boolean brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' + tag: messaging-generic - id: destination_publish.anonymous type: boolean brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' + tag: messaging-generic - id: destination_publish.name type: string brief: 'The name of the original destination the message was published to' @@ -50,17 +57,20 @@ groups: The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] + tag: messaging-generic - id: kafka.consumer.group type: string brief: > Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. examples: 'my-group' + tag: tech-specific-kafka - id: kafka.destination.partition type: int brief: > Partition the message is sent to. examples: 2 + tag: tech-specific-kafka - id: kafka.message.key type: string brief: > @@ -71,20 +81,24 @@ groups: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. examples: 'myKey' + tag: tech-specific-kafka - id: kafka.message.offset type: int brief: > The offset of a record in the corresponding Kafka partition. examples: 42 + tag: tech-specific-kafka - id: kafka.message.tombstone type: boolean brief: 'A boolean that is true if the message is a tombstone.' + tag: tech-specific-kafka - id: message.conversation_id type: string brief: > The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". examples: 'MyConversationId' + tag: messaging-generic - id: message.envelope.size type: int brief: > @@ -93,10 +107,12 @@ groups: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. examples: 2738 + tag: messaging-generic - id: message.id type: string brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' examples: '452a7c7c7c7048c2f887f61572b18fc2' + tag: messaging-generic - id: message.body.size type: int brief: > @@ -105,6 +121,7 @@ groups: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. examples: 1439 + tag: messaging-generic - id: operation type: allow_custom_values: true @@ -132,16 +149,19 @@ groups: brief: > A string identifying the kind of messaging operation. note: If a custom value is used, it MUST be of low cardinality. + tag: messaging-generic - id: rabbitmq.destination.routing_key type: string brief: > RabbitMQ message routing key. examples: 'myKey' + tag: tech-specific-rabbitmq - id: rocketmq.client_group type: string brief: > Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. examples: 'myConsumerGroup' + tag: tech-specific-rocketmq - id: rocketmq.consumption_model type: allow_custom_values: false @@ -154,31 +174,37 @@ groups: brief: 'Broadcasting consumption model' brief: > Model of message consumption. This only applies to consumer spans. + tag: tech-specific-rocketmq - id: rocketmq.message.delay_time_level type: int brief: > The delay time level for delay message, which determines the message delay time. examples: 3 + tag: tech-specific-rocketmq - id: rocketmq.message.delivery_timestamp type: int brief: > The timestamp in milliseconds that the delay message is expected to be delivered to consumer. examples: 1665987217045 + tag: tech-specific-rocketmq - id: rocketmq.message.group type: string brief: > It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. examples: 'myMessageGroup' + tag: tech-specific-rocketmq - id: rocketmq.message.keys type: string[] brief: > Key(s) of message, another way to mark message besides message id. examples: ['keyA', 'keyB'] + tag: tech-specific-rocketmq - id: rocketmq.message.tag type: string brief: > The secondary classifier of message besides topic. examples: tagA + tag: tech-specific-rocketmq - id: rocketmq.message.type type: allow_custom_values: false @@ -197,16 +223,19 @@ groups: brief: 'Transaction message' brief: > Type of message. + tag: tech-specific-rocketmq - id: rocketmq.namespace type: string brief: > Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' + tag: tech-specific-rocketmq - id: gcp_pubsub.message.ordering_key type: string brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' + tag: tech-specific-gcp-pubsub - id: system brief: > An identifier for the messaging system being used. See below for a list of well-known identifiers. @@ -243,3 +272,4 @@ groups: - id: rocketmq value: 'rocketmq' brief: 'Apache RocketMQ' + tag: messaging-generic From bb017fa80a23b25a05a02cc49b0dc715f9653a2e Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Wed, 17 Jan 2024 17:52:22 +0100 Subject: [PATCH 325/482] Remove obsolete footnotes for messaging attributes (#642) Co-authored-by: Joao Grassi --- docs/messaging/messaging-spans.md | 73 ++++++++++++++----------------- model/trace/messaging.yaml | 8 ---- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 7562e2972b..b80eec3a84 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -24,7 +24,6 @@ + [Producer spans](#producer-spans) + [Consumer spans](#consumer-spans) - [Messaging attributes](#messaging-attributes) - * [Attribute namespaces](#attribute-namespaces) * [Consumer attributes](#consumer-attributes) * [Per-message attributes](#per-message-attributes) * [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems) @@ -272,6 +271,19 @@ messages were received). For each message it accounts for, the "Deliver" or ## Messaging attributes +Messaging attributes are organized into the following namespaces: + +- `messaging.message`: Contains [per-message attributes](#per-message-attributes) that describe individual messages. Those attributes are relevant only for spans or links that represent a single message. +- `messaging.destination`: Contains attributes that describe the logical entity messages are published to. See [Destinations](#destinations) for more details. +- `messaging.destination_publish`: Contains attributes that describe the logical entity messages were originally published to. See [Destinations](#destinations) for more details. +- `messaging.batch`: Contains attributes that describe batch operations. +- `messaging.consumer`: Contains [consumer attributes](#consumer-attributes) that describe the application instance that consumes a message. See [consumer](#consumer) for more details. + +The communication with the intermediary is described with general [network attributes]. + +Messaging system-specific attributes MUST be defined in the corresponding `messaging.{system}` namespace +as described in [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems). + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| @@ -282,20 +294,20 @@ messages were received). For each message it accounts for, the "Deliver" or | [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | Conditionally Required: [7] | | [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | Conditionally Required: [9] | | [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [10] | -| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [11] | `1439` | Recommended: [12] | -| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended: [13] | -| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | Recommended: [15] | -| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended: [16] | -| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [17] | `publish` | Required | +| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [11] | `1439` | Recommended | +| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended | +| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended | +| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended | +| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [13] | `publish` | Required | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [18] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [19] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [20] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [21] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [22] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [23] | `80`; `8080`; `443` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [14] | `amqp`; `mqtt` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [15] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [16] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [17] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [18] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [19] | `80`; `8080`; `443` | Recommended | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -335,34 +347,26 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi **[11]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[12]:** Only if span represents operation on a single message. - -**[13]:** Only if span represents operation on a single message. - -**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[12]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[15]:** Only if span represents operation on a single message. +**[13]:** If a custom value is used, it MUST be of low cardinality. -**[16]:** Only for spans that represent an operation on a single message. +**[14]:** The value SHOULD be normalized to lowercase. -**[17]:** If a custom value is used, it MUST be of low cardinality. +**[15]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[18]:** The value SHOULD be normalized to lowercase. - -**[19]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - -**[20]:** The value SHOULD be normalized to lowercase. +**[16]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[21]:** The value SHOULD be normalized to lowercase. +**[17]:** The value SHOULD be normalized to lowercase. -**[22]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +**[18]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. -**[23]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[19]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. @@ -415,19 +419,6 @@ Additionally `server.port` from the [network attributes][] is recommended. Furthermore, it is strongly recommended to add the [`network.transport`][] attribute and follow its guidelines, especially for in-process queueing systems (like [Hangfire][], for example). These attributes should be set to the broker to which the message is sent/from which it is received. -### Attribute namespaces - -- `messaging.message`: Contains attributes that describe individual messages -- `messaging.destination`: Contains attributes that describe the logical entity messages are published to. See [Destinations](#destinations) for more details -- `messaging.destination_publish`: Contains attributes that describe the logical entity messages were originally published to. See [Destinations](#destinations) for more details -- `messaging.batch`: Contains attributes that describe batch operations -- `messaging.consumer`: Contains attributes that describe application instance that consumes a message. See [consumer](#consumer) for more details - -Communication with broker is described with general [network attributes]. - -Messaging system-specific attributes MUST be defined in the corresponding `messaging.{system}` namespace -as described in [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems). - [network attributes]: /docs/general/attributes.md#server-and-client-attributes [`network.transport`]: /docs/general/attributes.md#network-attributes [Hangfire]: https://www.hangfire.io/ diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index be7a4441c7..011ad09570 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -77,17 +77,9 @@ groups: requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. - ref: messaging.message.id - requirement_level: - recommended: Only for spans that represent an operation on a single message. - ref: messaging.message.conversation_id - requirement_level: - recommended: Only if span represents operation on a single message. - ref: messaging.message.envelope.size - requirement_level: - recommended: Only if span represents operation on a single message. - ref: messaging.message.body.size - requirement_level: - recommended: Only if span represents operation on a single message. - ref: server.address - ref: network.peer.address tag: connection-level From a41f0e8961860205f37e585443d4de3d12d25c2a Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 19 Jan 2024 05:28:12 -0500 Subject: [PATCH 326/482] [editorial] Fix/adjust link to use https rather than http (#645) --- docs/database/couchdb.md | 2 +- model/trace/database.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 6702a92b40..8025aacd08 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -19,7 +19,7 @@ described on this page. |---|---|---|---|---| | [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | Conditionally Required: If `db.statement` is not applicable. | -**[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). +**[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 9df75ee20f..a896527ac7 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -116,7 +116,7 @@ groups: the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): - [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). + [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). - id: db.redis type: span From d21135e07ce9ca1ba05581021aebe84cc1d27ee8 Mon Sep 17 00:00:00 2001 From: Braydon Kains <93549768+braydonk@users.noreply.github.com> Date: Tue, 23 Jan 2024 03:37:27 -0500 Subject: [PATCH 327/482] Generate process metrics with `semconv` yaml (#330) Co-authored-by: Joao Grassi --- .yamllint | 3 + CHANGELOG.md | 14 ++ docs/system/process-metrics.md | 220 ++++++++++++++++++++++++++--- model/metrics/process-metrics.yaml | 120 ++++++++++++++++ schema-next.yaml | 31 ++++ 5 files changed, 368 insertions(+), 20 deletions(-) create mode 100644 model/metrics/process-metrics.yaml diff --git a/.yamllint b/.yamllint index 39c91cefa1..70b17e868b 100644 --- a/.yamllint +++ b/.yamllint @@ -1,5 +1,8 @@ extends: default +ignore-from-file: + - .gitignore + rules: document-start: disable octal-values: enable diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f597bc797..16ab5dcee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,20 @@ release. ([#484](https://github.com/open-telemetry/semantic-conventions/pull/484)) - Depluralize labels for pod (`k8s.pod.labels.*`) and container (`container.labels.*`) resources ([#625](https://github.com/open-telemetry/semantic-conventions/pull/625)) +- BREAKING: Generate process metrics from YAML + ([#330](https://github.com/open-telemetry/semantic-conventions/pull/330)) + - Rename `process.threads` to `process.thread.count` + - Rename `process.open_file_descriptors` to `process.open_file_descriptor.count` + - Rename attributes for `process.cpu.*` + - `state` to `process.cpu.state` + - Change attributes for `process.disk.io` + - Instead of `direction` use `disk.io.direction` from global registry + - Change attributes for `process.network.io` + - Instead of `direction` use `network.io.direction` from global registry + - Rename attributes for `process.context_switches` + - `type` to `process.context_switch_type` + - Rename attributes for `process.paging.faults` + - `type` to `process.paging.fault_type` ### Features diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index c619763717..35e343349e 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -19,9 +19,17 @@ metrics](/docs/runtime/README.md#metrics). -- [Metric Instruments](#metric-instruments) - * [Process](#process) -- [Attributes](#attributes) +- [Process Metrics](#process-metrics) + * [Metric: `process.cpu.time`](#metric-processcputime) + * [Metric: `process.cpu.utilization`](#metric-processcpuutilization) + * [Metric: `process.memory.usage`](#metric-processmemoryusage) + * [Metric: `process.memory.virtual`](#metric-processmemoryvirtual) + * [Metric: `process.disk.io`](#metric-processdiskio) + * [Metric: `process.network.io`](#metric-processnetworkio) + * [Metric: `process.thread.count`](#metric-processthreadcount) + * [Metric: `process.open_file_descriptor.count`](#metric-processopen_file_descriptorcount) + * [Metric: `process.context_switches`](#metric-processcontext_switches) + * [Metric: `process.paging.faults`](#metric-processpagingfaults) @@ -35,27 +43,199 @@ metrics](/docs/runtime/README.md#metrics). > * SHOULD introduce a control mechanism to allow users to opt-in to the new > conventions once the migration plan is finalized. -## Metric Instruments +## Process Metrics -### Process +### Metric: `process.cpu.time` -Below is a table of Process metric instruments. +This metric is [recommended][MetricRecommended]. -| Name | Instrument Type ([\*](/docs/general/metrics.md#instrument-types)) | Unit | Description | Labels | -|---------------------------------|----------------------------------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `process.cpu.time` | Counter | s | Total CPU seconds broken down by different states. | `state`, if specified, SHOULD be one of: `system`, `user`, `wait`. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | -| `process.cpu.utilization` | Gauge | 1 | Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process. | `state`, if specified, SHOULD be one of: `system`, `user`, `wait`. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | -| `process.memory.usage` | UpDownCounter | By | The amount of physical memory in use. | | -| `process.memory.virtual` | UpDownCounter | By | The amount of committed virtual memory. | | -| `process.disk.io` | Counter | By | Disk bytes transferred. | `direction` SHOULD be one of: `read`, `write` | -| `process.network.io` | Counter | By | Network bytes transferred. | `direction` SHOULD be one of: `receive`, `transmit` | -| `process.threads` | UpDownCounter | {thread} | Process threads count. | | -| `process.open_file_descriptors` | UpDownCounter | {count} | Number of file descriptors in use by the process. | | -| `process.context_switches` | Counter | {count} | Number of times the process has been context switched. | `type` SHOULD be one of: `involuntary`, `voluntary` | -| `process.paging.faults` | Counter | {fault} | Number of page faults the process has made. | `type`, if specified, SHOULD be one of: `major` (for major, or hard, page faults), `minor` (for minor, or soft, page faults). | + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.cpu.time` | Counter | `s` | Total CPU seconds broken down by different states. | + -## Attributes + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | Recommended | -Process metrics SHOULD be associated with a [`process`](/docs/resource/process.md#process) resource whose attributes provide additional context about the process. +`process.cpu.state` 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 | +|---|---| +| `system` | system | +| `user` | user | +| `wait` | wait | + + +### Metric: `process.cpu.utilization` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.cpu.utilization` | Gauge | `1` | Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | Recommended | + +`process.cpu.state` 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 | +|---|---| +| `system` | system | +| `user` | user | +| `wait` | wait | + + +### Metric: `process.memory.usage` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.memory.usage` | UpDownCounter | `By` | The amount of physical memory in use. | + + + + + +### Metric: `process.memory.virtual` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.memory.virtual` | UpDownCounter | `By` | The amount of committed virtual memory. | + + + + + +### Metric: `process.disk.io` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.disk.io` | Counter | `By` | Disk bytes transferred. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | + +`disk.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +### Metric: `process.network.io` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.network.io` | Counter | `By` | Network bytes transferred. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | + +`network.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +### Metric: `process.thread.count` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.thread.count` | UpDownCounter | `{thread}` | Process threads count. | + + + + + +### Metric: `process.open_file_descriptor.count` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.open_file_descriptor.count` | UpDownCounter | `{count}` | Number of file descriptors in use by the process. | + + + + + +### Metric: `process.context_switches` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.context_switches` | Counter | `{count}` | Number of times the process has been context switched. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `process.context_switch_type` | string | Specifies whether the context switches for this data point were voluntary or involuntary. | `voluntary` | Recommended | + +`process.context_switch_type` 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 | +|---|---| +| `voluntary` | voluntary | +| `involuntary` | involuntary | + + +### Metric: `process.paging.faults` + +This metric is [recommended][MetricRecommended]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `process.paging.faults` | Counter | `{fault}` | Number of page faults the process has made. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| `process.paging.fault_type` | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major` | Recommended | + +`process.paging.fault_type` 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 | +|---|---| +| `major` | major | +| `minor` | minor | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended diff --git a/model/metrics/process-metrics.yaml b/model/metrics/process-metrics.yaml new file mode 100644 index 0000000000..cc663a9eaf --- /dev/null +++ b/model/metrics/process-metrics.yaml @@ -0,0 +1,120 @@ +groups: + - id: attributes.process.cpu + prefix: process.cpu + type: attribute_group + brief: "Attributes for process CPU metrics." + attributes: + - id: state + brief: "The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels." + type: + allow_custom_values: true + members: + - id: system + value: 'system' + - id: user + value: 'user' + - id: wait + value: 'wait' + + - id: metric.process.cpu.time + type: metric + metric_name: process.cpu.time + brief: "Total CPU seconds broken down by different states." + instrument: counter + unit: "s" + attributes: + - ref: process.cpu.state + + - id: metric.process.cpu.utilization + type: metric + metric_name: process.cpu.utilization + brief: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process." + instrument: gauge + unit: "1" + attributes: + - ref: process.cpu.state + + - id: metric.process.memory.usage + type: metric + metric_name: process.memory.usage + brief: "The amount of physical memory in use." + instrument: updowncounter + unit: "By" + attributes: [] + + - id: metric.process.memory.virtual + type: metric + metric_name: process.memory.virtual + brief: "The amount of committed virtual memory." + instrument: updowncounter + unit: "By" + attributes: [] + + - id: metric.process.disk.io + type: metric + metric_name: process.disk.io + prefix: process.disk + brief: "Disk bytes transferred." + instrument: counter + unit: "By" + attributes: + - ref: disk.io.direction + + - id: metric.process.network.io + type: metric + metric_name: process.network.io + brief: "Network bytes transferred." + instrument: counter + unit: "By" + attributes: + - ref: network.io.direction + + - id: metric.process.thread.count + type: metric + metric_name: process.thread.count + brief: "Process threads count." + instrument: updowncounter + unit: "{thread}" + attributes: [] + + - id: metric.process.open_file_descriptor.count + type: metric + metric_name: process.open_file_descriptor.count + brief: "Number of file descriptors in use by the process." + instrument: updowncounter + unit: "{count}" + attributes: [] + + - id: metric.process.context_switches + type: metric + metric_name: process.context_switches + brief: "Number of times the process has been context switched." + instrument: counter + unit: "{count}" + attributes: + - id: process.context_switch_type + brief: "Specifies whether the context switches for this data point were voluntary or involuntary." + type: + allow_custom_values: true + members: + - id: voluntary + value: 'voluntary' + - id: involuntary + value: 'involuntary' + + - id: metric.process.paging.faults + type: metric + metric_name: process.paging.faults + brief: "Number of page faults the process has made." + instrument: counter + unit: "{fault}" + attributes: + - id: process.paging.fault_type + brief: "The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults." + type: + allow_custom_values: true + members: + - id: major + value: 'major' + - id: minor + value: 'minor' diff --git a/schema-next.yaml b/schema-next.yaml index 58de42a543..23ebad9a35 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -18,6 +18,37 @@ versions: attribute_map: container.labels: container.label k8s.pod.labels: k8s.pod.label + # https://github.com/open-telemetry/semantic-conventions/pull/330 + - rename_metrics: + process.threads: process.thread.count + process.open_file_descriptors: process.open_file_descriptor.count + - rename_attributes: + attribute_map: + state: process.cpu.state + apply_to_metrics: + - process.cpu.time + - process.cpu.utilization + - rename_attributes: + attribute_map: + direction: disk.io.direction + apply_to_metrics: + - process.disk.io + - rename_attributes: + attribute_map: + type: process.context_switch_type + apply_to_metrics: + - process.context_switches + - rename_attributes: + attribute_map: + direction: network.io.direction + apply_to_metrics: + - process.network.io + - rename_attributes: + attribute_map: + type: process.paging.fault_type + apply_to_metrics: + - process.paging.faults + 1.24.0: metrics: changes: From c3e35ee7c72322a78220b739fcec6eae0dcc3622 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 24 Jan 2024 14:51:56 +0100 Subject: [PATCH 328/482] added remaining ECS fields to the useragent (#452) Co-authored-by: Trask Stalnaker --- CHANGELOG.md | 4 +++- docs/attributes-registry/user-agent.md | 6 ++++++ model/registry/user-agent.yaml | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16ab5dcee3..bd719ed32b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,8 +32,10 @@ release. - Add `azure_container_apps` to `cloud.platform` semantic conventions ([#615](https://github.com/open-telemetry/semantic-conventions/pull/615)) +- Add `user_agent.name` and `user_agent.version` attributes + ([#452](https://github.com/open-telemetry/semantic-conventions/pull/452/)) - Add an example for gcp_pubsub asynchronous batch publish - ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)). + ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)) ### Fixes diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md index 589f722f87..f75c5d22ce 100644 --- a/docs/attributes-registry/user-agent.md +++ b/docs/attributes-registry/user-agent.md @@ -8,5 +8,11 @@ | Attribute | Type | Description | Examples | |---|---|---|---| +| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name [1] | `Safari` | | `user_agent.original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | +| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2` | + +**[1]:** [Example](https://www.whatsmyua.info) of extracting browser's name from original string + +**[2]:** [Example](https://www.whatsmyua.info) of extracting browser's version from original string diff --git a/model/registry/user-agent.yaml b/model/registry/user-agent.yaml index 0fbc5c9f2a..29e00ff6bc 100644 --- a/model/registry/user-agent.yaml +++ b/model/registry/user-agent.yaml @@ -11,3 +11,17 @@ groups: Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. examples: ['CERN-LineMode/2.15 libwww/2.17b3', 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] + - id: name + type: string + brief: > + Name of the user-agent extracted from original. Usually refers to the browser's name + examples: ['Safari'] + note: > + [Example](https://www.whatsmyua.info) of extracting browser's name from original string + - id: version + type: string + brief: > + Version of the user-agent extracted from original. Usually refers to the browser's version + examples: ['14.1.2'] + note: > + [Example](https://www.whatsmyua.info) of extracting browser's version from original string From dd41eac32f6bb391f49bd7e4deab5356b1a5505e Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Wed, 24 Jan 2024 15:57:19 +0100 Subject: [PATCH 329/482] Make `network.protocol.name` conditionally required for messaging (#644) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/messaging/messaging-metrics.md | 16 +++++++++------- docs/messaging/messaging-spans.md | 24 +++++++++++++----------- model/messaging-common.yaml | 2 ++ 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd719ed32b..86d2bb5ec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ release. ([#484](https://github.com/open-telemetry/semantic-conventions/pull/484)) - Depluralize labels for pod (`k8s.pod.labels.*`) and container (`container.labels.*`) resources ([#625](https://github.com/open-telemetry/semantic-conventions/pull/625)) +- Make `network.protocol.name` conditionally required for messaging + ([#644](https://github.com/open-telemetry/semantic-conventions/pull/644)) - BREAKING: Generate process metrics from YAML ([#330](https://github.com/open-telemetry/semantic-conventions/pull/330)) - Rename `process.threads` to `process.thread.count` diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index b2f7046bdd..d2fbda03dc 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -29,10 +29,10 @@ All messaging metrics share the same set of attributes: | [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | Conditionally Required: [4] | | [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | Conditionally Required: if available. | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `3.1.1` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `amqp`; `mqtt` | Conditionally Required: [7] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [8] | `3.1.1` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [10] | `80`; `8080`; `443` | Recommended | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -61,11 +61,13 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi **[6]:** The value SHOULD be normalized to lowercase. -**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[7]:** Only for messaging systems and frameworks that support more than one protocol. -**[8]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +**[8]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. -**[9]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[9]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + +**[10]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index b80eec3a84..f6d647a9bf 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -302,12 +302,12 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [14] | `amqp`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [15] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [16] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [17] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [18] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [19] | `80`; `8080`; `443` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [14] | `amqp`; `mqtt` | Conditionally Required: [15] | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [16] | `3.1.1` | Recommended | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [18] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [19] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [20] | `80`; `8080`; `443` | Recommended | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -354,19 +354,21 @@ size should be used. **[14]:** The value SHOULD be normalized to lowercase. -**[15]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[15]:** Only for messaging systems and frameworks that support more than one protocol. -**[16]:** The value SHOULD be normalized to lowercase. +**[16]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[17]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[17]:** The value SHOULD be normalized to lowercase. +**[18]:** The value SHOULD be normalized to lowercase. -**[18]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. +**[19]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. -**[19]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[20]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. diff --git a/model/messaging-common.yaml b/model/messaging-common.yaml index 07ef5f4a78..92bddd7924 100644 --- a/model/messaging-common.yaml +++ b/model/messaging-common.yaml @@ -18,6 +18,8 @@ groups: - ref: server.port - ref: network.protocol.name examples: ['amqp', 'mqtt'] + requirement_level: + conditionally_required: Only for messaging systems and frameworks that support more than one protocol. tag: connection-level - ref: network.protocol.version tag: connection-level From 3f30d418f86af82a908a8437bd8b03a42d5adf79 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Wed, 24 Jan 2024 19:57:37 +0100 Subject: [PATCH 330/482] Add stale bot workflow (#668) --- .github/workflows/stale-pr.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/stale-pr.yml diff --git a/.github/workflows/stale-pr.yml b/.github/workflows/stale-pr.yml new file mode 100644 index 0000000000..e463791fa9 --- /dev/null +++ b/.github/workflows/stale-pr.yml @@ -0,0 +1,17 @@ +name: "Close stale spull requests" +on: + schedule: + - cron: "12 3 * * *" # arbitrary time not to DDOS GitHub + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' + close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' + exempt-pr-labels: 'release:after-ga' + days-before-stale: 15 + days-before-close: 7 From fa0725719bcfbab57fa17961faef5f9448d20828 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 25 Jan 2024 07:27:35 -0800 Subject: [PATCH 331/482] (editorial) Update http.resend_count references to http.request.resend_count (#666) Co-authored-by: Joao Grassi --- docs/http/http-spans.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 1193cf2cb0..9ed7173c1b 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -277,7 +277,7 @@ Retries and redirects cause more than one physical HTTP request to be sent. A request is resent when an HTTP client library sends more than one HTTP request to satisfy the same API call. This may happen due to following redirects, authorization challenges, 503 Server Unavailable, network issues, or any other. -Each time an HTTP request is resent, the `http.resend_count` attribute SHOULD be added to each repeated span and set to the ordinal number of the request resend attempt. +Each time an HTTP request is resent, the `http.request.resend_count` attribute SHOULD be added to each repeated span and set to the ordinal number of the request resend attempt. See the examples for more details about: @@ -433,11 +433,11 @@ request (SERVER, trace=t1, span=s1) | | | --- server (SERVER, trace=t1, span=s3) | - -- GET / - 500 (CLIENT, trace=t1, span=s4, http.resend_count=1) + -- GET / - 500 (CLIENT, trace=t1, span=s4, http.request.resend_count=1) | | | --- server (SERVER, trace=t1, span=s5) | - -- GET / - 200 (CLIENT, trace=t1, span=s6, http.resend_count=2) + -- GET / - 200 (CLIENT, trace=t1, span=s6, http.request.resend_count=2) | --- server (SERVER, trace=t1, span=s7) ``` @@ -449,11 +449,11 @@ GET / - 500 (CLIENT, trace=t1, span=s1) | --- server (SERVER, trace=t1, span=s2) -GET / - 500 (CLIENT, trace=t2, span=s1, http.resend_count=1) +GET / - 500 (CLIENT, trace=t2, span=s1, http.request.resend_count=1) | --- server (SERVER, trace=t2, span=s2) -GET / - 200 (CLIENT, trace=t3, span=s1, http.resend_count=2) +GET / - 200 (CLIENT, trace=t3, span=s1, http.request.resend_count=2) | --- server (SERVER, trace=t3, span=s1) ``` @@ -469,7 +469,7 @@ request (SERVER, trace=t1, span=s1) | | | --- server (SERVER, trace=t1, span=s3) | - -- GET /hello - 200 (CLIENT, trace=t1, span=s4, http.resend_count=1) + -- GET /hello - 200 (CLIENT, trace=t1, span=s4, http.request.resend_count=1) | --- server (SERVER, trace=t1, span=s5) ``` @@ -481,7 +481,7 @@ GET /hello - 401 (CLIENT, trace=t1, span=s1) | --- server (SERVER, trace=t1, span=s2) -GET /hello - 200 (CLIENT, trace=t2, span=s1, http.resend_count=1) +GET /hello - 200 (CLIENT, trace=t2, span=s1, http.request.resend_count=1) | --- server (SERVER, trace=t2, span=s2) ``` @@ -497,7 +497,7 @@ request (SERVER, trace=t1, span=s1) | | | --- server (SERVER, trace=t1, span=s3) | - -- GET /hello - 200 (CLIENT, trace=t1, span=s4, http.resend_count=1) + -- GET /hello - 200 (CLIENT, trace=t1, span=s4, http.request.resend_count=1) | --- server (SERVER, trace=t1, span=s5) ``` @@ -509,7 +509,7 @@ GET / - 302 (CLIENT, trace=t1, span=s1) | --- server (SERVER, trace=t1, span=s2) -GET /hello - 200 (CLIENT, trace=t2, span=s1, http.resend_count=1) +GET /hello - 200 (CLIENT, trace=t2, span=s1, http.request.resend_count=1) | --- server (SERVER, trace=t2, span=s2) ``` From 3beb6cd937229329fd9bbf573a9f8c375be0b535 Mon Sep 17 00:00:00 2001 From: Marcin Kielar Date: Tue, 30 Jan 2024 11:50:38 +0100 Subject: [PATCH 332/482] Improvements for AWS/ECS attributes (#597) Co-authored-by: Pablo Baeyens Co-authored-by: Joao Grassi --- CHANGELOG.md | 2 ++ docs/resource/cloud-provider/aws/ecs.md | 7 ++++--- model/resource/cloud_provider/aws/ecs.yaml | 18 ++++++++++++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d2bb5ec2..7b6146e03f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ release. ([#452](https://github.com/open-telemetry/semantic-conventions/pull/452/)) - Add an example for gcp_pubsub asynchronous batch publish ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)) +- Add `aws.ecs.task.id` attribute, corrected description for `aws.ecs.task.arn`. + ([#597](https://github.com/open-telemetry/semantic-conventions/pull/597)) ### Fixes diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index 362b66dde9..2edafe56b9 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -12,9 +12,10 @@ | `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | Recommended | | `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | Recommended | | `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | Recommended | -| `aws.ecs.task.arn` | string | The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b` | Recommended | -| `aws.ecs.task.family` | string | The task definition family this task definition is a member of. | `opentelemetry-family` | Recommended | -| `aws.ecs.task.revision` | string | The revision for this task definition. | `8`; `26` | Recommended | +| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | Recommended | +| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | Recommended | +| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | Conditionally Required: If and only if `task.arn` is populated. | +| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | Recommended | `aws.ecs.launchtype` MUST be one of the following: diff --git a/model/resource/cloud_provider/aws/ecs.yaml b/model/resource/cloud_provider/aws/ecs.yaml index 2c6b8c9ba5..a40f950c18 100644 --- a/model/resource/cloud_provider/aws/ecs.yaml +++ b/model/resource/cloud_provider/aws/ecs.yaml @@ -28,15 +28,25 @@ groups: - id: task.arn type: string brief: > - The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). - examples: ['arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'] + The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). + examples: [ + 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b', + 'arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' + ] - id: task.family type: string brief: > - The task definition family this task definition is a member of. + The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. examples: ['opentelemetry-family'] + - id: task.id + type: string + brief: > + The ID of a running ECS task. The ID MUST be extracted from `task.arn`. + requirement_level: + conditionally_required: If and only if `task.arn` is populated. + examples: [ '10838bed-421f-43ef-870a-f43feacbbb5b', '23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' ] - id: task.revision type: string brief: > - The revision for this task definition. + The revision for the task definition used to create the ECS task. examples: ["8", "26"] From 4266051473ab56209104ff4106961665c4fe86e9 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 31 Jan 2024 10:55:34 -0500 Subject: [PATCH 333/482] [editorial] Use canonical wikipedia links (#678) --- docs/cloudevents/cloudevents-spans.md | 2 +- docs/system/hardware-metrics.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 4064262d1d..1236b745ad 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -40,7 +40,7 @@ document. A CloudEvent can be sent directly from producer to consumer. For such a scenario, the traditional parent-child trace model works well. However, CloudEvents are also used in distributed systems where an event -can go through many [hops]() +can go through many [hops](https://en.wikipedia.org/wiki/Hop_%28networking%29) until it reaches a consumer. In this scenario, the traditional parent-child trace model is not sufficient to produce a meaningful trace. diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index 09ba773b65..a5c9f8ac01 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -309,7 +309,7 @@ Additional **Recommended** attributes: | | | | | | `hw.type` (**Required**) | `physical_disk` | | `hw.physical_disk.endurance_utilization` | Endurance remaining for this SSD disk | 1 | Gauge | Double | `state` (**Required**) | `remaining` | | `hw.physical_disk.size` | Size of the disk | By | UpDownCounter | Int64 | | | -| `hw.physical_disk.smart` | Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) attribute | 1 | Gauge | Int | `smart_attribute` (Recommended) | `Seek Error Rate`, `Spin Retry Count`, etc. | +| `hw.physical_disk.smart` | Value of the corresponding [S.M.A.R.T.](https://en.wikipedia.org/wiki/S.M.A.R.T.) attribute | 1 | Gauge | Int | `smart_attribute` (Recommended) | `Seek Error Rate`, `Spin Retry Count`, etc. | | `hw.status` | Operational status: `1` (true) or `0` (false) for each of the possible states | | UpDownCounter | Int | `state` (**Required**) | `ok`, `degraded`, `failed`, `predicted_failure` | | | | | | | `hw.type` (**Required**) | `physical_disk` | From 13a8238b4dcdd4261751b16012edef6388654f86 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 1 Feb 2024 08:40:35 -0800 Subject: [PATCH 334/482] Define additional Azure messaging attributes (#572) --- CHANGELOG.md | 2 ++ docs/attributes-registry/messaging.md | 28 ++++++++++++++-- docs/messaging/azure-messaging.md | 43 ++++++++++++++++++++++++ docs/messaging/messaging-metrics.md | 6 ++-- docs/messaging/messaging-spans.md | 6 ++-- model/registry/messaging.yaml | 48 +++++++++++++++++++++++---- model/trace/messaging.yaml | 26 +++++++++++++++ 7 files changed, 144 insertions(+), 15 deletions(-) create mode 100644 docs/messaging/azure-messaging.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b6146e03f..ed085131b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ release. ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)) - Add `aws.ecs.task.id` attribute, corrected description for `aws.ecs.task.arn`. ([#597](https://github.com/open-telemetry/semantic-conventions/pull/597)) +- Add Azure Service Bus and Event Hubs messaging attributes + ([#572](https://github.com/open-telemetry/semantic-conventions/pull/572)) ### Fixes diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index c874710646..2ec5ad6c2d 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -10,6 +10,8 @@ - [Kafka Attributes](#kafka-attributes) - [RabbitMQ Attributes](#rabbitmq-attributes) - [RocketMQ Attributes](#rocketmq-attributes) +- [Azure Event Hubs Attributes](#azure-event-hubs-attributes) +- [Azure Service Bus Attributes](#azure-service-bus-attributes) @@ -66,9 +68,9 @@ size should be used. |---|---| | `activemq` | Apache ActiveMQ | | `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `azure_eventgrid` | Azure Event Grid | -| `azure_eventhubs` | Azure Event Hubs | -| `azure_servicebus` | Azure Service Bus | +| `eventgrid` | Azure Event Grid | +| `eventhubs` | Azure Event Hubs | +| `servicebus` | Azure Service Bus | | `gcp_pubsub` | Google Cloud Pub/Sub | | `jms` | Java Message Service | | `kafka` | Apache Kafka | @@ -137,3 +139,23 @@ size should be used. | `delay` | Delay message | | `transaction` | Transaction message | + +## Azure Event Hubs Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | +| `messaging.eventhubs.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. | `1` | +| `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | + + +## Azure Service Bus Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | +| `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | +| `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | + diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md new file mode 100644 index 0000000000..35e17ec2c3 --- /dev/null +++ b/docs/messaging/azure-messaging.md @@ -0,0 +1,43 @@ + + +# Semantic Conventions for Azure Messaging systems + +**Status**: [Experimental][DocumentStatus] + +The Semantic Conventions for [Azure Service Bus](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-messaging-overview) and [Azure Event Hubs](https://learn.microsoft.com/azure/event-hubs/event-hubs-about) extend and override the [Messaging Semantic Conventions](README.md) that describe common messaging operations attributes in addition to the Semantic Conventions described on this page. + +## Azure Service Bus + +`messaging.system` MUST be set to `"servicebus"`. + +### Span attributes + +The following additional attributes are defined: + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`messaging.servicebus.destination.subscription_name`](../attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | Conditionally Required: If messages are received from the subscription. | +| [`messaging.servicebus.message.delivery_count`](../attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | Conditionally Required: [1] | +| [`messaging.servicebus.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | + +**[1]:** If delivery count is available and is bigger than 0. + + +## Azure Event Hubs + +`messaging.system` MUST be set to `"eventhubs"`. + +### Span attributes + +The following additional attributes are defined: + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | Conditionally Required: If not default ("$Default"). | +| [`messaging.eventhubs.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. | `1` | Conditionally Required: If available. | +| [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index d2fbda03dc..dc9d1ef9b0 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -81,9 +81,9 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi |---|---| | `activemq` | Apache ActiveMQ | | `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `azure_eventgrid` | Azure Event Grid | -| `azure_eventhubs` | Azure Event Hubs | -| `azure_servicebus` | Azure Service Bus | +| `eventgrid` | Azure Event Grid | +| `eventhubs` | Azure Event Hubs | +| `servicebus` | Azure Service Bus | | `gcp_pubsub` | Google Cloud Pub/Sub | | `jms` | Java Message Service | | `kafka` | Apache Kafka | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index f6d647a9bf..19db054994 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -391,9 +391,9 @@ different processes could be listening on TCP port 12345 and UDP port 12345. |---|---| | `activemq` | Apache ActiveMQ | | `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `azure_eventgrid` | Azure Event Grid | -| `azure_eventhubs` | Azure Event Hubs | -| `azure_servicebus` | Azure Service Bus | +| `eventgrid` | Azure Event Grid | +| `eventhubs` | Azure Event Hubs | +| `servicebus` | Azure Service Bus | | `gcp_pubsub` | Google Cloud Pub/Sub | | `jms` | Java Message Service | | `kafka` | Apache Kafka | diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 6f638976a3..868df05065 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -248,14 +248,14 @@ groups: - id: aws_sqs value: 'aws_sqs' brief: 'Amazon Simple Queue Service (SQS)' - - id: azure_eventgrid - value: 'azure_eventgrid' + - id: eventgrid + value: 'eventgrid' brief: 'Azure Event Grid' - - id: azure_eventhubs - value: 'azure_eventhubs' + - id: eventhubs + value: 'eventhubs' brief: 'Azure Event Hubs' - - id: azure_servicebus - value: 'azure_servicebus' + - id: servicebus + value: 'servicebus' brief: 'Azure Service Bus' - id: gcp_pubsub value: 'gcp_pubsub' @@ -273,3 +273,39 @@ groups: value: 'rocketmq' brief: 'Apache RocketMQ' tag: messaging-generic + - id: servicebus.message.delivery_count + type: int + brief: > + Number of deliveries that have been attempted for this message. + examples: 2 + tag: tech-specific-servicebus + - id: servicebus.message.enqueued_time + type: int + brief: > + The UTC epoch seconds at which the message has been accepted and stored in the entity. + examples: 1701393730 + tag: tech-specific-servicebus + - id: servicebus.destination.subscription_name + type: string + brief: > + The name of the subscription in the topic messages are received from. + examples: "mySubscription" + tag: tech-specific-servicebus + - id: eventhubs.message.enqueued_time + type: int + brief: > + The UTC epoch seconds at which the message has been accepted and stored in the entity. + examples: 1701393730 + tag: tech-specific-eventhubs + - id: eventhubs.destination.partition.id + type: string + brief: > + The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. + examples: '1' + tag: tech-specific-eventhubs + - id: eventhubs.consumer.group + type: string + brief: > + The name of the consumer group the event consumer is associated with. + examples: 'indexer' + tag: tech-specific-eventhubs diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 011ad09570..cc980de321 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -164,3 +164,29 @@ groups: tag: tech-specific-gcp-pubsub requirement_level: conditionally_required: If the message type has an ordering key set. + - id: messaging.servicebus + type: attribute_group + extends: messaging + brief: > + Attributes for Azure Service Bus + attributes: + - ref: messaging.servicebus.message.delivery_count + requirement_level: + conditionally_required: If delivery count is available and is bigger than 0. + - ref: messaging.servicebus.message.enqueued_time + - ref: messaging.servicebus.destination.subscription_name + requirement_level: + conditionally_required: If messages are received from the subscription. + - id: messaging.eventhubs + type: attribute_group + extends: messaging + brief: > + Attributes for Azure Event Hubs + attributes: + - ref: messaging.eventhubs.message.enqueued_time + - ref: messaging.eventhubs.destination.partition.id + requirement_level: + conditionally_required: If available. + - ref: messaging.eventhubs.consumer.group + requirement_level: + conditionally_required: If not default ("$Default"). From 482cb01c4598429c65dd0b123b30259f41b360cb Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 2 Feb 2024 05:03:14 -0800 Subject: [PATCH 335/482] [Editorial] Add missing stable status markers (#682) --- docs/runtime/jvm-metrics.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 7c913815e2..780c15afd3 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -188,6 +188,8 @@ of `[ 0.01, 0.1, 1, 10 ]`. ## JVM Threads +**Status**: [Stable][DocumentStatus] + **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.thread.*` ### Metric: `jvm.thread.count` @@ -228,6 +230,8 @@ Note that this is the number of platform threads (as opposed to virtual threads) ## JVM Classes +**Status**: [Stable][DocumentStatus] + **Description:** Java Virtual Machine (JVM) metrics captured under the namespace `jvm.class.*` ### Metric: `jvm.class.loaded` From 379db81270cd598e90e532a574644f33d0c94ce9 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 5 Feb 2024 16:41:55 +0100 Subject: [PATCH 336/482] Use `chloggen` go tool for managing the changelog (#637) --- .chloggen/TEMPLATE.yaml | 21 +++ .chloggen/config.yaml | 24 +++ .github/PULL_REQUEST_TEMPLATE.md | 3 +- .github/workflows/changelog.yml | 88 +++++++++++ CHANGELOG.md | 10 +- CONTRIBUTING.md | 244 +++++++++++++++++++++++-------- Makefile | 25 ++++ internal/tools/go.mod | 5 +- internal/tools/go.sum | 27 ++++ internal/tools/tools.go | 2 + 10 files changed, 384 insertions(+), 65 deletions(-) create mode 100644 .chloggen/TEMPLATE.yaml create mode 100644 .chloggen/config.yaml create mode 100644 .github/workflows/changelog.yml diff --git a/.chloggen/TEMPLATE.yaml b/.chloggen/TEMPLATE.yaml new file mode 100644 index 0000000000..4387154dd4 --- /dev/null +++ b/.chloggen/TEMPLATE.yaml @@ -0,0 +1,21 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.chloggen/config.yaml b/.chloggen/config.yaml new file mode 100644 index 0000000000..411f32d3a5 --- /dev/null +++ b/.chloggen/config.yaml @@ -0,0 +1,24 @@ +# The directory that stores individual changelog entries. +# Each entry is stored in a dedicated yaml file. +# - 'make chlog-new' will copy the 'template_yaml' to this directory as a new entry file. +# - 'make chlog-validate' will validate that all entry files are valid. +# - 'make chlog-update' will read and delete all entry files in this directory, and update 'changelog_md'. + +# Specify as relative path from root of repo. +# (Optional) Default: .chloggen +entries_dir: .chloggen + +# This file is used as the input for individual changelog entries. +# Specify as relative path from root of repo. +# (Optional) Default: .chloggen/TEMPLATE.yaml +template_yaml: .chloggen/TEMPLATE.yaml + +# The CHANGELOG file or files to which 'chloggen update' will write new entries +# (Optional) Default filename: CHANGELOG.md +change_logs: + user: CHANGELOG.md + +# The default change_log or change_logs to which an entry should be added. +# If 'change_logs' is specified in this file, and no value is specified for 'default_change_logs', +# then 'change_logs' MUST be specified in every entry file. +default_change_logs: [user] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 40f8193207..0ea068d59c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,5 +9,6 @@ Note: if the PR is touching an area that is not listed in the [existing areas](h ## Merge requirement checklist * [ ] [CONTRIBUTING.md](https://github.com/open-telemetry/semantic-conventions/blob/main/CONTRIBUTING.md) guidelines followed. -* [ ] [CHANGELOG.md](https://github.com/open-telemetry/semantic-conventions/blob/main/CHANGELOG.md) updated for non-trivial changes. +* [ ] Change log entry added, according to the guidelines in [When to add a changelog entry](https://github.com/open-telemetry/semantic-conventions/blob/main/CONTRIBUTING.md#when-to-add-a-changelog-entry). + * If your PR does not need a change log, start the PR title with `[chore]` * [ ] [schema-next.yaml](https://github.com/open-telemetry/semantic-conventions/blob/main/schema-next.yaml) updated with changes to existing conventions. diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000000..a5a390b69d --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,88 @@ +# This action requires that any PR targeting the main branch should touch at +# least one CHANGELOG file. If a CHANGELOG entry is not required, add the "Skip +# Changelog" label to disable this action. + +name: 'Changelog' + +on: + pull_request: + types: [opened, ready_for_review, synchronize, reopened, labeled, unlabeled] + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: true + +jobs: + changelog: + runs-on: ubuntu-latest + if: >- + ${{ + !contains(github.event.pull_request.labels.*.name, 'dependencies') && + !contains(github.event.pull_request.labels.*.name, 'Skip Changelog') && + !contains(github.event.pull_request.title, '[chore]') + }} + env: + PR_HEAD: ${{ github.event.pull_request.head.sha }} + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: ~1.21.6 + - name: Cache Go + id: go-cache + uses: actions/cache@v3 + with: + path: | + ~/go/bin + ~/go/pkg/mod + key: changelog-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + + - name: Ensure no changes to the CHANGELOG.md + run: | + if [[ $(git diff --name-only $(git merge-base origin/main $PR_HEAD) $PR_HEAD ./CHANGELOG*.md) ]] + then + echo "CHANGELOG.md should not be directly modified." + echo "Please add a .yaml file to the ./.chloggen/ directory." + echo "See CONTRIBUTING.md for more details." + echo "Alternately, add either \"[chore]\" to the title of the pull \ request or add the \"Skip Changelog\" label if this job should be skipped." + false + else + echo "CHANGELOG.md was not modified." + fi + + - name: Ensure ./.chloggen/*.yaml addition(s) + run: | + if [[ 1 -gt $(git diff --diff-filter=A --name-only $(git merge-base origin/main $PR_HEAD) $PR_HEAD ./.chloggen | grep -c \\.yaml) ]] + then + echo "No changelog entry was added to the ./.chloggen/ directory." + echo "Please add a .yaml file to the ./.chloggen/ directory." + echo "See CONTRIBUTING.md for more details." + echo "Alternately, add either \"[chore]\" to the title of the pull request or add the \"Skip Changelog\" label if this job should be skipped." + false + else + echo "A changelog entry was added to the ./.chloggen/ directory." + fi + + - name: Validate ./.chloggen/*.yaml changes + run: | + make chlog-validate \ + || { echo "New ./.chloggen/*.yaml file failed validation."; exit 1; } + + # In order to validate any links in the yaml file, render the config to markdown + - name: Render .chloggen changelog entries + run: make chlog-preview > changelog_preview.md + - name: Install markdown-link-check + run: npm install -g markdown-link-check + - name: Run markdown-link-check + run: | + markdown-link-check \ + --verbose \ + --config .markdown_link_check_config.json \ + changelog_preview.md \ + || { echo "Check that anchor links are lowercase"; exit 1; } diff --git a/CHANGELOG.md b/CHANGELOG.md index ed085131b0..627a6650f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ + + # Changelog -Please update changelog as part of any significant pull request. Place short -description of your change into "Unreleased" section. As part of release process -content of "Unreleased" section content will generate release notes for the -release. + ## Unreleased diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0bfa90bc98..abde6789cc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,38 @@ Before you start - see OpenTelemetry general [contributing](https://github.com/open-telemetry/community/blob/main/CONTRIBUTING.md) requirements and recommendations. +
+Table of Contents + + + +- [Sign the CLA](#sign-the-cla) +- [How to Contribute](#how-to-contribute) + * [Prerequisites](#prerequisites) + * [1. Modify the YAML model](#1-modify-the-yaml-model) + + [Schema files](#schema-files) + * [2. Update the markdown files](#2-update-the-markdown-files) + + [Hugo frontmatter](#hugo-frontmatter) + * [3. Verify the changes before committing](#3-verify-the-changes-before-committing) + * [4. Changelog](#4-changelog) + + [When to add a Changelog Entry](#when-to-add-a-changelog-entry) + - [Examples](#examples) + + [Adding a Changelog Entry](#adding-a-changelog-entry) + * [5. Getting your PR merged](#5-getting-your-pr-merged) +- [Automation](#automation) + * [Consistency Checks](#consistency-checks) + * [Auto formatting](#auto-formatting) + * [Markdown style](#markdown-style) + * [Misspell check](#misspell-check) + * [Markdown link check](#markdown-link-check) +- [Updating the referenced specification version](#updating-the-referenced-specification-version) +- [Making a Release](#making-a-release) +- [Merging existing ECS conventions](#merging-existing-ecs-conventions) + + + +
+ ## Sign the CLA Before you can contribute, you will need to sign the [Contributor License @@ -18,31 +50,70 @@ key, but non-obvious, aspects: - All attributes, metrics, etc. are formally defined in YAML files under the `model/` directory. -- All descriptions, normative language are defined in the `docs/` - directory. - - We provide tooling to generate Markdown documentation from the formal - YAML definitons. See [Yaml to Markdown](#yaml-to-markdown). - - We use Hugo to render [semantic conventions on our website](https://opentelemetry.io/docs/specs/semconv/). - You will see ` ``` -When creating new pages, you should provide the `linkTitle` attribute. This is used -to generate the navigation bar on the website, and will be listed relative to the -"parent" document. +When creating new markdown files, you should provide the `linkTitle` attribute. +This is used to generate the navigation bar on the website, +and will be listed relative to the "parent" document. -## Automation +### 3. Verify the changes before committing -Semantic Conventions provides a set of automated tools for general development. +Before sending a PR with your changes, make sure to run the automated checks: -### Consistency Checks +```bash +make check +``` -The Specification has a number of tools it uses to check things like style, -spelling and link validity. Before using the tools: +Alternatively, you can run each check individually. +Refer to the [Automation](#automation) section for more details. -- Install the latest LTS release of **[Node](https://nodejs.org/)**. - For example, using **[nvm][]** under Linux run: +### 4. Changelog - ```bash - nvm install --lts - ``` +#### When to add a Changelog Entry -- Install tooling packages: +Pull requests that contain user-facing changes will require a changelog entry. +Keep in mind the following types of users (not limited to): - ```bash - npm install - ``` +1. Those who are consuming the data following these conventions (e.g., in alerts, dashboards, queries) +2. Those who are using the conventions in instrumentations (e.g., library authors) +3. Those who are using the conventions to derive heuristics, predictions and automatic analyses (e.g., observability products/back-ends) + +If a changelog entry is not required (e.g. editorial or trivial changes), +a maintainer or approver will add the `Skip Changelog` label to the pull request. + +##### Examples + +Changelog entry required: + +- Any modification to existing conventions with change in functionality/behavior +- New semantic conventions +- Changes on definitions, normative language (in `/docs`) + +No changelog entry: + +- Typical documentation/editorial updates (e.g. grammar fixes, restructuring) +- Changes in internal tooling (e.g. make file, GH actions, etc) +- Refactorings with no meaningful change in functionality +- Chores, such as enabling linters, updating dependencies + +#### Adding a Changelog Entry + +The [CHANGELOG.md](./CHANGELOG.md) files in this repo is autogenerated +from `.yaml` files in the [/.chloggen](/.chloggen) directory. + +Your pull request should add a new `.yaml` file to this directory. +The name of your file can be arbitrary but must be unique since the last release. + +During the release process, all `./chloggen/*.yaml` files are transcribed into +`CHANGELOG.md` and then deleted. + +1. Create an entry file using `make chlog-new`. The command generates a new file, + with its name based on the current branch (e.g. `./.chloggen/my-feature-xyz.yaml`) +2. Fill in all the fields in the generated file +3. The value for the `component` field MUST match a filename (without type) in the + [registry](https://github.com/open-telemetry/semantic-conventions/tree/main/model/registry) + (e.g. `browser`, `http`) +4. Run `make chlog-validate` to ensure the new file is valid +5. Commit and push the file + +Alternately, copy `./.chloggen/TEMPLATE.yaml`, or just create your file from scratch. + +### 5. Getting your PR merged + +A PR (pull request) is considered to be **ready to merge** when: + +- It has received at least two approvals from the [code + owners](./.github/CODEOWNERS) (if approvals are from only one company, they + won't count) +- There is no `request changes` from the [code owners](./.github/CODEOWNERS) +- There is no open discussions +- It has been at least two working days since the last modification (except for + the trivial updates, such like typo, cosmetic, rebase, etc.). This gives + people reasonable time to review +- Trivial changes (typos, cosmetic changes, CI improvements, etc.) don't have to + wait for two days + +Any [maintainer](./README.md#contributing) can merge the PR once it is **ready +to merge**. + +## Automation + +Semantic Conventions provides a set of automated tools for general development. + +### Consistency Checks + +The Specification has a number of tools it uses to check things like style, +spelling and link validity. You can perform all checks locally using this command: @@ -83,23 +221,18 @@ You can perform all checks locally using this command: make check ``` -Note: This can take a long time as it checks all links. You should use this -prior to submitting a PR to ensure validity. However, you can run individual -checks directly. +> Note: `make check` can take a long time as it checks all links. +> You should use this prior to submitting a PR to ensure validity. +> However, you can run individual checks directly. -See: +For more information on each check, see: -- [MarkdownStyle](#markdown-style) -- [Misspell Check](#misspell-check) -- Markdown link checking (docs TODO) +- [Markdown style](#markdown-style) +- [Misspell check](#misspell-check) +- [Markdown link check](#markdown-link-check) - Prettier formatting -### YAML to Markdown - -Semantic conventions are declared in YAML files and markdown tables are -generated from these files. Read about semantic convention updates [here](./model/README.md). - -### Autoformatting +### Auto formatting Semantic conventions have some autogenerated components and additionally can do automatic style/spell correction. You can run all of this via: @@ -113,7 +246,7 @@ You can also run these fixes individually. See: - [Misspell Correction](#misspell-check) -- Table Generation (docs TODO) +- [Update the markdown files](#2-update-the-markdown-files) ### Markdown style @@ -159,22 +292,13 @@ To quickly fix typos, use make misspell-correction ``` -### How to get your PR merged +### Markdown link check -A PR (pull request) is considered to be **ready to merge** when: +To check the validity of links in all markdown files, run the following command: -- It has received at least two approvals from the [code - owners](./.github/CODEOWNERS) (if approvals are from only one company, they - won't count). -- There is no `request changes` from the [code owners](./.github/CODEOWNERS). -- It has been at least two working days since the last modification (except for - the trivial updates, such like typo, cosmetic, rebase, etc.). This gives - people reasonable time to review. -- Trivial changes (typos, cosmetic changes, CI improvements, etc.) don't have to - wait for two days. - -Any [maintainer](./README.md#contributing) can merge the PR once it is **ready -to merge**. +```bash +make markdown-link-check +``` ## Updating the referenced specification version @@ -194,8 +318,10 @@ to merge**. - Ensure the `next` version is appropriately configured as the `{version}`. - Copy `schema-next.yaml` to `schemas/{version}`. - Add `next` as a version in `schema-next.yaml` version. - - Update `CHANGELOG.md` for the latest version. - - Add `## v{version} ({date})` under `## Unreleased` + - Run `make chlog-update VERSION=v{version}` + - `make chlog-update` will clean up all the current `.yaml` files inside the + `.chloggen` folder automatically + - Double check that `CONTRIBUTING.md` is updated with the proper `v{version}` - Send staging tag as PR for review. - Create a tag `v{version}` on the merged PR and push remote. diff --git a/Makefile b/Makefile index acbb7f7de7..14cadb3726 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,14 @@ ALL_DOCS := $(shell find . -type f -name '*.md' -not -path './.github/*' -not -p PWD := $(shell pwd) TOOLS_DIR := ./internal/tools + MISSPELL_BINARY=bin/misspell MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) +CHLOGGEN_BINARY=bin/chloggen +CHLOGGEN = $(TOOLS_DIR)/$(CHLOGGEN_BINARY) +CHLOGGEN_CONFIG := .chloggen/config.yaml + # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! SEMCONVGEN_VERSION=0.23.0 @@ -124,3 +129,23 @@ fix: table-generation misspell-correction fix-format install-tools: $(MISSPELL) npm install @echo "All tools installed" + +$(CHLOGGEN): + cd $(TOOLS_DIR) && go build -o $(CHLOGGEN_BINARY) go.opentelemetry.io/build-tools/chloggen + +FILENAME?=$(shell git branch --show-current) +.PHONY: chlog-new +chlog-new: $(CHLOGGEN) + $(CHLOGGEN) new --config $(CHLOGGEN_CONFIG) --filename $(FILENAME) + +.PHONY: chlog-validate +chlog-validate: $(CHLOGGEN) + $(CHLOGGEN) validate --config $(CHLOGGEN_CONFIG) + +.PHONY: chlog-preview +chlog-preview: $(CHLOGGEN) + $(CHLOGGEN) update --config $(CHLOGGEN_CONFIG) --dry --version $(VERSION) + +.PHONY: chlog-update +chlog-update: $(CHLOGGEN) + $(CHLOGGEN) update --config $(CHLOGGEN_CONFIG) --version $(VERSION) diff --git a/internal/tools/go.mod b/internal/tools/go.mod index aeac23a1d3..d0b9f54cf0 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -2,4 +2,7 @@ module github.com/open-telemetry/opentelemetry-specification/internal/tools go 1.12 -require github.com/client9/misspell v0.3.4 +require ( + github.com/client9/misspell v0.3.4 + go.opentelemetry.io/build-tools/chloggen v0.12.0 +) diff --git a/internal/tools/go.sum b/internal/tools/go.sum index ee5948021f..67e22ae48f 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -1,2 +1,29 @@ github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.opentelemetry.io/build-tools/chloggen v0.12.0 h1:BFj/1bNIGxOs1GykGjhV4gycz1nqVWI/xVDUaVfNibw= +go.opentelemetry.io/build-tools/chloggen v0.12.0/go.mod h1:zuYbAo3TkrHo3C7lCrM5dHWSS50BDr0UfRYtyBFv2dQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/tools/tools.go b/internal/tools/tools.go index bfa021b18f..2a785effdd 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -13,6 +13,7 @@ // limitations under the License. // +//go:build tools // +build tools package tools @@ -24,4 +25,5 @@ package tools import ( _ "github.com/client9/misspell/cmd/misspell" + _ "go.opentelemetry.io/build-tools/chloggen" ) From f3f577ce8e4a8ab8a87bd0e61f7f69dfd2f18b8b Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 5 Feb 2024 17:59:04 +0100 Subject: [PATCH 337/482] Chore: Bump stale bot version and exclude certain cases (#685) --- .github/workflows/stale-pr.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stale-pr.yml b/.github/workflows/stale-pr.yml index e463791fa9..3b6ebf4168 100644 --- a/.github/workflows/stale-pr.yml +++ b/.github/workflows/stale-pr.yml @@ -1,4 +1,4 @@ -name: "Close stale spull requests" +name: "Close stale pull requests" on: schedule: - cron: "12 3 * * *" # arbitrary time not to DDOS GitHub @@ -7,11 +7,12 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' - exempt-pr-labels: 'release:after-ga' + exempt-pr-labels: 'bug,work in progress,experts needed' + exempt-draft-pr: true days-before-stale: 15 days-before-close: 7 From 45a03e67ce2e109e860c38c60edf6367a1124545 Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Mon, 5 Feb 2024 19:15:46 +0100 Subject: [PATCH 338/482] Fix header level in README.md (#684) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/resource/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resource/README.md b/docs/resource/README.md index a77cbd2f69..6a3dc8231c 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -20,7 +20,7 @@ This document defines standard attributes for resources. These attributes are ty - [Document Conventions](#document-conventions) - [Attributes with Special Handling](#attributes-with-special-handling) * [Semantic Attributes with Dedicated Environment Variable](#semantic-attributes-with-dedicated-environment-variable) -- [Semantic Attributes with SDK-provided Default Value](#semantic-attributes-with-sdk-provided-default-value) + * [Semantic Attributes with SDK-provided Default Value](#semantic-attributes-with-sdk-provided-default-value) - [Service](#service) - [Service (Experimental)](#service-experimental) - [Telemetry SDK](#telemetry-sdk) @@ -63,7 +63,7 @@ as specified in [OpenTelemetry Environment Variable Specification](https://githu - [`service.name`](#service) -## Semantic Attributes with SDK-provided Default Value +### Semantic Attributes with SDK-provided Default Value These are the attributes which MUST be provided by the SDK as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md#sdk-provided-resource-attributes): From 5fd9bfeece5477ef72d529cce698d152652d846b Mon Sep 17 00:00:00 2001 From: Joao Grassi Date: Tue, 6 Feb 2024 11:07:57 +0100 Subject: [PATCH 339/482] Omit version on changelog preview cmd (#692) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 14cadb3726..b0a1e81e95 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ chlog-validate: $(CHLOGGEN) .PHONY: chlog-preview chlog-preview: $(CHLOGGEN) - $(CHLOGGEN) update --config $(CHLOGGEN_CONFIG) --dry --version $(VERSION) + $(CHLOGGEN) update --config $(CHLOGGEN_CONFIG) --dry .PHONY: chlog-update chlog-update: $(CHLOGGEN) From c9252a122256eaa491da5a2f4141ce1a580824ee Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Tue, 6 Feb 2024 02:10:36 -0800 Subject: [PATCH 340/482] A few small documentation things around changelog generation. (#691) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- .chloggen/TEMPLATE.yaml | 1 + CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.chloggen/TEMPLATE.yaml b/.chloggen/TEMPLATE.yaml index 4387154dd4..b094f4d184 100644 --- a/.chloggen/TEMPLATE.yaml +++ b/.chloggen/TEMPLATE.yaml @@ -13,6 +13,7 @@ component: note: # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. issues: [] # (Optional) One or more lines of additional information to render under the primary note. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abde6789cc..0639de51d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -174,7 +174,7 @@ from `.yaml` files in the [/.chloggen](/.chloggen) directory. Your pull request should add a new `.yaml` file to this directory. The name of your file can be arbitrary but must be unique since the last release. -During the release process, all `./chloggen/*.yaml` files are transcribed into +During the release process, all `./.chloggen/*.yaml` files are transcribed into `CHANGELOG.md` and then deleted. 1. Create an entry file using `make chlog-new`. The command generates a new file, From 2ff370d136debc9702ebe5750ff98532e75fa41e Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 6 Feb 2024 04:23:21 -0800 Subject: [PATCH 341/482] Fix jvm buffer metric schema translations (#683) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- CHANGELOG.md | 2 ++ schema-next.yaml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 627a6650f3..7537d61028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ - `type` to `process.context_switch_type` - Rename attributes for `process.paging.faults` - `type` to `process.paging.fault_type` +- Fix JVM buffer metric schema translations + ([#683](https://github.com/open-telemetry/semantic-conventions/pull/683)) ### Features diff --git a/schema-next.yaml b/schema-next.yaml index 23ebad9a35..441f34e983 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -140,8 +140,8 @@ versions: attribute_map: pool: jvm.buffer.pool.name apply_to_metrics: - - jvm.buffer.usage - - jvm.buffer.limit + - jvm.buffer.memory.usage + - jvm.buffer.memory.limit - jvm.buffer.count # https://github.com/open-telemetry/semantic-conventions/pull/89 - rename_attributes: From be0cae0e38c7f226a5973c695c9779704b9b30c1 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 6 Feb 2024 17:54:23 +0100 Subject: [PATCH 342/482] Add messaging semantic conventions for settlement spans (#661) Co-authored-by: Joao Grassi --- .chloggen/661.yaml | 22 ++++++++++++++++++++++ docs/messaging/messaging-spans.md | 16 ++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 .chloggen/661.yaml diff --git a/.chloggen/661.yaml b/.chloggen/661.yaml new file mode 100644 index 0000000000..dde1142c34 --- /dev/null +++ b/.chloggen/661.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: messaging + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add messaging semantic conventions for settlement spans + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [621] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 19db054994..33e7d9ba29 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -184,18 +184,19 @@ If the destination name is dynamic, such as a [conversation ID](#conversations) In these cases, an artificial destination name that best expresses the destination, or a generic, static fallback like `"(anonymous)"` for [anonymous destinations](#temporary-and-anonymous-destinations) SHOULD be used instead. The values allowed for `` are defined in the section [Operation names](#operation-names) below. -If the format above is used, the operation name MUST match the `messaging.operation` attribute defined for message consumer spans below. Examples: * `shop.orders publish` * `shop.orders receive` -* `shop.orders process` +* `shop.orders settle` * `print_jobs publish` -* `topic with spaces process` -* `AuthenticationRequest-Conversations process` +* `topic with spaces deliver` +* `AuthenticationRequest-Conversations settle` * `(anonymous) publish` (`(anonymous)` being a stable identifier for an unnamed destination) +Messaging system specific adaptions to span naming MUST be documented in [semantic conventions for specific messaging technologies](#semantic-conventions-for-specific-messaging-technologies). + ### Operation names The following operations related to messages are defined for these semantic conventions: @@ -206,6 +207,7 @@ The following operations related to messages are defined for these semantic conv | `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | | `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +| `settle` | One or more messages are settled. | ### Span kind @@ -269,6 +271,12 @@ batch of messages, or for no message at all (if it is signalled that no messages were received). For each message it accounts for, the "Deliver" or "Receive" span SHOULD link to the message's creation context. +"Settle" spans SHOULD be created for every manually or automatically triggered +settlement operation. A single "Settle" span can account for a single message +or for multiple messages (in case messages are passed for settling as batches). +For each message it accounts for, the "Settle" span MAY link to the creation +context of the message. + ## Messaging attributes Messaging attributes are organized into the following namespaces: From e39dcb521b18e0a671da53da07182d850b634d1e Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 6 Feb 2024 11:57:38 -0500 Subject: [PATCH 343/482] [editorial] Fix path base in Hugo front matter (#688) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/README.md | 4 ++-- docs/attributes-registry/host.md | 1 + docs/attributes-registry/os.md | 1 + docs/attributes-registry/url.md | 1 + docs/cloud-providers/README.md | 2 +- docs/cloudevents/README.md | 2 +- docs/database/README.md | 2 +- docs/dotnet/README.md | 2 +- docs/exceptions/README.md | 2 +- docs/faas/README.md | 2 +- docs/feature-flags/README.md | 2 +- docs/general/README.md | 2 +- docs/http/README.md | 2 +- docs/messaging/README.md | 2 +- docs/mobile/README.md | 4 ++-- docs/object-stores/README.md | 2 +- docs/resource/README.md | 2 +- docs/resource/cloud-provider/README.md | 2 +- docs/resource/cloud-provider/aws/README.md | 2 +- docs/resource/cloud-provider/gcp/README.md | 2 +- docs/rpc/README.md | 2 +- docs/system/README.md | 2 +- docs/url/README.md | 2 +- 23 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/README.md b/docs/README.md index 498f5e739c..e15b61dfaa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,10 +5,10 @@ cascade: body_class: otel-docs-spec github_repo: &repo https://github.com/open-telemetry/semantic-conventions github_subdir: docs - path_base_for_github_subdir: content/en/docs/specs/semconv/ + path_base_for_github_subdir: tmp/semconv/docs/ github_project_repo: *repo path_base_for_github_subdir: - from: content/en/docs/specs/semconv/_index.md + from: tmp/semconv/docs/_index.md to: README.md ---> diff --git a/docs/attributes-registry/host.md b/docs/attributes-registry/host.md index 005700c2cc..e44d10555d 100644 --- a/docs/attributes-registry/host.md +++ b/docs/attributes-registry/host.md @@ -1,5 +1,6 @@ + # Host ## Host Attributes diff --git a/docs/attributes-registry/os.md b/docs/attributes-registry/os.md index a813298f98..1a9df99771 100644 --- a/docs/attributes-registry/os.md +++ b/docs/attributes-registry/os.md @@ -1,6 +1,7 @@ + # OS ## Operating System Attributes diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index 5b1aa7c0d8..c7a22357b7 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -1,6 +1,7 @@ + # URL ## URL Attributes diff --git a/docs/cloud-providers/README.md b/docs/cloud-providers/README.md index 4b213871fe..8e88f408fc 100644 --- a/docs/cloud-providers/README.md +++ b/docs/cloud-providers/README.md @@ -1,7 +1,7 @@ diff --git a/docs/cloudevents/README.md b/docs/cloudevents/README.md index b5c2c20ad7..beb6527e62 100644 --- a/docs/cloudevents/README.md +++ b/docs/cloudevents/README.md @@ -1,7 +1,7 @@ diff --git a/docs/database/README.md b/docs/database/README.md index 50d42dd7cb..8ef9dd98c9 100644 --- a/docs/database/README.md +++ b/docs/database/README.md @@ -1,7 +1,7 @@ diff --git a/docs/dotnet/README.md b/docs/dotnet/README.md index 1bc9673359..a8b5f7bbd2 100644 --- a/docs/dotnet/README.md +++ b/docs/dotnet/README.md @@ -1,7 +1,7 @@ diff --git a/docs/exceptions/README.md b/docs/exceptions/README.md index 4e074df495..4632585126 100644 --- a/docs/exceptions/README.md +++ b/docs/exceptions/README.md @@ -1,7 +1,7 @@ diff --git a/docs/faas/README.md b/docs/faas/README.md index bdf3b05222..19ab9d3131 100644 --- a/docs/faas/README.md +++ b/docs/faas/README.md @@ -1,7 +1,7 @@ diff --git a/docs/feature-flags/README.md b/docs/feature-flags/README.md index 1eb70a28e3..a55b42b7d9 100644 --- a/docs/feature-flags/README.md +++ b/docs/feature-flags/README.md @@ -1,7 +1,7 @@ diff --git a/docs/general/README.md b/docs/general/README.md index ec1e248fda..a4bff5597e 100644 --- a/docs/general/README.md +++ b/docs/general/README.md @@ -1,7 +1,7 @@ diff --git a/docs/http/README.md b/docs/http/README.md index c4ae8a10d2..4bd1e41f73 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -1,7 +1,7 @@ diff --git a/docs/messaging/README.md b/docs/messaging/README.md index 5308786270..2ba98b5977 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -1,7 +1,7 @@ diff --git a/docs/mobile/README.md b/docs/mobile/README.md index bcf994e485..cc6ffb6285 100644 --- a/docs/mobile/README.md +++ b/docs/mobile/README.md @@ -1,7 +1,7 @@ diff --git a/docs/object-stores/README.md b/docs/object-stores/README.md index da6a0d8612..67637442ee 100644 --- a/docs/object-stores/README.md +++ b/docs/object-stores/README.md @@ -1,7 +1,7 @@ diff --git a/docs/resource/README.md b/docs/resource/README.md index 6a3dc8231c..c67b8f3517 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -1,7 +1,7 @@ diff --git a/docs/resource/cloud-provider/README.md b/docs/resource/cloud-provider/README.md index 9d4757a6c0..1be2cbd21c 100644 --- a/docs/resource/cloud-provider/README.md +++ b/docs/resource/cloud-provider/README.md @@ -1,7 +1,7 @@ diff --git a/docs/resource/cloud-provider/aws/README.md b/docs/resource/cloud-provider/aws/README.md index 2ac32239e5..1409a89b5f 100644 --- a/docs/resource/cloud-provider/aws/README.md +++ b/docs/resource/cloud-provider/aws/README.md @@ -1,7 +1,7 @@ diff --git a/docs/resource/cloud-provider/gcp/README.md b/docs/resource/cloud-provider/gcp/README.md index 1e975ff9db..6b115235ea 100644 --- a/docs/resource/cloud-provider/gcp/README.md +++ b/docs/resource/cloud-provider/gcp/README.md @@ -1,7 +1,7 @@ diff --git a/docs/rpc/README.md b/docs/rpc/README.md index c7810685b4..353f6bce85 100644 --- a/docs/rpc/README.md +++ b/docs/rpc/README.md @@ -1,7 +1,7 @@ diff --git a/docs/system/README.md b/docs/system/README.md index a05a0bf9e8..a3422a342f 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -1,7 +1,7 @@ diff --git a/docs/url/README.md b/docs/url/README.md index 6c863191ae..61c2398793 100644 --- a/docs/url/README.md +++ b/docs/url/README.md @@ -1,7 +1,7 @@ From e2382e6ba570c76b78085aebf6226ea46d096dc2 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:43:56 +0100 Subject: [PATCH 344/482] [chore] remove microsoft link to fix PR checks (#701) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/database/mssql.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 763e7a1b12..239be3960b 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -6,7 +6,7 @@ linkTitle: MSSQL **Status**: [Experimental][DocumentStatus] -The Semantic Conventions for the [Microsoft SQL Server](https://www.microsoft.com/sql-server) extend and override the [Database Semantic Conventions](database-spans.md) +The Semantic Conventions for the *Microsoft SQL Server* extend and override the [Database Semantic Conventions](database-spans.md) that describe common database operations attributes in addition to the Semantic Conventions described on this page. From a78115ee8b5428a27ad6b1b2b86ac7bf3fb96e72 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Thu, 8 Feb 2024 18:58:27 +0200 Subject: [PATCH 345/482] [resource/host] Change type of `host.cpu.stepping` to string (#665) --- .chloggen/fix_cpu_step.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/host.md | 2 +- docs/resource/host.md | 2 +- model/registry/host.yaml | 4 ++-- 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100755 .chloggen/fix_cpu_step.yaml diff --git a/.chloggen/fix_cpu_step.yaml b/.chloggen/fix_cpu_step.yaml new file mode 100755 index 0000000000..9633748d8c --- /dev/null +++ b/.chloggen/fix_cpu_step.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: "breaking" + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: 'host' + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "[resource/host] Change type of host.cpu.stepping to string" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [664, 665] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/host.md b/docs/attributes-registry/host.md index e44d10555d..a8c1de6e3f 100644 --- a/docs/attributes-registry/host.md +++ b/docs/attributes-registry/host.md @@ -13,7 +13,7 @@ | `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | | `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | | `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | -| `host.cpu.stepping` | int | Stepping or core revisions. | `1` | +| `host.cpu.stepping` | string | Stepping or core revisions. | `1`; `r1p1` | | `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | | `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | | `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | diff --git a/docs/resource/host.md b/docs/resource/host.md index a11c735b86..9dfdd5d2b5 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -49,7 +49,7 @@ To report host metrics, the `system.*` namespace SHOULD be used. | [`host.cpu.family`](../attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | Opt-In | | [`host.cpu.model.id`](../attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | Opt-In | | [`host.cpu.model.name`](../attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | -| [`host.cpu.stepping`](../attributes-registry/host.md) | int | Stepping or core revisions. | `1` | Opt-In | +| [`host.cpu.stepping`](../attributes-registry/host.md) | string | Stepping or core revisions. | `1`; `r1p1` | Opt-In | | [`host.cpu.vendor.id`](../attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. diff --git a/model/registry/host.yaml b/model/registry/host.yaml index 3deb5f5707..e8243a12cc 100644 --- a/model/registry/host.yaml +++ b/model/registry/host.yaml @@ -111,10 +111,10 @@ groups: Model designation of the processor. examples: [ '11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz' ] - id: cpu.stepping - type: int + type: string brief: > Stepping or core revisions. - examples: [ 1 ] + examples: ["1", "r1p1"] - id: cpu.cache.l2.size type: int brief: > From 44c830d3dabad9d59f340d92e774a1d5a2356743 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:16:01 +0100 Subject: [PATCH 346/482] Update `user_agent.*` wording to support multiple apps (#680) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Joao Grassi --- .chloggen/ua_wording.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/user-agent.md | 10 +++++----- docs/http/http-spans.md | 4 ++-- model/registry/user-agent.yaml | 19 +++++++++++++------ 4 files changed, 42 insertions(+), 13 deletions(-) create mode 100755 .chloggen/ua_wording.yaml diff --git a/.chloggen/ua_wording.yaml b/.chloggen/ua_wording.yaml new file mode 100755 index 0000000000..b8be0677f0 --- /dev/null +++ b/.chloggen/ua_wording.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: user-agent + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Update user_agent subfields wording to support it's usage for non-browser products with multiple names/versions + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [680] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md index f75c5d22ce..3baeaaf931 100644 --- a/docs/attributes-registry/user-agent.md +++ b/docs/attributes-registry/user-agent.md @@ -8,11 +8,11 @@ | Attribute | Type | Description | Examples | |---|---|---|---| -| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name [1] | `Safari` | -| `user_agent.original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | -| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2` | +| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name. [1] | `Safari`; `YourApp` | +| `user_agent.original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | +| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2`; `1.0.0` | -**[1]:** [Example](https://www.whatsmyua.info) of extracting browser's name from original string +**[1]:** [Example](https://www.whatsmyua.info) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version` -**[2]:** [Example](https://www.whatsmyua.info) of extracting browser's version from original string +**[2]:** [Example](https://www.whatsmyua.info) of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align with `user_agent.name` diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 9ed7173c1b..3e11eb8704 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -232,7 +232,7 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Required | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Opt-In | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | Opt-In | **[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. @@ -349,7 +349,7 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | | [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | Recommended | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | Recommended | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. diff --git a/model/registry/user-agent.yaml b/model/registry/user-agent.yaml index 29e00ff6bc..f783d379e5 100644 --- a/model/registry/user-agent.yaml +++ b/model/registry/user-agent.yaml @@ -10,18 +10,25 @@ groups: brief: > Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. examples: ['CERN-LineMode/2.15 libwww/2.17b3', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1', + 'YourApp/1.0.0 grpc-java-okhttp/1.27.2'] - id: name type: string brief: > - Name of the user-agent extracted from original. Usually refers to the browser's name - examples: ['Safari'] + Name of the user-agent extracted from original. Usually refers to the browser's name. + examples: ['Safari', 'YourApp'] note: > - [Example](https://www.whatsmyua.info) of extracting browser's name from original string + [Example](https://www.whatsmyua.info) of extracting browser's name from original string. In the case of using + a user-agent for non-browser products, such as microservices with multiple names/versions inside the + `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with + `user_agent.version` - id: version type: string brief: > Version of the user-agent extracted from original. Usually refers to the browser's version - examples: ['14.1.2'] + examples: ['14.1.2', '1.0.0'] note: > - [Example](https://www.whatsmyua.info) of extracting browser's version from original string + [Example](https://www.whatsmyua.info) of extracting browser's version from original string. In the case of + using a user-agent for non-browser products, such as microservices with multiple names/versions inside the + `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align + with `user_agent.name` From b6afdeb6ee708618d91d7267ac99e5d3dc261c28 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Mon, 12 Feb 2024 09:35:04 +0100 Subject: [PATCH 347/482] Clarify producer span relationships and add a messaging example for a batch publishing scenario (#509) --- .chloggen/509.yaml | 22 ++++++++ docs/messaging/messaging-spans.md | 86 +++++++++++++++++++++++++------ 2 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 .chloggen/509.yaml diff --git a/.chloggen/509.yaml b/.chloggen/509.yaml new file mode 100644 index 0000000000..620f8e134f --- /dev/null +++ b/.chloggen/509.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: messaging + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Clarify producer span relationships for messaging semantic conventions + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [509] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 33e7d9ba29..2e39da3b11 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -30,6 +30,7 @@ - [Examples](#examples) * [Topic with multiple consumers](#topic-with-multiple-consumers) * [Batch receiving](#batch-receiving) + * [Batch publishing](#batch-publishing) - [Semantic Conventions for specific messaging technologies](#semantic-conventions-for-specific-messaging-technologies) @@ -203,8 +204,8 @@ The following operations related to messages are defined for these semantic conv | Operation name | Description | | -------------- | ----------- | +| `create` | A message is created or passed to a client library for publishing. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | -| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | | `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | | `settle` | One or more messages are settled. | @@ -216,8 +217,8 @@ SHOULD be set according to the following table, based on the operation a span de | Operation name | Span kind| |----------------|-------------| -| `publish` | `PRODUCER` if the context of the "Publish" span is used as creation context. | | `create` | `PRODUCER` | +| `publish` | `PRODUCER` if the context of the "Publish" span is used as creation context. | | `receive` | `CONSUMER` | | `deliver` | `CONSUMER` | @@ -236,20 +237,22 @@ interpret linked traces without the need for additional semantic hints. #### Producer spans -"Publish" spans SHOULD be created for operations of providing messages for -sending or publishing to an intermediary. A single "Publish" span can account -for a single message, or for multiple messages (in the case of providing -messages in batches). "Create" spans MAY be created. A single "Create" span -SHOULD account only for a single message. "Create" spans SHOULD either be -children or links of the related "Publish" span. +"Create" spans MAY be created when a message is created or passed to the client +library or other component responsible for publishing. A single "Create" span +SHOULD account only for a single message. "Publish" spans SHOULD be created +for operations of sending or publishing a message to an intermediary. A single +"Publish" span can account for a single message, or for multiple messages (in +the case of sending messages in batches). If a user provides a custom creation context in a message, this context SHOULD -NOT be modified, a "Create" span SHOULD NOT be created, and the "Publish" span -SHOULD link to the custom creation context. Otherwise, if a "Create" span -exists for a message, its context SHOULD be injected into the message. If no -"Create" span exists and no custom creation context is injected into the -message, the context of the related "Publish" span SHOULD be injected into the -message. +NOT be modified and a "Create" span SHOULD NOT be created. Otherwise, if a +"Create" span exists for a message, its context SHOULD be injected into the +message. If no "Create" span exists and no custom creation context is injected +into the message, the context of the related "Publish" span SHOULD be injected +into the message. + +The "Publish" span SHOULD always link to the creation context that was injected +into a message either from a "Create" span or as a custom creation context. #### Consumer spans @@ -475,6 +478,14 @@ All attributes that are specific for a messaging system SHOULD be populated in ` ## Examples +This section contains a list of examples illustrating the use of the +conventions outlined above. Green boxes denote spans that are required to exist +in order to conform to those conventions. Other boxes denote spans that are not +required and covered by the conventions, but are hopefully helpful in +understanding how messaging spans can be integrated into an overall trace flow. +Solid arrows denote parent/child relationships, dotted arrows denote link +relationships. + ### Topic with multiple consumers Given is a publisher that publishes a message to a topic exchange "T" on RabbitMQ, and two consumers which both get the message delivered. @@ -507,7 +518,6 @@ flowchart LR; | Parent | | | | | Links | | `T publish` | `T publish` | | SpanKind | `PRODUCER` | `CONSUMER` | `CONSUMER` | -| Status | `Ok` | `Ok` | `Ok` | | `server.address` | `"ms"` | `"ms"` | `"ms"` | | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | @@ -546,7 +556,6 @@ flowchart LR; | Link attributes | | | Span Publish A: `messaging.message.id`: `"a1"` | | | | | Span Publish B: `messaging.message.id`: `"a2"` | | SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | -| Status | `Ok` | `Ok` | `Ok` | | `server.address` | `"ms"` | `"ms"` | `"ms"` | | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | @@ -555,6 +564,51 @@ flowchart LR; | `messaging.message.id` | `"a1"` | `"a2"` | | | `messaging.batch.message_count` | | | 2 | +### Batch publishing + +Given is a publisher that publishes a batch with two messages to a topic "Q" on +Kafka, and two different consumers receiving one of the messages. + +```mermaid +flowchart LR; + subgraph PRODUCER + direction TB + CA[Span Create A] + CB[Span Create B] + P[Span Publish] + end + subgraph CONSUMER1 + direction TB + D1[Span Receive A] + end + subgraph CONSUMER2 + direction TB + D2[Span Receive B] + end + CA-. link .-P; + CB-. link .-P; + CA-. link .-D1; + CB-. link .-D2; + + classDef normal fill:green + class P,CA,CB,D1,D2 normal + linkStyle 0,1,2,3 color:green,stroke:green +``` + +| Field or Attribute | Span Create A | Span Create B | Span Publish | Span Receive A | Span Receive B | +|-|-|-|-|-|-| +| Span name | `Q create` | `Q create` | `Q publish` | `Q receive` | `Q receive` | +| Parent | | | | | | +| Links | | | | Span Create A | Span Create B | +| SpanKind | `PRODUCER` | `PRODUCER` | `CLIENT` | `CONSUMER` | `CONSUMER` | +| `server.address` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | `"ms"` | +| `server.port` | `1234` | `1234` | `1234` | `1234` | `1234` | +| `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | +| `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | +| `messaging.operation` | `"create"` | `"create"` | `"publish"` | `"receive"` | `"receive"` | +| `messaging.message.id` | `"a1"` | `"a2"` | | `"a1"` | `"a2"` | +| `messaging.batch.message_count` | | | 2 | | | + ## Semantic Conventions for specific messaging technologies More specific Semantic Conventions are defined for the following messaging technologies: From 183647b9e55ecccb320b76bab325416507e151b9 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 12 Feb 2024 06:08:27 -0800 Subject: [PATCH 348/482] Add placeholder for database stability transition plan (#733) Co-authored-by: Joao Grassi --- docs/database/README.md | 7 +++++++ docs/database/database-metrics.md | 7 +++++++ docs/database/database-spans.md | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/docs/database/README.md b/docs/database/README.md index 8ef9dd98c9..ab5bc2658a 100644 --- a/docs/database/README.md +++ b/docs/database/README.md @@ -12,6 +12,13 @@ path_base_for_github_subdir: This document defines semantic conventions for database client spans as well as database metrics and logs. +> **Warning** +> Existing database instrumentations that are using +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/README.md) +> (or prior) SHOULD NOT change the version of the database conventions that they emit +> until a transition plan to the (future) stable semantic conventions has been published. +> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. + Semantic conventions for database operations are defined for the following signals: * [DB Spans](database-spans.md): Semantic Conventions for database client *spans*. diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index f211e64c37..54c9e92927 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -28,6 +28,13 @@ and attributes but more may be added in the future. +> **Warning** +> Existing database instrumentations that are using +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-metrics.md) +> (or prior) SHOULD NOT change the version of the database conventions that they emit +> until a transition plan to the (future) stable semantic conventions has been published. +> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. + ## Connection pools The following metric instruments describe database client connection pool operations. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index b352e48252..50ff735718 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -17,6 +17,13 @@ linkTitle: Client Calls +> **Warning** +> Existing database instrumentations that are using +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md) +> (or prior) SHOULD NOT change the version of the database conventions that they emit +> until a transition plan to the (future) stable semantic conventions has been published. +> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. +> > **Warning** > Existing Database instrumentations that are using > [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/database.md) From 352293d18a2b6e3e625d5be044aeaf0e4f83727b Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:06:29 +0100 Subject: [PATCH 349/482] [chore] revert temp fix for resource attributes (#702) Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- model/registry/cloud.yaml | 2 +- model/registry/container.yaml | 2 +- model/registry/device.yaml | 2 +- model/registry/host.yaml | 2 +- model/registry/oci.yaml | 2 +- model/registry/os.yaml | 2 +- model/registry/process.yaml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml index 9835e09b62..5ddb25c899 100644 --- a/model/registry/cloud.yaml +++ b/model/registry/cloud.yaml @@ -1,7 +1,7 @@ groups: - id: registry.cloud prefix: cloud - type: resource + type: attribute_group brief: > A cloud environment (e.g. GCP, Azure, AWS). attributes: diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 4b11e772fd..2288c39e52 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -1,7 +1,7 @@ groups: - id: registry.container prefix: container - type: resource + type: attribute_group brief: > A container instance. attributes: diff --git a/model/registry/device.yaml b/model/registry/device.yaml index 6eaf8e3b5e..c109981f11 100644 --- a/model/registry/device.yaml +++ b/model/registry/device.yaml @@ -1,7 +1,7 @@ groups: - id: registry.device prefix: device - type: resource + type: attribute_group brief: > Describes device attributes. attributes: diff --git a/model/registry/host.yaml b/model/registry/host.yaml index e8243a12cc..c6b68ef414 100644 --- a/model/registry/host.yaml +++ b/model/registry/host.yaml @@ -1,7 +1,7 @@ groups: - id: registry.host prefix: host - type: resource + type: attribute_group brief: > A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. attributes: diff --git a/model/registry/oci.yaml b/model/registry/oci.yaml index 45e2838796..24e0cb93f2 100644 --- a/model/registry/oci.yaml +++ b/model/registry/oci.yaml @@ -1,7 +1,7 @@ groups: - id: registry.oci.manifest prefix: oci.manifest - type: resource + type: attribute_group brief: > An OCI image manifest. attributes: diff --git a/model/registry/os.yaml b/model/registry/os.yaml index 5b699b1faf..af8dbfcd2a 100644 --- a/model/registry/os.yaml +++ b/model/registry/os.yaml @@ -1,7 +1,7 @@ groups: - id: registry.os prefix: os - type: resource + type: attribute_group brief: > The operating system (OS) on which the process represented by this resource is running. note: > diff --git a/model/registry/process.yaml b/model/registry/process.yaml index 169b426538..e4b5c230bd 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -1,7 +1,7 @@ groups: - id: registry.process prefix: process - type: resource + type: attribute_group brief: > An operating system process. attributes: From 85ea994ff629653a694d79d16ca0b630ea252600 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Mon, 12 Feb 2024 12:41:58 -0800 Subject: [PATCH 350/482] Event payload lives in the LogRecord body (#566) Co-authored-by: jack-berg <34418638+jack-berg@users.noreply.github.com> Co-authored-by: Joao Grassi Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Josh Suereth --- .chloggen/event_payload_in_body.yaml | 21 +++++++++++++++++++ docs/general/events.md | 30 ++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 .chloggen/event_payload_in_body.yaml diff --git a/.chloggen/event_payload_in_body.yaml b/.chloggen/event_payload_in_body.yaml new file mode 100644 index 0000000000..8ac0c36291 --- /dev/null +++ b/.chloggen/event_payload_in_body.yaml @@ -0,0 +1,21 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: events + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add clarification that the body of an Event will live in the LogRecord body field. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [ 566] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/general/events.md b/docs/general/events.md index 8fcd24cf8a..51f4ef29d9 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -3,13 +3,35 @@ linkTitle: Events aliases: [docs/specs/semconv/general/events-general] ---> -# Semantic Conventions for Event Attributes +# Semantic Conventions for Events **Status**: [Experimental][DocumentStatus] -This document describes the attributes of standalone Events that are represented +This document describes the characteristics of standalone Events that are represented in the data model by `LogRecord`s. +Semantically, an Event is a named occurrence at an instant in time. It signals that +"this thing happened at this time" and provides additional specifics about the occurrence. +Examples of Events might include things like uncaught exceptions, button clicks, user logout, +network connection severed, etc. + +In OpenTelemetry, Events are implemented as a specific type of `LogRecord` that conforms to +the conventions included here, and Events +[have their own API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/event-api.md). +The API abstracts away knowledge of `LogRecord` so that users only deal with Event +semantics. + +In addition to a required name, an Event may contain a _payload_ of any type permitted by the +[LogRecord body](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-body). +In its implementation, the Event _payload_ will constitute the `Body` of the `LogRecord`. +Like all other OpenTelemetry signals, an Event has optional attribute metadata that helps describe +the event context. + +Over time, some Events will be specified by OpenTelemetry and will have documented payload structure, +field semantics, and stability and requirement levels. Other events may be user-defined and carry +bespoke user semantics. When an Event name exists in the semantic conventions, its _payload_ +structure and semantics will also be defined. + The following semantic conventions for events are defined: * **[General](#general-event-attributes): General semantic attributes that may be used in describing Events.** @@ -18,8 +40,8 @@ The following semantic conventions for events are defined: ## General event attributes Events are recorded as LogRecords that are shaped in a special way: Event -LogRecords have the attribute `event.name` that uniquely identifies the event. -Events with same `event.name` are structurally similar to one another. Events +LogRecords MUST have the attribute `event.name` that uniquely identifies the event. +Events with the same `event.name` are structurally similar to one another. Events may also have other LogRecord attributes. When recording events from an existing system as OpenTelemetry Events, it is From 059b219ded3d060483d1ff477152f4b7c8d8fe32 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 13 Feb 2024 13:26:15 +0100 Subject: [PATCH 351/482] Add placeholder for messaging stabiblity transition plan (#734) Co-authored-by: Joao Grassi --- docs/messaging/messaging-metrics.md | 7 +++++++ docs/messaging/messaging-spans.md | 29 +++++------------------------ 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index dc9d1ef9b0..63bb6b384e 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -18,6 +18,13 @@ +> **Warning** +> Existing messaging instrumentations that are using +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-metrics.md) +> (or prior) SHOULD NOT change the version of the messaging conventions that they emit +> until a transition plan to the (future) stable semantic conventions has been published. +> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. + ## Common attributes All messaging metrics share the same set of attributes: diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 2e39da3b11..14ee11002d 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -36,30 +36,11 @@ > **Warning** -> Existing Messaging instrumentations that are using -> [v1.20.0 of this document](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/semantic_conventions/messaging.md) -> (or prior): -> -> * SHOULD NOT change the version of the networking conventions that they emit -> until the HTTP semantic conventions are marked stable (HTTP stabilization will -> include stabilization of a core set of networking conventions which are also used -> in Messaging instrumentations). Conventions include, but are not limited to, attributes, -> metric and span names, and unit of measure. -> * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN` -> in the existing major version which is a comma-separated list of values. -> The only values defined so far are: -> * `http` - emit the new, stable networking conventions, -> and stop emitting the old experimental networking conventions -> that the instrumentation emitted previously. -> * `http/dup` - emit both the old and the stable networking conventions, -> allowing for a seamless transition. -> * The default behavior (in the absence of one of these values) is to continue -> emitting whatever version of the old experimental networking conventions -> the instrumentation was emitting previously. -> * Note: `http/dup` has higher precedence than `http` in case both values are present -> * SHOULD maintain (security patching at a minimum) the existing major version -> for at least six months after it starts emitting both sets of conventions. -> * SHOULD drop the environment variable in the next major version. +> Existing messaging instrumentations that are using +> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-spans.md) +> (or prior) SHOULD NOT change the version of the messaging conventions that they emit +> until a transition plan to the (future) stable semantic conventions has been published. +> Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. ## Definitions From 0b437c0edf3221786cb516c7f24c526d2a39a6a2 Mon Sep 17 00:00:00 2001 From: Matt McCleary <43887470+mattmccleary@users.noreply.github.com> Date: Wed, 14 Feb 2024 01:44:56 -0800 Subject: [PATCH 352/482] [chore] Change Traces SemConv Status to Mixed (#741) --- docs/general/trace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general/trace.md b/docs/general/trace.md index 2397794348..4dd8f79411 100644 --- a/docs/general/trace.md +++ b/docs/general/trace.md @@ -5,7 +5,7 @@ aliases: [docs/specs/semconv/general/trace-general] # Trace Semantic Conventions -**Status**: [Experimental][DocumentStatus] +**Status**: [Mixed][DocumentStatus] In OpenTelemetry spans can be created freely and it’s up to the implementor to annotate them with attributes specific to the represented operation. Spans From 8b4ad95d21b3d5e17fe97538f93f98e537013661 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 14 Feb 2024 20:02:49 +0100 Subject: [PATCH 353/482] [chore] Exclude issues from stale bot check (#745) --- .github/workflows/stale-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale-pr.yml b/.github/workflows/stale-pr.yml index 3b6ebf4168..c1b7f9370e 100644 --- a/.github/workflows/stale-pr.yml +++ b/.github/workflows/stale-pr.yml @@ -14,5 +14,5 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' exempt-pr-labels: 'bug,work in progress,experts needed' exempt-draft-pr: true - days-before-stale: 15 - days-before-close: 7 + days-before-pr-stale: 15 + days-before-pr-close: 7 From 5d7e48746a1f01059b86bc59f62c4daa09f86903 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 15 Feb 2024 10:41:03 -0800 Subject: [PATCH 354/482] [chore] Move GraphQL out of database folder/semconv (#736) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/README.md | 1 + docs/database/README.md | 1 - docs/database/database-spans.md | 1 - docs/{database/graphql.md => graphql/graphql-spans.md} | 0 4 files changed, 1 insertion(+), 2 deletions(-) rename docs/{database/graphql.md => graphql/graphql-spans.md} (100%) diff --git a/docs/README.md b/docs/README.md index e15b61dfaa..1dfe42baf3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,7 @@ Semantic Conventions are defined for the following areas: * [Exceptions](exceptions/README.md): Semantic Conventions for exceptions. * [FaaS](faas/README.md): Semantic Conventions for Function as a Service (FaaS) operations. * [Feature Flags](feature-flags/README.md): Semantic Conventions for feature flag evaluations. +* [GraphQL](graphql/graphql-spans.md): Semantic Conventions for GraphQL implementations. * [HTTP](http/README.md): Semantic Conventions for HTTP client and server operations. * [Messaging](messaging/README.md): Semantic Conventions for messaging operations and systems. * [Object Stores](object-stores/README.md): Semantic Conventions for object stores operations. diff --git a/docs/database/README.md b/docs/database/README.md index ab5bc2658a..ff0b546d8b 100644 --- a/docs/database/README.md +++ b/docs/database/README.md @@ -31,7 +31,6 @@ Technology specific semantic conventions are defined for the following databases * [Cosmos DB](cosmosdb.md): Semantic Conventions for *Microsoft Cosmos DB*. * [CouchDB](couchdb.md): Semantic Conventions for *CouchDB*. * [Elasticsearch](elasticsearch.md): Semantic Conventions for *Elasticsearch*. -* [GraphQL](graphql.md): Semantic Conventions for *GraphQL Server*. * [HBase](hbase.md): Semantic Conventions for *HBase*. * [MongoDB](mongodb.md): Semantic Conventions for *MongoDB*. * [MSSQL](mssql.md): Semantic Conventions for *MSSQL*. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 50ff735718..d5c2e54d32 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -215,7 +215,6 @@ More specific Semantic Conventions are defined for the following database techno * [Cosmos DB](cosmosdb.md): Semantic Conventions for *Microsoft Cosmos DB*. * [CouchDB](couchdb.md): Semantic Conventions for *CouchDB*. * [Elasticsearch](elasticsearch.md): Semantic Conventions for *Elasticsearch*. -* [GraphQL](graphql.md): Semantic Conventions for *GraphQL Server*. * [HBase](hbase.md): Semantic Conventions for *HBase*. * [MongoDB](mongodb.md): Semantic Conventions for *MongoDB*. * [MSSQL](mssql.md): Semantic Conventions for *MSSQL*. diff --git a/docs/database/graphql.md b/docs/graphql/graphql-spans.md similarity index 100% rename from docs/database/graphql.md rename to docs/graphql/graphql-spans.md From 1e7bb0e4626c2ebb4b3032b8449dc39464d589b7 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:39:26 +0100 Subject: [PATCH 355/482] add remaining url fields to the registry (#496) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/url-ecs.yaml | 22 +++++++++ docs/attributes-registry/url.md | 28 +++++++++-- model/registry/url.yaml | 86 +++++++++++++++++++++++++++++---- 3 files changed, 122 insertions(+), 14 deletions(-) create mode 100755 .chloggen/url-ecs.yaml diff --git a/.chloggen/url-ecs.yaml b/.chloggen/url-ecs.yaml new file mode 100755 index 0000000000..1c61cb40c3 --- /dev/null +++ b/.chloggen/url-ecs.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: url + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add remaining ECS fields to the url namespace + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [496] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index c7a22357b7..8c161e6648 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -9,15 +9,35 @@ linkTitle: URL | Attribute | Type | Description | Examples | |---|---|---|---| +| `url.domain` | string | Domain extracted from the `url.full`, such as "opentelemetry.io". [1] | `www.foo.bar`; `opentelemetry.io`; `3.12.167.2`; `[1080:0:0:0:8:800:200C:417A]` | +| `url.extension` | string | The file extension extracted from the `url.full`, excluding the leading dot. [2] | `png`; `gz` | | `url.fragment` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | -| `url.full` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | +| `url.full` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | +| `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | | `url.path` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | -| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | +| `url.port` | int | Port extracted from the `url.full` | `443` | +| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [5] | `q=OpenTelemetry` | +| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [6] | `example.com`; `foo.co.uk` | | `url.scheme` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | +| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [7] | `east`; `sub2.sub1` | +| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [8] | `com`; `co.uk` | -**[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +**[1]:** In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. + +**[2]:** The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions `example.tar.gz`, only the last one should be captured `gz`, not `tar.gz`. + +**[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. -**[2]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[4]:** In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. +`url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. + +**[5]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + +**[6]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for "foo.example.com" is "example.com". Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". + +**[7]:** The subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. + +**[8]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). \ No newline at end of file diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 985ca9123f..65dc2602bc 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -4,11 +4,30 @@ groups: type: attribute_group prefix: url attributes: - - id: scheme + - id: domain + type: string + brief: > + Domain extracted from the `url.full`, such as "opentelemetry.io". + note: > + In some cases a URL may refer to an IP and/or port directly, + without a domain name. In this case, the IP address would go to the domain field. + If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) + enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. + examples: ["www.foo.bar", "opentelemetry.io", "3.12.167.2", "[1080:0:0:0:8:800:200C:417A]"] + - id: extension + type: string + brief: > + The file extension extracted from the `url.full`, excluding the leading dot. + note: > + The file extension is only set if it exists, as not every url has a file extension. + When the file name has multiple extensions `example.tar.gz`, only the last one should be captured `gz`, not `tar.gz`. + examples: [ "png", "gz" ] + - id: fragment stability: stable type: string - brief: 'The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.' - examples: ["https", "ftp", "telnet"] + brief: > + The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + examples: ["SemConv"] - id: full stability: stable type: string @@ -23,19 +42,66 @@ groups: `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] + - id: original + type: string + brief: > + Unmodified original URL as seen in the event source. + note: > + In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often + just represented as a path. This field is meant to represent the URL as it was observed, complete or not. + + `url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. + In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. + examples: ["https://www.foo.bar/search?q=OpenTelemetry#SemConv", "search?q=OpenTelemetry"] - id: path stability: stable type: string - brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' - examples: ['/search'] + brief: > + The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + examples: ["/search"] + - id: port + type: int + brief: > + Port extracted from the `url.full` + examples: [443] - id: query stability: stable type: string - brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' + brief: > + The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component examples: ["q=OpenTelemetry"] - note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - - id: fragment + note: > + Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + - id: registered_domain + type: string + brief: > + The highest registered url domain, stripped of the subdomain. + examples: ["example.com", "foo.co.uk"] + note: > + This value can be determined precisely with the [public suffix list](http://publicsuffix.org). + For example, the registered domain for "foo.example.com" is "example.com". + Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". + - id: scheme stability: stable type: string - brief: 'The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component' - examples: ["SemConv"] + brief: > + The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + examples: ["https", "ftp", "telnet"] + - id: subdomain + type: string + brief: > + The subdomain portion of a fully qualified domain name includes all of the names except the host name + under the registered_domain. In a partially qualified domain, or if the the qualification level of the + full name cannot be determined, subdomain contains all of the names below the registered domain. + examples: ["east", "sub2.sub1"] + note: > + The subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, + such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. + - id: top_level_domain + type: string + brief: > + The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. + For example, the top level domain for example.com is `com`. + examples: ["com", "co.uk"] + note: > + This value can be determined precisely with the [public suffix list](http://publicsuffix.org). From 096596b200faeefdca7e27e2ef60113f908eafbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stef=C3=A1n=20J=C3=B6kull=20Sigur=C3=B0arson?= Date: Thu, 22 Feb 2024 12:51:32 +0000 Subject: [PATCH 356/482] Adding `messaging.rabbitmq.message.delivery_tag` to the list of RabbitMQ specific tags (#433) Co-authored-by: Liudmila Molkova --- .chloggen/433.yaml | 4 ++++ docs/attributes-registry/messaging.md | 1 + docs/messaging/rabbitmq.md | 1 + model/registry/messaging.yaml | 7 +++++++ model/trace/messaging.yaml | 4 ++++ 5 files changed, 17 insertions(+) create mode 100644 .chloggen/433.yaml diff --git a/.chloggen/433.yaml b/.chloggen/433.yaml new file mode 100644 index 0000000000..0ca14de923 --- /dev/null +++ b/.chloggen/433.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: messaging +note: Add `messaging.rabbitmq.message.delivery_tag`` to the list of RabbitMQ specific tags +issues: [433] diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 2ec5ad6c2d..e53250e0c4 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -106,6 +106,7 @@ size should be used. | Attribute | Type | Description | Examples | |---|---|---|---| | `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | +| `messaging.rabbitmq.message.delivery_tag` | int | RabbitMQ message delivery tag | `123` | ## RocketMQ Attributes diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 1c762c4386..1c8f2ec8cc 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -21,6 +21,7 @@ In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | +| [`messaging.rabbitmq.message.delivery_tag`](../attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | Conditionally Required: When available. | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 868df05065..33d2d2ac4f 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -156,6 +156,13 @@ groups: RabbitMQ message routing key. examples: 'myKey' tag: tech-specific-rabbitmq + - id: rabbitmq.message.delivery_tag + type: int + brief: > + RabbitMQ message delivery tag + examples: 123 + tag: tech-specific-rabbitmq + - id: rocketmq.client_group type: string brief: > diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index cc980de321..6252c0830b 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -102,6 +102,10 @@ groups: requirement_level: conditionally_required: If not empty. tag: tech-specific-rabbitmq + - ref: messaging.rabbitmq.message.delivery_tag + requirement_level: + conditionally_required: When available. + tag: tech-specific-rabbitmq - id: messaging.kafka type: attribute_group From 4362b16491184db55fa30c456a20a567d62d8249 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 23 Feb 2024 09:51:10 -0500 Subject: [PATCH 357/482] Add Alexandra to approver list. (#766) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f2b46980c0..89c9df4055 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/open-telemetry/teams/specs-semconv-approvers)): +- [Alexandra Konrad](https://github.com/trisch-me), Elastic - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian - [Johannes Tax](https://github.com/pyohannes), Grafana Labs From b825ce1b93c39abd628345d792f4e09ece8d2c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraci=20Paix=C3=A3o=20Kr=C3=B6hling?= Date: Fri, 23 Feb 2024 20:02:08 +0100 Subject: [PATCH 358/482] Define a common algorithm for service.instance.id (#312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Juraci Paixão Kröhling Co-authored-by: Josh Suereth --- .chloggen/service-instance-id.yaml | 4 +++ docs/resource/README.md | 29 +++++++++++++++-- model/resource/service_experimental.yaml | 41 ++++++++++++++++-------- 3 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 .chloggen/service-instance-id.yaml diff --git a/.chloggen/service-instance-id.yaml b/.chloggen/service-instance-id.yaml new file mode 100644 index 0000000000..34acc9cf03 --- /dev/null +++ b/.chloggen/service-instance-id.yaml @@ -0,0 +1,4 @@ +change_type: 'enhancement' +component: resource +note: Define a common algorithm for `service.instance.id`. +issues: [312] diff --git a/docs/resource/README.md b/docs/resource/README.md index c67b8f3517..5dd529d264 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -99,10 +99,35 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `service.instance.id` | string | The string ID of the service instance. [1] | `my-k8s-pod-deployment-1`; `627cc493-f310-47de-96bd-71410b7dec09` | Recommended | +| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | Recommended | | `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | Recommended | -**[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent and stay the same for the lifetime of the service instance, however it is acceptable that the ID is ephemeral and changes during important lifetime events for the service (e.g. service restarts). If the service has no inherent unique ID that can be used as the value of this attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). +**[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words +`service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to +distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled +service). + +Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC +4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of +this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and +SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + +UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is +needed. Similar to what can be seen in the man page for the +[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying +data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it +or not via another resource attribute. + +For applications running behind an application server (like unicorn), we do not recommend using one identifier +for all processes participating in the application. Instead, it's recommended each division (e.g. a worker +thread in unicorn) to have its own instance.id. + +It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the +service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will +likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. +However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance +for that telemetry. This is typically the case for scraping receivers, as they know the target address and +port. **[2]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index 43c869ee35..99ed64f024 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -22,16 +22,31 @@ groups: type: string brief: > The string ID of the service instance. - note: > - MUST be unique for each instance of the same `service.namespace,service.name` pair - (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). - The ID helps to distinguish instances of the same service that exist at the same time - (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent - and stay the same for the lifetime of the service instance, however it is acceptable that - the ID is ephemeral and changes during important lifetime events for the service - (e.g. service restarts). - If the service has no inherent unique ID that can be used as the value of this attribute - it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID - (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 - for more recommendations). - examples: ["my-k8s-pod-deployment-1", "627cc493-f310-47de-96bd-71410b7dec09"] + note: | + MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words + `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to + distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + service). + + Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC + 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of + this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and + SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + + UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + needed. Similar to what can be seen in the man page for the + [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying + data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it + or not via another resource attribute. + + For applications running behind an application server (like unicorn), we do not recommend using one identifier + for all processes participating in the application. Instead, it's recommended each division (e.g. a worker + thread in unicorn) to have its own instance.id. + + It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the + service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will + likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance + for that telemetry. This is typically the case for scraping receivers, as they know the target address and + port. + examples: ["627cc493-f310-47de-96bd-71410b7dec09"] From 4f434da570cda9c6ab7af3b5cfb797cfd2cbcd97 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:18:54 +0100 Subject: [PATCH 359/482] [chore] Attempt two: Avoid running stale bot on issues (#771) --- .github/workflows/stale-pr.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/stale-pr.yml b/.github/workflows/stale-pr.yml index c1b7f9370e..d5259a6140 100644 --- a/.github/workflows/stale-pr.yml +++ b/.github/workflows/stale-pr.yml @@ -14,5 +14,9 @@ jobs: close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' exempt-pr-labels: 'bug,work in progress,experts needed' exempt-draft-pr: true + # opt out of defaults to avoid marking issues as stale + days-before-stale: -1 + days-before-close: -1 + # overrides the above only for pull requests days-before-pr-stale: 15 days-before-pr-close: 7 From 399978fb27615d7751964b79bc43ad87fe290728 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 27 Feb 2024 11:36:26 -0500 Subject: [PATCH 360/482] Add Liudmila to semconv maintainers. (#776) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89c9df4055..c200f36972 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/ope - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian - [Johannes Tax](https://github.com/pyohannes), Grafana Labs -- [Liudmila Molkova](https://github.com/lmolkova), Microsoft - [Sean Marciniak](https://github.com/MovieStoreGuy), Atlassian - [Ted Young](https://github.com/tedsuo), Lightstep @@ -34,6 +33,7 @@ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs - [Armin Ruech](https://github.com/arminru), Dynatrace - [Joao Grassi](https://github.com/joaopgrassi), Dynatrace - [Josh Suereth](https://github.com/jsuereth), Google +- [Liudmila Molkova](https://github.com/lmolkova), Microsoft - [Reiley Yang](https://github.com/reyang), Microsoft _Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)._ From f98fc43b1806e5a150a9a0fe266069e83b1b3af6 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 28 Feb 2024 07:24:34 -0800 Subject: [PATCH 361/482] [chore] Bring a few attributes that were removed back (as deprecated) (#770) --- docs/attributes-registry/network.md | 2 +- model/registry/deprecated/container.yaml | 10 ++++++++++ model/registry/deprecated/k8s.yaml | 10 ++++++++++ model/registry/deprecated/network.yaml | 2 +- model/registry/deprecated/system.yaml | 20 ++++++++++++++++++++ 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 model/registry/deprecated/container.yaml create mode 100644 model/registry/deprecated/k8s.yaml create mode 100644 model/registry/deprecated/system.yaml diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 9c388f4d75..a06417c9dc 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -100,7 +100,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. ## Deprecated Network Attributes - + | Attribute | Type | Description | Examples | |---|---|---|---| | `net.host.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`. | `example.com` | diff --git a/model/registry/deprecated/container.yaml b/model/registry/deprecated/container.yaml new file mode 100644 index 0000000000..8c19e64f8b --- /dev/null +++ b/model/registry/deprecated/container.yaml @@ -0,0 +1,10 @@ +groups: + - id: attributes.container.deprecated + type: attribute_group + brief: "Describes deprecated container attributes." + attributes: + - id: container.labels + type: template[string] + examples: [ 'container.label.app=nginx' ] + brief: "Deprecated, use `container.label` instead." + deprecated: "Replaced by `container.label`." diff --git a/model/registry/deprecated/k8s.yaml b/model/registry/deprecated/k8s.yaml new file mode 100644 index 0000000000..5793257d7f --- /dev/null +++ b/model/registry/deprecated/k8s.yaml @@ -0,0 +1,10 @@ +groups: + - id: attributes.k8s.deprecated + type: attribute_group + brief: "Describes deprecated k8s attributes." + attributes: + - id: k8s.pod.labels + type: template[string] + examples: ['k8s.pod.label.app=my-app'] + brief: "Deprecated, use `k8s.pod.label` instead." + deprecated: "Replaced by `k8s.pod.label`." diff --git a/model/registry/deprecated/network.yaml b/model/registry/deprecated/network.yaml index 135373fa09..63e3959d7e 100644 --- a/model/registry/deprecated/network.yaml +++ b/model/registry/deprecated/network.yaml @@ -1,5 +1,5 @@ groups: - - id: network-deprecated + - id: attributes.network.deprecated prefix: net type: attribute_group brief: > diff --git a/model/registry/deprecated/system.yaml b/model/registry/deprecated/system.yaml new file mode 100644 index 0000000000..2356ebc562 --- /dev/null +++ b/model/registry/deprecated/system.yaml @@ -0,0 +1,20 @@ +groups: + - id: attributes.system.deprecated + type: attribute_group + brief: "Deprecated system attributes." + attributes: + - id: system.processes.status + type: + allow_custom_values: true + members: + - id: running + value: 'running' + - id: sleeping + value: 'sleeping' + - id: stopped + value: 'stopped' + - id: defunct + value: 'defunct' + brief: "Deprecated, use `system.process.status` instead." + deprecated: "Replaced by `system.process.status`." + examples: ["running"] From bdbcf68a9b29246948b69f7db42b9fbf70510a7b Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 28 Feb 2024 07:34:24 -0800 Subject: [PATCH 362/482] Double backslash -> Single backslash (#779) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- docs/resource/host.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/resource/host.md b/docs/resource/host.md index 9dfdd5d2b5..da04a28970 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -63,12 +63,12 @@ When collecting `host.id` for non-containerized systems non-privileged lookups of the machine id are preferred. SDK detector implementations MUST use the sources listed below to obtain the machine id. -| OS | Primary | Fallback | -|---------|-------------------------------------------------------------------------------------|----------------------------------------| -| Linux | contents of `/etc/machine-id` | contents of `/var/lib/dbus/machine-id` | -| BSD | contents of `/etc/hostid` | output of `kenv -q smbios.system.uuid` | -| MacOS | `IOPlatformUUID` line from the output of `ioreg -rd1 -c "IOPlatformExpertDevice"` | - | -| Windows | `MachineGuid` from registry `HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography` | - | +| OS | Primary | Fallback | +|---------|-----------------------------------------------------------------------------------|----------------------------------------| +| Linux | contents of `/etc/machine-id` | contents of `/var/lib/dbus/machine-id` | +| BSD | contents of `/etc/hostid` | output of `kenv -q smbios.system.uuid` | +| MacOS | `IOPlatformUUID` line from the output of `ioreg -rd1 -c "IOPlatformExpertDevice"` | - | +| Windows | `MachineGuid` from registry `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography` | - | ### Privileged Machine ID Lookup From b8e5dada01b345d6dea186b5c5aec0bdafafc038 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 28 Feb 2024 16:50:21 -0500 Subject: [PATCH 363/482] [chore] URL attributes: consistently use code font for URLs and URL parts (#783) --- docs/attributes-registry/url.md | 4 ++-- model/registry/url.yaml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index 8c161e6648..b33926756b 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -35,9 +35,9 @@ linkTitle: URL **[5]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. -**[6]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for "foo.example.com" is "example.com". Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". +**[6]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. -**[7]:** The subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. +**[7]:** The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. **[8]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). \ No newline at end of file diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 65dc2602bc..fdde8d2de0 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -79,8 +79,8 @@ groups: examples: ["example.com", "foo.co.uk"] note: > This value can be determined precisely with the [public suffix list](http://publicsuffix.org). - For example, the registered domain for "foo.example.com" is "example.com". - Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk". + For example, the registered domain for `foo.example.com` is `example.com`. + Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. - id: scheme stability: stable type: string @@ -95,8 +95,8 @@ groups: full name cannot be determined, subdomain contains all of the names below the registered domain. examples: ["east", "sub2.sub1"] note: > - The subdomain portion of "www.east.mydomain.co.uk" is "east". If the domain has multiple levels of subdomain, - such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period. + The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, + such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. - id: top_level_domain type: string brief: > From ca61ac1b2ba652ec21155676172c777e1979eb7b Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 29 Feb 2024 07:31:12 -0800 Subject: [PATCH 364/482] [chore] Mark otel.* attributes as stable in yaml (#784) --- model/scope/exporter/exporter.yaml | 2 ++ model/trace/exporter/exporter.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/model/scope/exporter/exporter.yaml b/model/scope/exporter/exporter.yaml index 3bbf3fe073..0a47d625a9 100644 --- a/model/scope/exporter/exporter.yaml +++ b/model/scope/exporter/exporter.yaml @@ -8,10 +8,12 @@ groups: type: string brief: The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). examples: ['io.opentelemetry.contrib.mongodb'] + stability: stable - id: version type: string brief: The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). examples: ['1.0.0'] + stability: stable - id: otel.library prefix: otel.library type: resource diff --git a/model/trace/exporter/exporter.yaml b/model/trace/exporter/exporter.yaml index 2989475d71..23b5f921b3 100644 --- a/model/trace/exporter/exporter.yaml +++ b/model/trace/exporter/exporter.yaml @@ -15,7 +15,9 @@ groups: value: ERROR brief: 'The operation contains an error.' brief: Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + stability: stable - id: status_description type: string brief: "Description of the Status if it has a value, otherwise not set." examples: ['resource not found'] + stability: stable From 6659dfabfe35ce3f96a470eaa6a3678fbfb0a4d6 Mon Sep 17 00:00:00 2001 From: Tyler Benson Date: Thu, 29 Feb 2024 20:24:31 -0500 Subject: [PATCH 365/482] Fix problem in `xray-lambda` propagator definition (#778) Co-authored-by: Raphael Philipe Mendes da Silva Co-authored-by: Trask Stalnaker Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/778.yaml | 22 +++++++++++++++++++++ docs/faas/aws-lambda.md | 42 ++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 .chloggen/778.yaml diff --git a/.chloggen/778.yaml b/.chloggen/778.yaml new file mode 100644 index 0000000000..03c1db8225 --- /dev/null +++ b/.chloggen/778.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: aws-lambda + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Fix problem in `xray-lambda` propagator definition + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [778] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index c8a568b378..45b68d67f3 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -70,37 +70,49 @@ Users MUST be able to [configure the propagator](#xray-lambda-propagator-configu SDK's that have instrumentation for AWS Lambda SHOULD provide an additional propagator alongside the X-Ray propagator that can [be configured](#xray-lambda-propagator-configuration) via the `OTEL_PROPAGATORS` environment variable setting as `xray-lambda`. -This propagator ignores the provided carrier instance and instead attempts to propagate the span context from the `_X_AMZN_TRACE_ID` environment variable -(and the `com.amazonaws.xray.traceHeader` system property for Java Lambda functions with priority given to the system property if set). - -To avoid potential issues when extracting with an active span context, the `xray-lambda` propagator SHOULD check if the provided context already has an active span context. If found, the propagator SHOULD return the provided context unmodified. - -Example pseudo implementation: +This propagator is expected to replace the `xray` propagator in the `OTEL_PROPAGATORS` list. The behavior for this propagator is described in pseudo code below. ``` extract(context, carrier) { + xrayContext = xrayPropagator.extract(context, carrier) + + // To avoid potential issues when extracting with an active span context (such as with a span link), + // the `xray-lambda` propagator SHOULD check if the provided context already has an active span context. + // If found, the propagator SHOULD just return the extract result of the `xray` propagator. if (Span.fromContext(context).getSpanContext().isValid()) - return context + return xrayContext - traceHeader = getEnvironment("_X_AMZN_TRACE_ID"); + // If xray-lambda environment variable not set, return the xray extract result. + traceHeader = getEnvironment("_X_AMZN_TRACE_ID") if (isEmptyOrNull(traceHeader)) - return context + return xrayContext - return xrayPropagator.extract(context, ["_X_AMZN_TRACE_ID": traceHeader]) + // Apply the xray propagator using the span context contained in the xray-lambda environment variable. + return xrayPropagator.extract(xrayContext, ["X-Amzn-Trace-Id": traceHeader]) } ``` +*Note:* Java implementations should use the system property value of the key `com.amazonaws.xray.traceHeader` +instead of the environment variable if the system property is not empty. + #### `xray-lambda` Propagator Configuration -Since propagators are invoked in order, users would give priority to X-Ray's "Active Tracing" span context by setting the environment variable: +**When reporting spans to AWS X-Ray** from AWS Lambda, the `xray-lambda` propagator SHOULD replace the `xray` propagator in the `OTEL_PROPAGATORS` configuration. Including both will prevent `xray-lambda` from functioning properly. + +Example valid configuration when reporting spans to AWS X-Ray: + +- `OTEL_PROPAGATORS=tracecontext,baggage,xray-lambda` + +Example invalid configurations: -`OTEL_PROPAGATORS=tracecontext,baggage,xray,xray-lambda` +- `OTEL_PROPAGATORS=tracecontext,baggage,xray,xray-lambda` +- `OTEL_PROPAGATORS=tracecontext,baggage,xray-lambda,xray` -To avoid broken traces, if OpenTelemetry is reporting traces to another system besides AWS X-Ray, users should either omit `xray-lambda` or add it to the beginning: +**When OpenTelemetry is reporting traces to another system besides AWS X-Ray**, users SHOULD NOT use `xray-lambda` or reported traces will be broken. -`OTEL_PROPAGATORS=xray-lambda,tracecontext,baggage,xray` +Example valid configuration when OpenTelemetry is reporting traces to another system besides AWS X-Ray: -*Note: The `xray-lambda` propagator can only `extract` context. The `inject` operation MUST be a no-op.* +- `OTEL_PROPAGATORS=tracecontext,baggage,xray` ## API Gateway From e4930d38613994ce6df0a88bcd5adbe4245c34dc Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 1 Mar 2024 00:42:58 -0800 Subject: [PATCH 366/482] Update Azure messaging: settlement attributes and span names (#697) Co-authored-by: Johannes Tax Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/697.yaml | 7 +++++++ docs/attributes-registry/messaging.md | 10 ++++++++++ docs/messaging/azure-messaging.md | 19 +++++++++++++++++++ model/registry/messaging.yaml | 20 ++++++++++++++++++++ model/trace/messaging.yaml | 3 +++ 5 files changed, 59 insertions(+) create mode 100644 .chloggen/697.yaml diff --git a/.chloggen/697.yaml b/.chloggen/697.yaml new file mode 100644 index 0000000000..e6bb861718 --- /dev/null +++ b/.chloggen/697.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: messaging + +note: Clarifies span names for Azure messaging systems and adds `messaging.servicebus.disposition_status attribute`. + +issues: [697] diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index e53250e0c4..c94f5aa3cb 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -157,6 +157,16 @@ size should be used. | Attribute | Type | Description | Examples | |---|---|---|---| | `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | +| `messaging.servicebus.disposition_status` | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | | `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | | `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | + +`messaging.servicebus.disposition_status` 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 | +|---|---| +| `complete` | Message is completed | +| `abandon` | Message is abandoned | +| `dead_letter` | Message is sent to dead letter queue | +| `defer` | Message is deferred | diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 35e17ec2c3..e7317d7b3a 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -12,6 +12,15 @@ The Semantic Conventions for [Azure Service Bus](https://learn.microsoft.com/azu `messaging.system` MUST be set to `"servicebus"`. +### Span names + +The span name SHOULD follow [the general messaging span name pattern](../messaging/azure-messaging.md): it SHOULD start with the messaging destination name (Event Hubs queue or topic name) and contain a low-cardinality name of the operation the span describes: + +- Spans names for `settle` operations SHOULD follow the ` {messaging.servicebus.disposition_status}` pattern. + For example, `my-queue complete` or `my-queue abandon`. +- Spans names for `publish` operations SHOULD follow the ` send` pattern. +- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. + ### Span attributes The following additional attributes are defined: @@ -19,6 +28,7 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.servicebus.destination.subscription_name`](../attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | Conditionally Required: If messages are received from the subscription. | +| [`messaging.servicebus.disposition_status`](../attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | Conditionally Required: if and only if `messaging.operation` is `settle`. | | [`messaging.servicebus.message.delivery_count`](../attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | Conditionally Required: [1] | | [`messaging.servicebus.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | @@ -29,6 +39,15 @@ The following additional attributes are defined: `messaging.system` MUST be set to `"eventhubs"`. +### Span names + +The span name SHOULD follow the [general messaging span name pattern](../messaging/azure-messaging.md): it SHOULD start with the messaging destination name (Event Hubs namespace) and +contain a low-cardinality name of an operation the span describes: + +- Spans for `settle` operations SHOULD follow the ` checkpoint` pattern (matching Event Hubs terminology). +- Spans names for `publish` operations SHOULD follow the ` send` pattern. +- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. + ### Span attributes The following additional attributes are defined: diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 33d2d2ac4f..d05b5cc71d 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -298,6 +298,26 @@ groups: The name of the subscription in the topic messages are received from. examples: "mySubscription" tag: tech-specific-servicebus + - id: servicebus.disposition_status + brief: > + Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). + type: + allow_custom_values: true + members: + - id: complete + value: 'complete' + brief: 'Message is completed' + - id: abandon + value: 'abandon' + brief: 'Message is abandoned' + - id: dead_letter + value: 'dead_letter' + brief: 'Message is sent to dead letter queue' + - id: defer + value: 'defer' + brief: 'Message is deferred' + stability: experimental + tag: tech-specific-servicebus - id: eventhubs.message.enqueued_time type: int brief: > diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 6252c0830b..f5b08b74f8 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -181,6 +181,9 @@ groups: - ref: messaging.servicebus.destination.subscription_name requirement_level: conditionally_required: If messages are received from the subscription. + - ref: messaging.servicebus.disposition_status + requirement_level: + conditionally_required: if and only if `messaging.operation` is `settle`. - id: messaging.eventhubs type: attribute_group extends: messaging From 9e90894cfac44045f1bcddb6169023af01204ad4 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:53:51 +0100 Subject: [PATCH 367/482] [chore] Add recommendation for lowercase attribute names (#788) --- docs/general/attribute-naming.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index b84f71f03e..f0eec71dbb 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -31,6 +31,8 @@ particular programming language or wire format._ Names SHOULD follow these rules: +- Names SHOULD be lowercase. + - Use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example `service.version` denotes the service version where `service` is the namespace and `version` is an attribute in that namespace. From 58c2705b7c93ea529d11db991e7ae4ad175473e1 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 1 Mar 2024 04:42:23 -0800 Subject: [PATCH 368/482] Merge DB connection-level and call-level attributes (#780) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/780.yaml | 4 + docs/database/cassandra.md | 4 +- docs/database/cosmosdb.md | 4 +- docs/database/couchdb.md | 4 +- docs/database/database-metrics.md | 18 ++--- docs/database/database-spans.md | 57 ++++++-------- docs/database/elasticsearch.md | 4 +- docs/database/hbase.md | 4 +- docs/database/mongodb.md | 4 +- docs/database/mssql.md | 7 +- docs/database/redis.md | 4 +- docs/database/sql.md | 5 +- model/messaging-common.yaml | 2 - model/metrics/database-metrics.yaml | 2 +- model/trace/database.yaml | 113 +++++++++++----------------- model/trace/messaging.yaml | 4 - 16 files changed, 106 insertions(+), 134 deletions(-) create mode 100644 .chloggen/780.yaml diff --git a/.chloggen/780.yaml b/.chloggen/780.yaml new file mode 100644 index 0000000000..626e967153 --- /dev/null +++ b/.chloggen/780.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: db +note: Merge DB connection-level and call-level attributes tables +issues: [780] diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 0fcc385c82..6193ee0d21 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -12,9 +12,9 @@ described on this page. `db.system` MUST be set to `"cassandra"`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | Recommended | diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 1862a1efa7..51fc4ba2f9 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -11,13 +11,13 @@ extend and override the [Database Semantic Conventions](database-spans.md) that describe common database operations attributes in addition to the Semantic Conventions described on this page. -## Call-level attributes +## Attributes `db.system` MUST be set to `"cosmosdb"`. Cosmos DB instrumentation includes call-level (public API) surface spans and network spans. Depending on the connection mode (Gateway or Direct), network-level spans may also be created. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | Recommended | diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 8025aacd08..5ad2aae166 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -12,9 +12,9 @@ described on this page. `db.system` MUST be set to `"couchdb"`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | Conditionally Required: If `db.statement` is not applicable. | diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 54c9e92927..1f21ddf074 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -52,7 +52,7 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | | `state` | string | The state of a connection in the pool | `idle` | Required | `state` MUST be one of the following: @@ -75,7 +75,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.idle.min` @@ -91,7 +91,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.max` @@ -107,7 +107,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.pending_requests` @@ -123,7 +123,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.timeouts` @@ -139,7 +139,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.create_time` @@ -155,7 +155,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.wait_time` @@ -171,7 +171,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | ### Metric: `db.client.connections.use_time` @@ -187,7 +187,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index d5c2e54d32..e8e224fc74 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -10,9 +10,8 @@ linkTitle: Client Calls -- [Connection-level attributes](#connection-level-attributes) +- [Common attributes](#common-attributes) * [Notes and well-known identifiers for `db.system`](#notes-and-well-known-identifiers-for-dbsystem) -- [Call-level attributes](#call-level-attributes) - [Semantic Conventions for specific database technologies](#semantic-conventions-for-specific-database-technologies) @@ -62,38 +61,51 @@ It is not recommended to attempt any client-side parsing of `db.statement` just they should only be used if the library being instrumented already provides them. When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. -## Connection-level attributes +Span that describes database call SHOULD cover the duration of the corresponding call as if it was observed by the caller (such as client application). +For example, if a transient issue happened and was retried within this database call, the corresponding span should cover the duration of the logical operation +with all retries. + +## Common attributes These attributes will usually be the same for all operations performed over the same database connection. Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.connection_string`](../attributes-registry/db.md) | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: If different from the `server.address` | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | +| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | +| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | Recommended | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Conditionally Required: [8] | -**[1]:** The value SHOULD be normalized to lowercase. +**[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + +**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + +**[3]:** Should be collected by default only if there is sanitization that excludes sensitive information. + +**[4]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[2]:** The value SHOULD be normalized to lowercase. +**[5]:** The value SHOULD be normalized to lowercase. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[5]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. `db.system` 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. @@ -187,25 +199,6 @@ Back ends could, for example, use the provided identifier to determine the appro When additional attributes are added that only apply to a specific DBMS, its identifier SHOULD be used as a namespace in the attribute key as for the attributes in the sections below. -## Call-level attributes - -These attributes may be different for each operation performed, even if the same connection is used for multiple operations. -Usually only one `db.name` will be used per connection though. - - -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | -| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | -| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | - -**[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). - -**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. - -**[3]:** Should be collected by default only if there is sanitization that excludes sensitive information. - - ## Semantic Conventions for specific database technologies More specific Semantic Conventions are defined for the following database technologies: diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 156e7cb15f..ccea388ecc 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -21,9 +21,9 @@ name, as the path could contain dynamic values. The endpoint id is the `name` fi [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json). If the endpoint id is not available, the span name SHOULD be the `http.request.method`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 47b8acd2c5..50675d6b91 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -12,9 +12,9 @@ described on this page. `db.system` MUST be set to `"hbase"`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | Conditionally Required: If applicable. | diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 10fdbb785e..ebb2a5a883 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -12,9 +12,9 @@ described on this page. `db.system` MUST be set to `"mongodb"`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | Required | diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 239be3960b..6eeaf08030 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -12,15 +12,18 @@ described on this page. `db.system` MUST be set to `"mssql"`. -## Connection-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.jdbc.driver_classname`](../attributes-registry/db.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | | [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [2] | `public.users`; `customers` | Recommended | **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +**[2]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index 2614e494fa..62637688e3 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -12,9 +12,9 @@ described on this page. `db.system` MUST be set to `"redis"`. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | Conditionally Required: If other than the default database (`0`). | diff --git a/docs/database/sql.md b/docs/database/sql.md index 6483e36374..5eaddacf39 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -10,11 +10,12 @@ The SQL databases Semantic Conventions extend and override the [Database Semanti that describe common database operations attributes in addition to the Semantic Conventions described on this page. -## Call-level attributes +## Attributes - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`db.jdbc.driver_classname`](../attributes-registry/db.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | | [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | Recommended | **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/model/messaging-common.yaml b/model/messaging-common.yaml index 92bddd7924..f5505a0baf 100644 --- a/model/messaging-common.yaml +++ b/model/messaging-common.yaml @@ -20,6 +20,4 @@ groups: examples: ['amqp', 'mqtt'] requirement_level: conditionally_required: Only for messaging systems and frameworks that support more than one protocol. - tag: connection-level - ref: network.protocol.version - tag: connection-level diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index 3df6d86a2c..097ff79abf 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -20,7 +20,7 @@ groups: brief: > The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, - then the [db.connection_string](/docs/database/database-spans.md#connection-level-attributes) + then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used examples: ["myDataSource"] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index a896527ac7..8637fbed28 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -6,95 +6,80 @@ groups: span_kind: client attributes: - ref: db.system - tag: connection-level requirement_level: required - ref: db.connection_string - tag: connection-level - ref: db.user - tag: connection-level - - ref: db.jdbc.driver_classname - tag: connection-level-tech-specific - ref: db.name - tag: call-level requirement_level: conditionally_required: If applicable. - ref: db.statement - tag: call-level requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. - ref: db.operation - tag: call-level requirement_level: conditionally_required: If `db.statement` is not applicable. - ref: server.address - tag: connection-level brief: > Name of the database host. - ref: server.port - tag: connection-level requirement_level: conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - ref: network.peer.address - tag: connection-level - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. - tag: connection-level - ref: network.transport - tag: connection-level - ref: network.type - tag: connection-level - ref: db.instance.id - tag: connection-level requirement_level: recommended: If different from the `server.address` - id: db.mssql type: span - extends: db + extends: db.sql brief: > - Connection-level attributes for Microsoft SQL Server + Attributes for Microsoft SQL Server attributes: - ref: db.mssql.instance_name - tag: connection-level-tech-specific + tag: tech-specific - id: db.cassandra type: span extends: db brief: > - Call-level attributes for Cassandra + Attributes for Cassandra attributes: - ref: db.name - tag: call-level-tech-specific-cassandra + tag: tech-specific brief: > The keyspace name in Cassandra. examples: ["mykeyspace"] note: For Cassandra the `db.name` should be set to the Cassandra keyspace name. - ref: db.cassandra.page_size - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.consistency_level - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.table - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.idempotence - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.speculative_execution_count - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.coordinator.id - tag: call-level-tech-specific-cassandra + tag: tech-specific - ref: db.cassandra.coordinator.dc - tag: call-level-tech-specific-cassandra + tag: tech-specific - id: db.hbase type: span extends: db brief: > - Call-level attributes for HBase + Attributes for HBase attributes: - ref: db.name - tag: call-level-tech-specific + tag: tech-specific brief: > The HBase namespace. examples: ['mynamespace'] @@ -104,10 +89,10 @@ groups: type: span extends: db brief: > - Call-level attributes for CouchDB + Attributes for CouchDB attributes: - ref: db.operation - tag: call-level-tech-specific + tag: tech-specific brief: > The HTTP method + the target REST route. examples: ['GET /{db}/{docid}'] @@ -122,14 +107,14 @@ groups: type: span extends: db brief: > - Call-level attributes for Redis + Attributes for Redis attributes: - ref: db.redis.database_index requirement_level: conditionally_required: If other than the default database (`0`). - tag: call-level-tech-specific + tag: tech-specific - ref: db.statement - tag: call-level-tech-specific + tag: tech-specific brief: > The full syntax of the Redis CLI command. examples: ["HMSET myhash field1 'Hello' field2 'World'"] @@ -141,30 +126,30 @@ groups: type: span extends: db brief: > - Call-level attributes for MongoDB + Attributes for MongoDB attributes: - ref: db.mongodb.collection requirement_level: required - tag: call-level-tech-specific + tag: tech-specific - id: db.elasticsearch type: span extends: db brief: > - Call-level attributes for Elasticsearch + Attributes for Elasticsearch attributes: - ref: http.request.method requirement_level: required - tag: call-level-tech-specific + tag: tech-specific - ref: db.operation requirement_level: required brief: The endpoint identifier for the request. examples: [ 'search', 'ml.close_job', 'cat.aliases' ] - tag: call-level-tech-specific + tag: tech-specific - ref: url.full requirement_level: required examples: [ 'https://localhost:9200/index/_search?q=user.id:kimchy' ] - tag: call-level-tech-specific + tag: tech-specific - ref: db.statement requirement_level: recommended: > @@ -172,48 +157,50 @@ groups: sensitive information. brief: The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. examples: [ '"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"' ] - tag: call-level-tech-specific + tag: tech-specific - ref: server.address - tag: call-level-tech-specific + tag: tech-specific - ref: server.port - tag: call-level-tech-specific + tag: tech-specific - ref: db.elasticsearch.cluster.name requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. - tag: call-level-tech-specific + tag: tech-specific - ref: db.elasticsearch.node.name requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. - tag: call-level-tech-specific + tag: tech-specific - ref: db.elasticsearch.path_parts requirement_level: conditionally_required: when the url has dynamic values - tag: call-level-tech-specific + tag: tech-specific - id: db.sql type: span extends: 'db' brief: > - Call-level attributes for SQL databases + Attributes for SQL databases attributes: - ref: db.sql.table - tag: call-level-tech-specific + tag: tech-specific + - ref: db.jdbc.driver_classname + tag: tech-specific - id: db.cosmosdb type: span extends: db prefix: db.cosmosdb brief: > - Call-level attributes for Cosmos DB. + Attributes for Cosmos DB. attributes: - ref: db.cosmosdb.client_id - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.operation_type requirement_level: conditionally_required: when performing one of the operations in this list - tag: call-level-tech-specific + tag: tech-specific - ref: user_agent.original brief: 'Full user-agent string is generated by Cosmos DB SDK' note: > @@ -228,36 +215,26 @@ groups: Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). Default value is "NS". examples: ['cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|'] - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.connection_mode requirement_level: conditionally_required: if not `direct` (or pick gw as default) - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.container requirement_level: conditionally_required: if available - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.request_content_length - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.status_code requirement_level: conditionally_required: if response was received - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.sub_status_code requirement_level: conditionally_required: when response was received and contained sub-code. - tag: call-level-tech-specific + tag: tech-specific - ref: db.cosmosdb.request_charge requirement_level: conditionally_required: when available - tag: call-level-tech-specific - - - id: db.tech - type: span - brief: "Semantic convention group for specific technologies" - constraints: - - include: 'db.cassandra' - - include: 'db.redis' - - include: 'db.mongodb' - - include: 'db.sql' - - include: 'db.cosmosdb' + tag: tech-specific diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index f5b08b74f8..3a8543d540 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -82,15 +82,11 @@ groups: - ref: messaging.message.body.size - ref: server.address - ref: network.peer.address - tag: connection-level - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. - tag: connection-level - ref: network.transport - tag: connection-level - ref: network.type - tag: connection-level - id: messaging.rabbitmq type: attribute_group From 44690f11c7edf9b916f8486f9a4440b841312cb0 Mon Sep 17 00:00:00 2001 From: klauco Date: Sat, 2 Mar 2024 01:03:01 +0100 Subject: [PATCH 369/482] Allow url.path sanitization (#676) Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/allow-sanitizing-url-path.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/url.md | 22 ++++++++++++---------- docs/database/elasticsearch.md | 2 +- docs/http/http-spans.md | 14 ++++++++------ docs/url/url.md | 10 ++++++---- model/registry/url.yaml | 8 +++++--- 6 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 .chloggen/allow-sanitizing-url-path.yaml diff --git a/.chloggen/allow-sanitizing-url-path.yaml b/.chloggen/allow-sanitizing-url-path.yaml new file mode 100644 index 0000000000..29d4311168 --- /dev/null +++ b/.chloggen/allow-sanitizing-url-path.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: url + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Sensitive content provided in `url.full`, `url.path`, and `url.query` SHOULD be scrubbed when instrumentations can identify it. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [676] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index b33926756b..d2aa233eeb 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -14,13 +14,13 @@ linkTitle: URL | `url.fragment` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | | `url.full` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | | `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | -| `url.path` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | +| `url.path` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [5] | `/search` | | `url.port` | int | Port extracted from the `url.full` | `443` | -| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [5] | `q=OpenTelemetry` | -| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [6] | `example.com`; `foo.co.uk` | +| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | +| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | | `url.scheme` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | -| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [7] | `east`; `sub2.sub1` | -| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [8] | `com`; `co.uk` | +| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | +| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | **[1]:** In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. @@ -28,16 +28,18 @@ linkTitle: URL **[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. **[4]:** In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. `url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. -**[5]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[5]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. -**[6]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. +**[6]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. -**[7]:** The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. +**[7]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. -**[8]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). +**[8]:** The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. + +**[9]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). \ No newline at end of file diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index ccea388ecc..e7bd336158 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -69,7 +69,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. `http.request.method` 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. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 3e11eb8704..4b5edb5b99 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -246,7 +246,7 @@ The attribute value MUST consist of either multiple header values as an array of **[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): @@ -346,9 +346,9 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | | [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Required | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [7] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [8] | `http`; `https` | Required | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | Recommended | **[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. @@ -366,9 +366,11 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[7]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[7]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. -**[8]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. + +**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): diff --git a/docs/url/url.md b/docs/url/url.md index f9605574ee..77cdbf1109 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -27,15 +27,17 @@ This document defines semantic conventions that describe URL and its components. |---|---|---|---|---| | [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component | `/search` | Recommended | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [2] | `q=OpenTelemetry` | Recommended | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. -**[2]:** Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. +**[2]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. + +**[3]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. ## Sensitive information diff --git a/model/registry/url.yaml b/model/registry/url.yaml index fdde8d2de0..7e07ad7936 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -39,8 +39,8 @@ groups: `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. - `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) - and SHOULD NOT be validated or modified except for sanitizing purposes. + `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). + Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] - id: original type: string @@ -59,6 +59,8 @@ groups: brief: > The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component examples: ["/search"] + note: > + Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. - id: port type: int brief: > @@ -71,7 +73,7 @@ groups: The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component examples: ["q=OpenTelemetry"] note: > - Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. - id: registered_domain type: string brief: > From 19f2ba7d0c0b0adc1b9efb8ab189c5300e038e4d Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Mon, 4 Mar 2024 14:38:44 +0100 Subject: [PATCH 370/482] Add a "Process" operation for messaging (#700) Co-authored-by: Alex Hong <9397363+hongalex@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/700.yaml | 22 +++++++++++++++ docs/attributes-registry/messaging.md | 3 ++- docs/messaging/messaging-metrics.md | 25 ++++++++--------- docs/messaging/messaging-spans.md | 39 +++++++++++++++------------ model/metrics/messaging.yaml | 12 ++++----- model/registry/messaging.yaml | 9 ++++--- 6 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 .chloggen/700.yaml diff --git a/.chloggen/700.yaml b/.chloggen/700.yaml new file mode 100644 index 0000000000..5272119136 --- /dev/null +++ b/.chloggen/700.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: messaging + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add a "Process" spans and metrics for messaging + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [657] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index c94f5aa3cb..4d349029b7 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -60,7 +60,8 @@ size should be used. | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | | `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | -| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +| `process` | One or more messages are delivered to or processed by a consumer. | +| `settle` | One or more messages are settled. | `messaging.system` 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. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 63bb6b384e..d715d1100d 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -13,8 +13,8 @@ - [Consumer metrics](#consumer-metrics) * [Metric: `messaging.receive.duration`](#metric-messagingreceiveduration) * [Metric: `messaging.receive.messages`](#metric-messagingreceivemessages) - * [Metric: `messaging.deliver.duration`](#metric-messagingdeliverduration) - * [Metric: `messaging.deliver.messages`](#metric-messagingdelivermessages) + * [Metric: `messaging.process.duration`](#metric-messagingprocessduration) + * [Metric: `messaging.process.messages`](#metric-messagingprocessmessages) @@ -158,34 +158,35 @@ _Note: The need to report `messaging.receive.messages` depends on the messaging | `messaging.receive.messages` | Counter | `{message}` | Measures the number of received messages. | -### Metric: `messaging.deliver.duration` +### Metric: `messaging.process.duration` -This metric is [required][MetricRequired] for operations are not initiated by the application code (push-based deliver). +This metric is [required][MetricRequired] for operations that are not initiated by the application code (push-based deliver), and [recommended][MetricRecommended] for processing operations instrumented for pull-based scenarios. -When this metric is reported alongside a messaging deliver span, the metric value SHOULD be the same as the corresponding span duration. +When this metric is reported alongside a messaging process span, the metric value SHOULD be the same as the corresponding span duration. This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `messaging.deliver.duration` | Histogram | `s` | Measures the duration of deliver operation. | +| `messaging.process.duration` | Histogram | `s` | Measures the duration of process operation. | -### Metric: `messaging.deliver.messages` +### Metric: `messaging.process.messages` -This metric is [required][MetricRequired] for batch delivery operations. It's [opt-in][MetricOptIn] when the messaging system does not support batch delivery since the message count can be derived from the `messaging.deliver.duration` histogram. +This metric is [required][MetricRequired] for batch process operations, and [recommended][MetricRecommended] for batch processing operations instrumented for pull-based scenarios. It's [opt-in][MetricOptIn] when the messaging system does not support batch processing since the message count can be derived from the `messaging.process.duration` histogram. -_Note: The need to report `messaging.deliver.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ +_Note: The need to report `messaging.process.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | -| `messaging.deliver.messages` | Counter | `{message}` | Measures the number of delivered messages. | +| `messaging.process.messages` | Counter | `{message}` | Measures the number of processed messages. | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/document-status.md [MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#required +[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#recommended [MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#opt-in diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 14ee11002d..b93932c8b6 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -173,7 +173,7 @@ Examples: * `shop.orders receive` * `shop.orders settle` * `print_jobs publish` -* `topic with spaces deliver` +* `topic with spaces process` * `AuthenticationRequest-Conversations settle` * `(anonymous) publish` (`(anonymous)` being a stable identifier for an unnamed destination) @@ -188,7 +188,7 @@ The following operations related to messages are defined for these semantic conv | `create` | A message is created or passed to a client library for publishing. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | -| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +| `process` | One or more messages are delivered to or processed by a consumer. | | `settle` | One or more messages are settled. | ### Span kind @@ -201,7 +201,7 @@ SHOULD be set according to the following table, based on the operation a span de | `create` | `PRODUCER` | | `publish` | `PRODUCER` if the context of the "Publish" span is used as creation context. | | `receive` | `CONSUMER` | -| `deliver` | `CONSUMER` | +| `process` | `CONSUMER` for push-based scenarios where no `receive` span exists. | For cases not covered by the table above, the span kind should be set according to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind), @@ -237,22 +237,26 @@ into a message either from a "Create" span or as a custom creation context. #### Consumer spans -"Deliver" spans SHOULD be created for operations of passing messages to the -application when those operations are not initiated by the application code -(push-based scenarios). A "Deliver" span covers the duration of such an -operation, which is usually a callback or handler. - "Receive" spans SHOULD be created for operations of passing messages to the application when those operations are initiated by the application code (pull-based scenarios). -"Deliver" or "Receive" spans MUST NOT be created for messages that are +"Process" spans SHOULD be created for operations of passing messages to the +application when those operations are not initiated by the application code +(push-based scenarios). Such "Process" span covers the duration of such an +operation, which is usually a callback or handler. + +"Process" spans MAY be created in addition to "Receive" spans for pull-based +scenarios for operations of processing messages. Such spans could be created by +application code, or by abstraction layers built on top of messaging SDKs. + +"Receive" or "Process" spans MUST NOT be created for messages that are pre-fetched or cached by messaging libraries or SDKs until they are forwarded to the caller. -A single "Deliver" or "Receive" span can account for a single message, for a +A single "Process" or "Receive" span can account for a single message, for a batch of messages, or for no message at all (if it is signalled that no -messages were received). For each message it accounts for, the "Deliver" or +messages were received). For each message it accounts for, the "Process" or "Receive" span SHOULD link to the message's creation context. "Settle" spans SHOULD be created for every manually or automatically triggered @@ -375,7 +379,8 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | | `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | -| `deliver` | One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. | +| `process` | One or more messages are delivered to or processed by a consumer. | +| `settle` | One or more messages are settled. | `messaging.system` 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. @@ -479,11 +484,11 @@ flowchart LR; end subgraph CONSUMER1 direction TB - R1[Span Deliver A 1] + R1[Span Process A 1] end subgraph CONSUMER2 direction TB - R2[Span Deliver A 2] + R2[Span Process A 2] end P-. link .-R1; P-. link .-R2; @@ -493,9 +498,9 @@ flowchart LR; linkStyle 0,1 color:green,stroke:green ``` -| Field or Attribute | Span Publish A | Span Deliver A 1| Span Deliver A 2 | +| Field or Attribute | Span Publish A | Span Process A 1| Span Process A 2 | |-|-|-|-| -| Span name | `T publish` | `T deliver` | `T deliver` | +| Span name | `T publish` | `T process` | `T process` | | Parent | | | | | Links | | `T publish` | `T publish` | | SpanKind | `PRODUCER` | `CONSUMER` | `CONSUMER` | @@ -503,7 +508,7 @@ flowchart LR; | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | | `messaging.destination.name` | `"T"` | `"T"` | `"T"` | -| `messaging.operation` | `"publish"` | `"deliver"` | `"deliver"` | +| `messaging.operation` | `"publish"` | `"process"` | `"process"` | | `messaging.message.id` | `"a"` | `"a"`| `"a"` | ### Batch receiving diff --git a/model/metrics/messaging.yaml b/model/metrics/messaging.yaml index 2d2f2a29ef..18079b3a52 100644 --- a/model/metrics/messaging.yaml +++ b/model/metrics/messaging.yaml @@ -28,10 +28,10 @@ groups: unit: "s" extends: metric.messaging.attributes - - id: metric.messaging.deliver.duration + - id: metric.messaging.process.duration type: metric - metric_name: messaging.deliver.duration - brief: "Measures the duration of deliver operation." + metric_name: messaging.process.duration + brief: "Measures the duration of process operation." instrument: histogram unit: "s" extends: metric.messaging.attributes @@ -53,10 +53,10 @@ groups: unit: "{message}" extends: metric.messaging.attributes - - id: metric.messaging.deliver.messages + - id: metric.messaging.process.messages type: metric - metric_name: messaging.deliver.messages - brief: "Measures the number of delivered messages." + metric_name: messaging.process.messages + brief: "Measures the number of processed messages." instrument: counter unit: "{message}" extends: metric.messaging.attributes diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index d05b5cc71d..fcd0c111bb 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -142,10 +142,13 @@ groups: One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. - id: deliver - value: "deliver" + value: "process" brief: > - One or more messages are passed to a consumer. - This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs. + One or more messages are delivered to or processed by a consumer. + - id: settle + value: "settle" + brief: > + One or more messages are settled. brief: > A string identifying the kind of messaging operation. note: If a custom value is used, it MUST be of low cardinality. From 0d963c4016d96972bf0bfa51b23074d05bea8ec9 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 5 Mar 2024 17:28:09 -0800 Subject: [PATCH 371/482] [chore] Mark attributes and metrics as experimental explicitly (#781) --- model/faas-common.yaml | 4 ++ model/general.yaml | 4 ++ model/logs/events.yaml | 1 + model/logs/general.yaml | 1 + model/logs/media.yaml | 5 +++ model/logs/mobile-events.yaml | 2 + model/metrics/database-metrics.yaml | 11 +++++ model/metrics/faas-metrics.yaml | 9 +++++ model/metrics/http.yaml | 5 +++ model/metrics/jvm-metrics-experimental.yaml | 7 ++++ model/metrics/messaging.yaml | 7 ++++ model/metrics/process-metrics.yaml | 17 ++++++-- model/metrics/rpc-metrics.yaml | 10 +++++ model/metrics/system-metrics.yaml | 40 +++++++++++++++++++ model/registry/browser.yaml | 4 ++ model/registry/cloud.yaml | 7 +++- model/registry/code.yaml | 6 +++ model/registry/container.yaml | 11 +++++ model/registry/db.yaml | 30 ++++++++++++++ model/registry/destination.yaml | 2 + model/registry/device.yaml | 4 ++ model/registry/disk.yaml | 1 + model/registry/host.yaml | 15 +++++++ model/registry/k8s.yaml | 23 +++++++++++ model/registry/messaging.yaml | 37 +++++++++++++++++ model/registry/network.yaml | 7 ++++ model/registry/oci.yaml | 1 + model/registry/os.yaml | 5 +++ model/registry/process.yaml | 11 +++++ model/registry/rpc.yaml | 13 ++++++ model/registry/source.yaml | 2 + model/registry/thread.yaml | 2 + model/registry/tls.yaml | 29 ++++++++++++++ model/registry/url.yaml | 7 ++++ model/registry/user-agent.yaml | 2 + model/resource/android.yaml | 1 + model/resource/cloud_provider/aws/ecs.yaml | 7 ++++ model/resource/cloud_provider/aws/eks.yaml | 1 + model/resource/cloud_provider/aws/logs.yaml | 4 ++ .../cloud_provider/gcp/cloud_run.yaml | 2 + model/resource/cloud_provider/gcp/gce.yaml | 2 + model/resource/cloud_provider/heroku.yaml | 3 ++ model/resource/deployment_environment.yaml | 1 + model/resource/faas.yaml | 4 ++ model/resource/service_experimental.yaml | 2 + model/resource/telemetry_experimental.yaml | 2 + model/resource/webengine.yaml | 3 ++ model/scope/exporter/exporter.yaml | 8 ++-- model/session.yaml | 2 + model/trace/aws/lambda.yaml | 1 + model/trace/cloudevents.yaml | 5 +++ model/trace/compatibility.yaml | 1 + model/trace/faas.yaml | 10 ++++- model/trace/feature-flag.yaml | 3 ++ model/trace/instrumentation/aws-sdk.yml | 29 ++++++++++++++ model/trace/instrumentation/graphql.yml | 3 ++ model/trace/rpc.yaml | 4 ++ 57 files changed, 429 insertions(+), 11 deletions(-) diff --git a/model/faas-common.yaml b/model/faas-common.yaml index 7f903bb57f..11a8b430c0 100644 --- a/model/faas-common.yaml +++ b/model/faas-common.yaml @@ -24,8 +24,10 @@ groups: - id: other value: 'other' brief: 'If none of the others apply' + stability: experimental - id: invoked_name type: string + stability: experimental requirement_level: required brief: > The name of the invoked function. @@ -52,6 +54,7 @@ groups: - id: 'tencent_cloud' value: 'tencent_cloud' brief: 'Tencent Cloud' + stability: experimental requirement_level: required brief: > The cloud provider of the invoked function. @@ -60,6 +63,7 @@ groups: invoked function. - id: invoked_region type: string + stability: experimental requirement_level: conditionally_required: > For some cloud providers, like AWS or GCP, the region in which a diff --git a/model/general.yaml b/model/general.yaml index e3bad3d46a..ec38d6e8dd 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -34,6 +34,7 @@ groups: attributes: - id: service type: string + stability: experimental brief: > The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` @@ -47,6 +48,7 @@ groups: attributes: - id: id type: string + stability: experimental brief: > Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) @@ -54,10 +56,12 @@ groups: examples: 'username' - id: role type: string + stability: experimental brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' examples: 'admin' - id: scope type: string + stability: experimental brief: > Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated diff --git a/model/logs/events.yaml b/model/logs/events.yaml index 3942d432fd..a1ecf5f538 100644 --- a/model/logs/events.yaml +++ b/model/logs/events.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: name type: string + stability: experimental requirement_level: required brief: > Identifies the class / type of event. diff --git a/model/logs/general.yaml b/model/logs/general.yaml index 48da970c13..e8f9ea5853 100644 --- a/model/logs/general.yaml +++ b/model/logs/general.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: uid type: string + stability: experimental requirement_level: opt_in brief: > A unique identifier for the Log Record. diff --git a/model/logs/media.yaml b/model/logs/media.yaml index b8d1c29975..d2ac89f470 100644 --- a/model/logs/media.yaml +++ b/model/logs/media.yaml @@ -6,6 +6,7 @@ groups: attributes: - id: iostream requirement_level: opt_in + stability: experimental brief: > The stream associated with the log. See below for a list of well-known values. type: @@ -25,24 +26,28 @@ groups: attributes: - id: name type: string + stability: experimental requirement_level: recommended brief: > The basename of the file. examples: ["audit.log"] - id: path type: string + stability: experimental requirement_level: opt_in brief: > The full path to the file. examples: [ "/var/log/mysql/audit.log" ] - id: name_resolved type: string + stability: experimental requirement_level: opt_in brief: > The basename of the file, with symlinks resolved. examples: [ "uuid.log" ] - id: path_resolved type: string + stability: experimental requirement_level: opt_in brief: > The full path to the file, with symlinks resolved. diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index d6f49e70c5..0ae14ca975 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -7,6 +7,7 @@ groups: This event represents an occurrence of a lifecycle transition on the iOS platform. attributes: - id: state + stability: experimental requirement_level: "required" note: > The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), @@ -46,6 +47,7 @@ groups: This event represents an occurrence of a lifecycle transition on the Android platform. attributes: - id: state + stability: experimental requirement_level: required brief: > This attribute represents the state the application has transitioned into at the occurrence of the event. diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index 097ff79abf..0691e6c625 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -4,6 +4,7 @@ groups: brief: Describes Database attributes attributes: - id: state + stability: experimental type: allow_custom_values: false members: @@ -16,6 +17,7 @@ groups: examples: ["idle"] - id: pool.name type: string + stability: experimental requirement_level: required brief: > The name of the connection pool; unique within the instrumented application. @@ -27,6 +29,7 @@ groups: - id: metric.db.client.connections.usage type: metric metric_name: db.client.connections.usage + stability: experimental brief: "The number of connections that are currently in state described by the `state` attribute" instrument: updowncounter unit: "{connection}" @@ -37,6 +40,7 @@ groups: - id: metric.db.client.connections.idle.max type: metric metric_name: db.client.connections.idle.max + stability: experimental brief: "The maximum number of idle open connections allowed" instrument: updowncounter unit: "{connection}" @@ -46,6 +50,7 @@ groups: - id: metric.db.client.connections.idle.min type: metric metric_name: db.client.connections.idle.min + stability: experimental brief: "The minimum number of idle open connections allowed" instrument: updowncounter unit: "{connection}" @@ -55,6 +60,7 @@ groups: - id: metric.db.client.connections.max type: metric metric_name: db.client.connections.max + stability: experimental brief: "The maximum number of open connections allowed" instrument: updowncounter unit: "{connection}" @@ -64,6 +70,7 @@ groups: - id: metric.db.client.connections.pending_requests type: metric metric_name: db.client.connections.pending_requests + stability: experimental brief: "The number of pending requests for an open connection, cumulative for the entire pool" instrument: updowncounter unit: "{request}" @@ -73,6 +80,7 @@ groups: - id: metric.db.client.connections.timeouts type: metric metric_name: db.client.connections.timeouts + stability: experimental brief: "The number of connection timeouts that have occurred trying to obtain a connection from the pool" instrument: counter unit: "{timeout}" @@ -82,6 +90,7 @@ groups: - id: metric.db.client.connections.create_time type: metric metric_name: db.client.connections.create_time + stability: experimental brief: "The time it took to create a new connection" instrument: histogram unit: "ms" @@ -91,6 +100,7 @@ groups: - id: metric.db.client.connections.wait_time type: metric metric_name: db.client.connections.wait_time + stability: experimental brief: "The time it took to obtain an open connection from the pool" instrument: histogram unit: "ms" @@ -100,6 +110,7 @@ groups: - id: metric.db.client.connections.use_time type: metric metric_name: db.client.connections.use_time + stability: experimental brief: "The time between borrowing a connection and returning it to the pool" instrument: histogram unit: "ms" diff --git a/model/metrics/faas-metrics.yaml b/model/metrics/faas-metrics.yaml index d68119f320..238e49df77 100644 --- a/model/metrics/faas-metrics.yaml +++ b/model/metrics/faas-metrics.yaml @@ -2,6 +2,7 @@ groups: - id: metric.faas.invoke_duration type: metric metric_name: faas.invoke_duration + stability: experimental brief: "Measures the duration of the function's logic execution" instrument: histogram unit: "s" @@ -11,6 +12,7 @@ groups: - id: metric.faas.init_duration type: metric metric_name: faas.init_duration + stability: experimental brief: "Measures the duration of the function's initialization, such as a cold start" instrument: histogram unit: "s" @@ -20,6 +22,7 @@ groups: - id: metric.faas.coldstarts type: metric metric_name: faas.coldstarts + stability: experimental brief: "Number of invocation cold starts" instrument: counter unit: "{coldstart}" @@ -29,6 +32,7 @@ groups: - id: metric.faas.errors type: metric metric_name: faas.errors + stability: experimental brief: "Number of invocation errors" instrument: counter unit: "{error}" @@ -38,6 +42,7 @@ groups: - id: metric.faas.invocations type: metric metric_name: faas.invocations + stability: experimental brief: "Number of successful invocations" instrument: counter unit: "{invocation}" @@ -47,6 +52,7 @@ groups: - id: metric.faas.timeouts type: metric metric_name: faas.timeouts + stability: experimental brief: "Number of invocation timeouts" instrument: counter unit: "{timeout}" @@ -56,6 +62,7 @@ groups: - id: metric.faas.mem_usage type: metric metric_name: faas.mem_usage + stability: experimental brief: "Distribution of max memory usage per invocation" instrument: histogram unit: "By" @@ -65,6 +72,7 @@ groups: - id: metric.faas.cpu_usage type: metric metric_name: faas.cpu_usage + stability: experimental brief: "Distribution of CPU usage per invocation" instrument: histogram unit: "s" @@ -74,6 +82,7 @@ groups: - id: metric.faas.net_io type: metric metric_name: faas.net_io + stability: experimental brief: "Distribution of net I/O usage per invocation" instrument: histogram unit: "By" diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index a309994f2d..d22e7836b8 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -35,6 +35,7 @@ groups: - id: metric.http.server.active_requests type: metric metric_name: http.server.active_requests + stability: experimental brief: "Number of active HTTP server requests." instrument: updowncounter unit: "{request}" @@ -66,6 +67,7 @@ groups: - id: metric.http.server.request.body.size type: metric metric_name: http.server.request.body.size + stability: experimental brief: "Size of HTTP server request bodies." instrument: histogram unit: "By" @@ -78,6 +80,7 @@ groups: - id: metric.http.server.response.body.size type: metric metric_name: http.server.response.body.size + stability: experimental brief: "Size of HTTP server response bodies." instrument: histogram unit: "By" @@ -99,6 +102,7 @@ groups: - id: metric.http.client.request.body.size type: metric metric_name: http.client.request.body.size + stability: experimental brief: "Size of HTTP client request bodies." instrument: histogram unit: "By" @@ -111,6 +115,7 @@ groups: - id: metric.http.client.response.body.size type: metric metric_name: http.client.response.body.size + stability: experimental brief: "Size of HTTP client response bodies." instrument: histogram unit: "By" diff --git a/model/metrics/jvm-metrics-experimental.yaml b/model/metrics/jvm-metrics-experimental.yaml index 8ea4fa57c5..4bc7cc7581 100644 --- a/model/metrics/jvm-metrics-experimental.yaml +++ b/model/metrics/jvm-metrics-experimental.yaml @@ -2,6 +2,7 @@ groups: - id: metric.jvm.memory.init type: metric metric_name: jvm.memory.init + stability: experimental extends: attributes.jvm.memory brief: "Measure of initial memory requested." instrument: updowncounter @@ -10,6 +11,7 @@ groups: - id: metric.jvm.system.cpu.utilization type: metric metric_name: jvm.system.cpu.utilization + stability: experimental brief: "Recent CPU utilization for the whole system as reported by the JVM." note: > The value range is [0.0,1.0]. @@ -22,6 +24,7 @@ groups: - id: metric.jvm.system.cpu.load_1m type: metric metric_name: jvm.system.cpu.load_1m + stability: experimental brief: "Average CPU load of the whole system for the last minute as reported by the JVM." note: > The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. @@ -38,6 +41,7 @@ groups: attributes: - id: pool.name type: string + stability: experimental requirement_level: recommended brief: Name of the buffer pool. examples: [ "mapped", "direct" ] @@ -48,6 +52,7 @@ groups: - id: metric.jvm.buffer.memory.usage type: metric metric_name: jvm.buffer.memory.usage + stability: experimental extends: attributes.jvm.buffer brief: "Measure of memory used by buffers." instrument: updowncounter @@ -56,6 +61,7 @@ groups: - id: metric.jvm.buffer.memory.limit type: metric metric_name: jvm.buffer.memory.limit + stability: experimental extends: attributes.jvm.buffer brief: "Measure of total memory capacity of buffers." instrument: updowncounter @@ -64,6 +70,7 @@ groups: - id: metric.jvm.buffer.count type: metric metric_name: jvm.buffer.count + stability: experimental extends: attributes.jvm.buffer brief: "Number of buffers in the pool." instrument: updowncounter diff --git a/model/metrics/messaging.yaml b/model/metrics/messaging.yaml index 18079b3a52..03a1a5b44b 100644 --- a/model/metrics/messaging.yaml +++ b/model/metrics/messaging.yaml @@ -1,6 +1,7 @@ groups: - id: metric.messaging.attributes type: attribute_group + stability: experimental brief: "Common messaging metrics attributes." extends: messaging.attributes.common attributes: @@ -16,6 +17,7 @@ groups: type: metric metric_name: messaging.publish.duration brief: "Measures the duration of publish operation." + stability: experimental instrument: histogram unit: "s" extends: metric.messaging.attributes @@ -24,6 +26,7 @@ groups: type: metric metric_name: messaging.receive.duration brief: "Measures the duration of receive operation." + stability: experimental instrument: histogram unit: "s" extends: metric.messaging.attributes @@ -32,6 +35,7 @@ groups: type: metric metric_name: messaging.process.duration brief: "Measures the duration of process operation." + stability: experimental instrument: histogram unit: "s" extends: metric.messaging.attributes @@ -41,6 +45,7 @@ groups: type: metric metric_name: messaging.publish.messages brief: "Measures the number of published messages." + stability: experimental instrument: counter unit: "{message}" extends: metric.messaging.attributes @@ -49,6 +54,7 @@ groups: type: metric metric_name: messaging.receive.messages brief: "Measures the number of received messages." + stability: experimental instrument: counter unit: "{message}" extends: metric.messaging.attributes @@ -57,6 +63,7 @@ groups: type: metric metric_name: messaging.process.messages brief: "Measures the number of processed messages." + stability: experimental instrument: counter unit: "{message}" extends: metric.messaging.attributes diff --git a/model/metrics/process-metrics.yaml b/model/metrics/process-metrics.yaml index cc663a9eaf..d6735399a1 100644 --- a/model/metrics/process-metrics.yaml +++ b/model/metrics/process-metrics.yaml @@ -15,10 +15,11 @@ groups: value: 'user' - id: wait value: 'wait' - + stability: experimental - id: metric.process.cpu.time type: metric metric_name: process.cpu.time + stability: experimental brief: "Total CPU seconds broken down by different states." instrument: counter unit: "s" @@ -28,6 +29,7 @@ groups: - id: metric.process.cpu.utilization type: metric metric_name: process.cpu.utilization + stability: experimental brief: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process." instrument: gauge unit: "1" @@ -37,6 +39,7 @@ groups: - id: metric.process.memory.usage type: metric metric_name: process.memory.usage + stability: experimental brief: "The amount of physical memory in use." instrument: updowncounter unit: "By" @@ -45,6 +48,7 @@ groups: - id: metric.process.memory.virtual type: metric metric_name: process.memory.virtual + stability: experimental brief: "The amount of committed virtual memory." instrument: updowncounter unit: "By" @@ -53,6 +57,7 @@ groups: - id: metric.process.disk.io type: metric metric_name: process.disk.io + stability: experimental prefix: process.disk brief: "Disk bytes transferred." instrument: counter @@ -63,6 +68,7 @@ groups: - id: metric.process.network.io type: metric metric_name: process.network.io + stability: experimental brief: "Network bytes transferred." instrument: counter unit: "By" @@ -72,22 +78,23 @@ groups: - id: metric.process.thread.count type: metric metric_name: process.thread.count + stability: experimental brief: "Process threads count." instrument: updowncounter unit: "{thread}" - attributes: [] - id: metric.process.open_file_descriptor.count type: metric metric_name: process.open_file_descriptor.count + stability: experimental brief: "Number of file descriptors in use by the process." instrument: updowncounter unit: "{count}" - attributes: [] - id: metric.process.context_switches type: metric metric_name: process.context_switches + stability: experimental brief: "Number of times the process has been context switched." instrument: counter unit: "{count}" @@ -101,10 +108,11 @@ groups: value: 'voluntary' - id: involuntary value: 'involuntary' - + stability: experimental - id: metric.process.paging.faults type: metric metric_name: process.paging.faults + stability: experimental brief: "Number of page faults the process has made." instrument: counter unit: "{fault}" @@ -118,3 +126,4 @@ groups: value: 'major' - id: minor value: 'minor' + stability: experimental diff --git a/model/metrics/rpc-metrics.yaml b/model/metrics/rpc-metrics.yaml index ca29cdf194..aa47588d41 100644 --- a/model/metrics/rpc-metrics.yaml +++ b/model/metrics/rpc-metrics.yaml @@ -19,6 +19,7 @@ groups: - id: metric.rpc.server.duration type: metric metric_name: rpc.server.duration + stability: experimental brief: Measures the duration of inbound RPC. instrument: histogram unit: "ms" @@ -31,6 +32,7 @@ groups: - id: metric.rpc.server.request.size type: metric metric_name: rpc.server.request.size + stability: experimental brief: Measures the size of RPC request messages (uncompressed). instrument: histogram unit: "By" @@ -40,6 +42,7 @@ groups: - id: metric.rpc.server.response.size type: metric metric_name: rpc.server.response.size + stability: experimental brief: Measures the size of RPC response messages (uncompressed). instrument: histogram unit: "By" @@ -49,6 +52,7 @@ groups: - id: metric.rpc.server.requests_per_rpc type: metric metric_name: rpc.server.requests_per_rpc + stability: experimental brief: Measures the number of messages received per RPC. instrument: histogram unit: "{count}" @@ -60,6 +64,7 @@ groups: - id: metric.rpc.server.responses_per_rpc type: metric metric_name: rpc.server.responses_per_rpc + stability: experimental brief: Measures the number of messages sent per RPC. instrument: histogram unit: "{count}" @@ -72,6 +77,7 @@ groups: - id: metric.rpc.client.duration type: metric metric_name: rpc.client.duration + stability: experimental brief: Measures the duration of outbound RPC. instrument: histogram unit: "ms" @@ -84,6 +90,7 @@ groups: - id: metric.rpc.client.request.size type: metric metric_name: rpc.client.request.size + stability: experimental brief: Measures the size of RPC request messages (uncompressed). instrument: histogram unit: "By" @@ -93,6 +100,7 @@ groups: - id: metric.rpc.client.response.size type: metric metric_name: rpc.client.response.size + stability: experimental brief: Measures the size of RPC response messages (uncompressed). instrument: histogram unit: "By" @@ -102,6 +110,7 @@ groups: - id: metric.rpc.client.requests_per_rpc type: metric metric_name: rpc.client.requests_per_rpc + stability: experimental brief: Measures the number of messages received per RPC. instrument: histogram unit: "{count}" @@ -113,6 +122,7 @@ groups: - id: metric.rpc.client.responses_per_rpc type: metric metric_name: rpc.client.responses_per_rpc + stability: experimental brief: Measures the number of messages sent per RPC. instrument: histogram unit: "{count}" diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 9f288e87ff..49a3a765b4 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: device type: string + stability: experimental brief: "The device identifier" examples: ["(identifier)"] @@ -34,16 +35,19 @@ groups: value: 'interrupt' - id: steal value: 'steal' + stability: experimental brief: "The state of the CPU" examples: ["idle", "interrupt"] - id: logical_number type: int + stability: experimental brief: "The logical CPU number [0..n-1]" examples: [1] - id: metric.system.cpu.time type: metric metric_name: system.cpu.time + stability: experimental brief: "Seconds each logical CPU spent on each mode" instrument: counter unit: "s" @@ -54,6 +58,7 @@ groups: - id: metric.system.cpu.utilization type: metric metric_name: system.cpu.utilization + stability: experimental brief: "Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs" instrument: gauge unit: "1" @@ -64,6 +69,7 @@ groups: - id: metric.system.cpu.frequency type: metric metric_name: system.cpu.frequency + stability: experimental brief: "Reports the current frequency of the CPU in Hz" instrument: gauge unit: "{Hz}" @@ -73,6 +79,7 @@ groups: - id: metric.system.cpu.physical.count type: metric metric_name: system.cpu.physical.count + stability: experimental brief: "Reports the number of actual physical processor cores on the hardware" instrument: updowncounter unit: "{cpu}" @@ -81,6 +88,7 @@ groups: - id: metric.system.cpu.logical.count type: metric metric_name: system.cpu.logical.count + stability: experimental brief: "Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking" instrument: updowncounter unit: "{cpu}" @@ -106,12 +114,14 @@ groups: value: 'buffers' - id: cached value: 'cached' + stability: experimental brief: "The memory state" examples: ["free", "cached"] - id: metric.system.memory.usage type: metric metric_name: system.memory.usage + stability: experimental brief: "Reports memory in use by state." note: | The sum over all `system.memory.state` values SHOULD equal the total memory @@ -124,6 +134,7 @@ groups: - id: metric.system.memory.limit type: metric metric_name: system.memory.limit + stability: experimental brief: "Total memory available in the system." note: | Its value SHOULD equal the sum of `system.memory.state` over all states. @@ -133,6 +144,7 @@ groups: - id: metric.system.memory.utilization type: metric metric_name: system.memory.utilization + stability: experimental brief: "" instrument: gauge unit: "1" @@ -153,6 +165,7 @@ groups: value: 'used' - id: free value: 'free' + stability: experimental brief: "The memory paging state" examples: ["free"] - id: type @@ -163,6 +176,7 @@ groups: value: 'major' - id: minor value: 'minor' + stability: experimental brief: "The memory paging type" examples: ["minor"] - id: direction @@ -173,11 +187,13 @@ groups: value: 'in' - id: out value: 'out' + stability: experimental brief: "The paging access direction" examples: ["in"] - id: metric.system.paging.usage type: metric metric_name: system.paging.usage + stability: experimental brief: "Unix swap or windows pagefile usage" instrument: updowncounter unit: "By" @@ -187,6 +203,7 @@ groups: - id: metric.system.paging.utilization type: metric metric_name: system.paging.utilization + stability: experimental brief: "" instrument: gauge unit: "1" @@ -196,6 +213,7 @@ groups: - id: metric.system.paging.faults type: metric metric_name: system.paging.faults + stability: experimental brief: "" instrument: counter unit: "{fault}" @@ -205,6 +223,7 @@ groups: - id: metric.system.paging.operations type: metric metric_name: system.paging.operations + stability: experimental brief: "" instrument: counter unit: "{operation}" @@ -216,6 +235,7 @@ groups: - id: metric.system.disk.io type: metric metric_name: system.disk.io + stability: experimental brief: "" instrument: counter unit: "By" @@ -226,6 +246,7 @@ groups: - id: metric.system.disk.operations type: metric metric_name: system.disk.operations + stability: experimental brief: "" instrument: counter unit: "{operation}" @@ -236,6 +257,7 @@ groups: - id: metric.system.disk.io_time type: metric metric_name: system.disk.io_time + stability: experimental brief: "Time disk spent activated" instrument: counter unit: "s" @@ -252,6 +274,7 @@ groups: - id: metric.system.disk.operation_time type: metric metric_name: system.disk.operation_time + stability: experimental brief: "Sum of the time each operation took to complete" instrument: counter unit: "s" @@ -267,6 +290,7 @@ groups: - id: metric.system.disk.merged type: metric metric_name: system.disk.merged + stability: experimental brief: "" instrument: counter unit: "{operation}" @@ -291,6 +315,7 @@ groups: value: 'free' - id: reserved value: 'reserved' + stability: experimental examples: ["used"] - id: type type: @@ -308,20 +333,24 @@ groups: value: 'hfsplus' - id: ext4 value: 'ext4' + stability: experimental brief: "The filesystem type" examples: ["ext4"] - id: mode type: string + stability: experimental brief: "The filesystem mode" examples: ["rw, ro"] - id: mountpoint type: string + stability: experimental brief: "The filesystem mount path" examples: ["/mnt/data"] - id: metric.system.filesystem.usage type: metric metric_name: system.filesystem.usage + stability: experimental brief: "" instrument: updowncounter unit: "By" @@ -335,6 +364,7 @@ groups: - id: metric.system.filesystem.utilization type: metric metric_name: system.filesystem.utilization + stability: experimental brief: "" instrument: gauge unit: "1" @@ -381,12 +411,14 @@ groups: value: 'syn_sent' - id: time_wait value: 'time_wait' + stability: experimental brief: "A stateless protocol MUST NOT set this attribute" examples: ["close_wait"] - id: metric.system.network.dropped type: metric metric_name: system.network.dropped + stability: experimental brief: "Count of packets that are dropped or discarded even though there was no error" instrument: counter unit: "{packet}" @@ -403,6 +435,7 @@ groups: - id: metric.system.network.packets type: metric metric_name: system.network.packets + stability: experimental brief: "" instrument: counter unit: "{packet}" @@ -413,6 +446,7 @@ groups: - id: metric.system.network.errors type: metric metric_name: system.network.errors + stability: experimental brief: "Count of network errors detected" instrument: counter unit: "{error}" @@ -429,6 +463,7 @@ groups: - id: metric.system.network.io type: metric metric_name: system.network.io + stability: experimental brief: "" instrument: counter unit: "By" @@ -439,6 +474,7 @@ groups: - id: metric.system.network.connections type: metric metric_name: system.network.connections + stability: experimental brief: "" instrument: updowncounter unit: "{connection}" @@ -465,6 +501,7 @@ groups: value: 'stopped' - id: defunct value: 'defunct' + stability: experimental brief: > The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) examples: ["running"] @@ -473,6 +510,7 @@ groups: - id: metric.system.process.count type: metric metric_name: system.process.count + stability: experimental brief: "Total number of processes in each state" instrument: updowncounter unit: "{process}" @@ -482,6 +520,7 @@ groups: - id: metric.system.process.created type: metric metric_name: system.process.created + stability: experimental brief: "Total number of processes created over uptime of the host" instrument: counter unit: "{process}" @@ -490,6 +529,7 @@ groups: - id: metric.system.linux.memory.available type: metric metric_name: system.linux.memory.available + stability: experimental brief: "An estimate of how much memory is available for starting new applications, without causing swapping" note: | This is an alternative to `system.memory.usage` metric with `state=free`. diff --git a/model/registry/browser.yaml b/model/registry/browser.yaml index e9d0da5c93..286c95b193 100644 --- a/model/registry/browser.yaml +++ b/model/registry/browser.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: brands type: string[] + stability: experimental brief: 'Array of brand name and version separated by a space' note: > This value is intended to be taken from the @@ -15,6 +16,7 @@ groups: examples: [ " Not A;Brand 99", "Chromium 99", "Chrome 99" ] - id: platform type: string + stability: experimental brief: 'The platform on which the browser is running' note: > This value is intended to be taken from the @@ -32,6 +34,7 @@ groups: examples: ['Windows', 'macOS', 'Android'] - id: mobile type: boolean + stability: experimental brief: 'A boolean that is true if the browser is running on a mobile device' note: > This value is intended to be taken from the @@ -40,6 +43,7 @@ groups: SHOULD be left unset. - id: language type: string + stability: experimental brief: 'Preferred language of the user using the browser' note: > This value is intended to be taken from the Navigator API diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml index 5ddb25c899..e3ce26b0e4 100644 --- a/model/registry/cloud.yaml +++ b/model/registry/cloud.yaml @@ -30,16 +30,18 @@ groups: - id: 'tencent_cloud' value: 'tencent_cloud' brief: 'Tencent Cloud' - + stability: experimental brief: > Name of the cloud provider. - id: account.id type: string + stability: experimental brief: > The cloud account ID the resource is assigned to. examples: ['111111111111', 'opentelemetry'] - id: region type: string + stability: experimental brief: > The geographical region the resource is running. note: > @@ -52,6 +54,7 @@ groups: examples: ['us-central1', 'us-east-1'] - id: resource_id type: string + stability: experimental brief: > Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, @@ -81,6 +84,7 @@ groups: - '/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/' - id: availability_zone type: string + stability: experimental brief: > Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the @@ -176,6 +180,7 @@ groups: - id: tencent_cloud_scf value: 'tencent_cloud_scf' brief: Tencent Cloud Serverless Cloud Function (SCF) + stability: experimental brief: > The cloud platform in use. note: > diff --git a/model/registry/code.yaml b/model/registry/code.yaml index d5afceeaed..5848b4fa60 100644 --- a/model/registry/code.yaml +++ b/model/registry/code.yaml @@ -7,32 +7,38 @@ groups: attributes: - id: function type: string + stability: experimental brief: > The method or function name, or equivalent (usually rightmost part of the code unit's name). examples: serveRequest - id: namespace type: string + stability: experimental brief: > The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. examples: com.example.MyHttpService - id: filepath type: string + stability: experimental brief: > The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). examples: /usr/local/MyApplication/content_root/app/index.php - id: lineno type: int + stability: experimental brief: > The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. examples: 42 - id: column type: int + stability: experimental brief: > The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. examples: 16 - id: stacktrace type: string + stability: experimental brief: > A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 2288c39e52..343c63b927 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -7,11 +7,13 @@ groups: attributes: - id: name type: string + stability: experimental brief: > Container name used by container runtime. examples: ['opentelemetry-autoconf'] - id: id type: string + stability: experimental brief: > Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). @@ -19,16 +21,19 @@ groups: examples: ['a3bf90e006b2'] - id: runtime type: string + stability: experimental brief: > The container runtime managing this container. examples: ['docker', 'containerd', 'rkt'] - id: image.name type: string + stability: experimental brief: > Name of the image the container was built on. examples: ['gcr.io/opentelemetry/operator'] - id: image.tags type: string[] + stability: experimental brief: > Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). @@ -37,6 +42,7 @@ groups: examples: ['v1.27.1', '3.5.7-0'] - id: image.id type: string + stability: experimental brief: > Runtime specific image identifier. Usually a hash algorithm followed by a UUID. note: > @@ -53,6 +59,7 @@ groups: examples: ['sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f'] - id: image.repo_digests type: string[] + stability: experimental brief: > Repo digests of the container image as provided by the container runtime. note: > @@ -64,6 +71,7 @@ groups: - 'internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578' - id: command type: string + stability: experimental note: > If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. brief: > @@ -71,16 +79,19 @@ groups: examples: [ 'otelcontribcol' ] - id: command_line type: string + stability: experimental brief: > The full command run by the container as a single string representing the full command. [2] examples: [ 'otelcontribcol --config config.yaml' ] - id: command_args type: string[] + stability: experimental brief: > All the command arguments (including the command/executable itself) run by the container. [2] examples: [ 'otelcontribcol, --config, config.yaml' ] - id: label type: template[string] + stability: experimental brief: > Container labels, `` being the label name, the value being the label value. examples: [ 'container.label.app=nginx' ] diff --git a/model/registry/db.yaml b/model/registry/db.yaml index a17c1046d4..6926fa53b6 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -7,12 +7,14 @@ groups: attributes: - id: cassandra.coordinator.dc type: string + stability: experimental brief: > The data center of the coordinating node for a query. examples: 'us-west-2' tag: tech-specific-cassandra - id: cassandra.coordinator.id type: string + stability: experimental brief: > The ID of the coordinating node for a query. examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' @@ -44,26 +46,31 @@ groups: value: 'serial' - id: local_serial value: 'local_serial' + stability: experimental tag: tech-specific-cassandra - id: cassandra.idempotence type: boolean + stability: experimental brief: > Whether or not the query is idempotent. tag: tech-specific-cassandra - id: cassandra.page_size type: int + stability: experimental brief: > The fetch size used for paging, i.e. how many rows will be returned at once. examples: [5000] tag: tech-specific-cassandra - id: cassandra.speculative_execution_count type: int + stability: experimental brief: > The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. examples: [0, 2] tag: tech-specific-cassandra - id: cassandra.table type: string + stability: experimental brief: The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). note: > This mirrors the db.sql.table attribute but references cassandra rather than sql. @@ -76,6 +83,7 @@ groups: tag: tech-specific-cassandra - id: connection_string type: string + stability: experimental brief: > The connection string used to connect to the database. It is recommended to remove embedded credentials. @@ -83,6 +91,7 @@ groups: tag: db-generic - id: cosmosdb.client_id type: string + stability: experimental brief: Unique Cosmos client instance id. examples: '3ba4827d-4422-483f-b59f-85b74211c11d' tag: tech-specific-cosmosdb @@ -96,10 +105,12 @@ groups: - id: direct value: 'direct' brief: Direct connection. + stability: experimental brief: Cosmos client connection mode. tag: tech-specific-cosmosdb - id: cosmosdb.container type: string + stability: experimental brief: Cosmos DB container name. examples: 'anystring' tag: tech-specific-cosmosdb @@ -137,41 +148,49 @@ groups: value: 'QueryPlan' - id: execute_javascript value: 'ExecuteJavaScript' + stability: experimental brief: CosmosDB Operation Type. tag: tech-specific-cosmosdb - id: cosmosdb.request_charge type: double + stability: experimental brief: RU consumed for that operation examples: [46.18, 1.0] tag: tech-specific-cosmosdb - id: cosmosdb.request_content_length type: int + stability: experimental brief: Request payload size in bytes tag: tech-specific-cosmosdb - id: cosmosdb.status_code type: int + stability: experimental brief: Cosmos DB status code. examples: [200, 201] tag: tech-specific-cosmosdb - id: cosmosdb.sub_status_code type: int + stability: experimental brief: Cosmos DB sub status code. examples: [1000, 1002] tag: tech-specific-cosmosdb - id: elasticsearch.cluster.name type: string + stability: experimental brief: > Represents the identifier of an Elasticsearch cluster. examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] tag: tech-specific-elasticsearch - id: elasticsearch.node.name type: string + stability: experimental brief: > Represents the human-readable identifier of the node/instance to which a request was routed. examples: ["instance-0000000001"] tag: tech-specific-elasticsearch - id: elasticsearch.path_parts type: template[string] + stability: experimental brief: > A dynamic value in the url path. note: > @@ -183,18 +202,21 @@ groups: tag: tech-specific-elasticsearch - id: jdbc.driver_classname type: string + stability: experimental brief: > The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] tag: tech-specific-jdbc - id: mongodb.collection type: string + stability: experimental brief: > The MongoDB collection being accessed within the database stated in `db.name`. examples: [ 'customers', 'products' ] tag: tech-specific-mongodb - id: mssql.instance_name type: string + stability: experimental note: > If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). @@ -205,6 +227,7 @@ groups: tag: tech-specific-mssql - id: name type: string + stability: experimental brief: > This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database @@ -218,6 +241,7 @@ groups: tag: db-generic - id: operation type: string + stability: experimental brief: > The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. @@ -232,6 +256,7 @@ groups: tag: db-generic - id: redis.database_index type: int + stability: experimental brief: > The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. @@ -239,6 +264,7 @@ groups: tag: tech-specific-redis - id: sql.table type: string + stability: experimental brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). note: > It is not recommended to attempt any client-side parsing of @@ -250,6 +276,7 @@ groups: tag: tech-specific-sql - id: statement type: string + stability: experimental brief: > The database statement being executed. examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] @@ -415,9 +442,11 @@ groups: - id: trino value: 'trino' brief: 'Trino' + stability: experimental tag: db-generic - id: user type: string + stability: experimental brief: > Username for accessing the database. examples: ['readonly_user', 'reporting_user'] @@ -425,6 +454,7 @@ groups: - id: instance.id tag: db-generic type: string + stability: experimental brief: > An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. diff --git a/model/registry/destination.yaml b/model/registry/destination.yaml index 595a1c67f9..99adf1a872 100644 --- a/model/registry/destination.yaml +++ b/model/registry/destination.yaml @@ -12,6 +12,7 @@ groups: attributes: - id: address type: string + stability: experimental brief: "Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent @@ -19,5 +20,6 @@ groups: examples: ['destination.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int + stability: experimental brief: 'Destination port number' examples: [3389, 2888] diff --git a/model/registry/device.yaml b/model/registry/device.yaml index c109981f11..5c324e37fe 100644 --- a/model/registry/device.yaml +++ b/model/registry/device.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: id type: string + stability: experimental brief: > A unique identifier representing the device note: > @@ -21,6 +22,7 @@ groups: examples: ['2ab2916d-a51f-4ac8-80ee-45ac31a28092'] - id: manufacturer type: string + stability: experimental brief: > The name of the device manufacturer note: > @@ -29,6 +31,7 @@ groups: examples: ['Apple', 'Samsung'] - id: model.identifier type: string + stability: experimental brief: > The model identifier for the device note: > @@ -38,6 +41,7 @@ groups: examples: ['iPhone3,4', 'SM-G920F'] - id: model.name type: string + stability: experimental brief: > The marketing name for the device model note: > diff --git a/model/registry/disk.yaml b/model/registry/disk.yaml index 90d6fb27d2..d8aba1e251 100644 --- a/model/registry/disk.yaml +++ b/model/registry/disk.yaml @@ -13,5 +13,6 @@ groups: value: 'read' - id: write value: 'write' + stability: experimental brief: "The disk IO operation direction." examples: ["read"] diff --git a/model/registry/host.yaml b/model/registry/host.yaml index c6b68ef414..f427266375 100644 --- a/model/registry/host.yaml +++ b/model/registry/host.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: id type: string + stability: experimental brief: > Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for @@ -14,6 +15,7 @@ groups: examples: ['fdbf79e8af94cb7f9e8df36789187052'] - id: name type: string + stability: experimental brief: > Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name @@ -21,6 +23,7 @@ groups: examples: ['opentelemetry-test'] - id: type type: string + stability: experimental brief: > Type of host. For Cloud, this must be the machine type. examples: ['n1-standard-1'] @@ -52,25 +55,30 @@ groups: - id: x86 value: 'x86' brief: "32-bit x86" + stability: experimental brief: > The CPU architecture the host system is running on. - id: image.name type: string + stability: experimental brief: > Name of the VM image or OS install the host was instantiated from. examples: ['infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'] - id: image.id + stability: experimental type: string brief: > VM image ID or host OS image ID. For Cloud, this value is from the provider. examples: ['ami-07b06b442921831e5'] - id: image.version + stability: experimental type: string brief: > The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). examples: ['0.1'] - id: ip + stability: experimental type: string[] brief: > Available IP addresses of the host, excluding loopback interfaces. @@ -79,6 +87,7 @@ groups: MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. examples: ["192.168.1.140", "fe80::abc2:4a28:737a:609e"] - id: mac + stability: experimental type: string[] brief: > Available MAC addresses of the host, excluding loopback interfaces. @@ -87,6 +96,7 @@ groups: as hyphen-separated octets in uppercase hexadecimal form from most to least significant. examples: ['AC-DE-48-23-45-67', 'AC-DE-48-23-45-67-01-9F'] - id: cpu.vendor.id + stability: experimental type: string brief: > Processor manufacturer identifier. A maximum 12-character string. @@ -95,27 +105,32 @@ groups: Writing these to memory in this order results in a 12-character string. examples: [ 'GenuineIntel' ] - id: cpu.family + stability: experimental type: string brief: > Family or generation of the CPU. examples: [ '6', 'PA-RISC 1.1e' ] - id: cpu.model.id + stability: experimental type: string brief: > Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. examples: [ '6', '9000/778/B180L' ] - id: cpu.model.name + stability: experimental type: string brief: > Model designation of the processor. examples: [ '11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz' ] - id: cpu.stepping + stability: experimental type: string brief: > Stepping or core revisions. examples: ["1", "r1p1"] - id: cpu.cache.l2.size + stability: experimental type: int brief: > The amount of level 2 memory cache available to the processor (in Bytes). diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index efda36e993..ca878b8fd8 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -7,11 +7,13 @@ groups: attributes: - id: cluster.name type: string + stability: experimental brief: > The name of the cluster. examples: ['opentelemetry-cluster'] - id: cluster.uid type: string + stability: experimental brief: > A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. @@ -41,41 +43,49 @@ groups: examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] - id: node.name type: string + stability: experimental brief: > The name of the Node. examples: ['node-1'] - id: node.uid type: string + stability: experimental brief: > The UID of the Node. examples: ['1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'] - id: namespace.name type: string + stability: experimental brief: > The name of the namespace that the pod is running in. examples: ['default'] - id: pod.uid type: string + stability: experimental brief: > The UID of the Pod. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: pod.name type: string + stability: experimental brief: > The name of the Pod. examples: ['opentelemetry-pod-autoconf'] - id: pod.label type: template[string] + stability: experimental brief: > The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. examples: ['k8s.pod.label.app=my-app', 'k8s.pod.label.mycompany.io/arch=x64', 'k8s.pod.label.data='] - id: pod.annotation type: template[string] + stability: experimental brief: > The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. examples: [ 'k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true', 'k8s.pod.annotation.mycompany.io/arch=x64', 'k8s.pod.annotation.data=' ] - id: container.name type: string + stability: experimental brief: > The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique @@ -83,6 +93,7 @@ groups: examples: ['redis'] - id: container.restart_count type: int + stability: experimental brief: > Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a @@ -90,61 +101,73 @@ groups: examples: [0, 2] - id: replicaset.uid type: string + stability: experimental brief: > The UID of the ReplicaSet. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: replicaset.name type: string + stability: experimental brief: > The name of the ReplicaSet. examples: ['opentelemetry'] - id: deployment.uid type: string + stability: experimental brief: > The UID of the Deployment. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: deployment.name type: string + stability: experimental brief: > The name of the Deployment. examples: ['opentelemetry'] - id: statefulset.uid type: string + stability: experimental brief: > The UID of the StatefulSet. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: statefulset.name type: string + stability: experimental brief: > The name of the StatefulSet. examples: ['opentelemetry'] - id: daemonset.uid type: string + stability: experimental brief: > The UID of the DaemonSet. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: daemonset.name type: string + stability: experimental brief: > The name of the DaemonSet. examples: ['opentelemetry'] - id: job.uid type: string + stability: experimental brief: > The UID of the Job. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: job.name type: string + stability: experimental brief: > The name of the Job. examples: ['opentelemetry'] - id: cronjob.uid type: string + stability: experimental brief: > The UID of the CronJob. examples: ['275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'] - id: cronjob.name type: string + stability: experimental brief: > The name of the CronJob. examples: ['opentelemetry'] diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index fcd0c111bb..4afd4d5320 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -6,6 +6,7 @@ groups: attributes: - id: batch.message_count type: int + stability: experimental brief: The number of messages sent, received, or processed in the scope of the batching operation. note: > Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. @@ -15,12 +16,14 @@ groups: tag: messaging-generic - id: client_id type: string + stability: experimental brief: > A unique identifier for the client that consumes or produces a message. examples: ['client-5', 'myhost@8742@s8083jm'] tag: messaging-generic - id: destination.name type: string + stability: experimental brief: 'The message destination name' note: | Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If @@ -29,6 +32,7 @@ groups: tag: messaging-generic - id: destination.template type: string + stability: experimental brief: Low cardinality representation of the messaging destination name note: > Destination names could be constructed from templates. @@ -40,18 +44,22 @@ groups: tag: messaging-generic - id: destination.anonymous type: boolean + stability: experimental brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' tag: messaging-generic - id: destination.temporary type: boolean + stability: experimental brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' tag: messaging-generic - id: destination_publish.anonymous type: boolean + stability: experimental brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' tag: messaging-generic - id: destination_publish.name type: string + stability: experimental brief: 'The name of the original destination the message was published to' note: | The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If @@ -60,6 +68,7 @@ groups: tag: messaging-generic - id: kafka.consumer.group type: string + stability: experimental brief: > Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. @@ -67,12 +76,14 @@ groups: tag: tech-specific-kafka - id: kafka.destination.partition type: int + stability: experimental brief: > Partition the message is sent to. examples: 2 tag: tech-specific-kafka - id: kafka.message.key type: string + stability: experimental brief: > Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. @@ -84,16 +95,19 @@ groups: tag: tech-specific-kafka - id: kafka.message.offset type: int + stability: experimental brief: > The offset of a record in the corresponding Kafka partition. examples: 42 tag: tech-specific-kafka - id: kafka.message.tombstone type: boolean + stability: experimental brief: 'A boolean that is true if the message is a tombstone.' tag: tech-specific-kafka - id: message.conversation_id type: string + stability: experimental brief: > The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". @@ -101,6 +115,7 @@ groups: tag: messaging-generic - id: message.envelope.size type: int + stability: experimental brief: > The size of the message body and metadata in bytes. note: | @@ -110,11 +125,13 @@ groups: tag: messaging-generic - id: message.id type: string + stability: experimental brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' examples: '452a7c7c7c7048c2f887f61572b18fc2' tag: messaging-generic - id: message.body.size type: int + stability: experimental brief: > The size of the message body in bytes. note: | @@ -149,18 +166,21 @@ groups: value: "settle" brief: > One or more messages are settled. + stability: experimental brief: > A string identifying the kind of messaging operation. note: If a custom value is used, it MUST be of low cardinality. tag: messaging-generic - id: rabbitmq.destination.routing_key type: string + stability: experimental brief: > RabbitMQ message routing key. examples: 'myKey' tag: tech-specific-rabbitmq - id: rabbitmq.message.delivery_tag type: int + stability: experimental brief: > RabbitMQ message delivery tag examples: 123 @@ -168,6 +188,7 @@ groups: - id: rocketmq.client_group type: string + stability: experimental brief: > Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. examples: 'myConsumerGroup' @@ -182,35 +203,41 @@ groups: - id: broadcasting value: 'broadcasting' brief: 'Broadcasting consumption model' + stability: experimental brief: > Model of message consumption. This only applies to consumer spans. tag: tech-specific-rocketmq - id: rocketmq.message.delay_time_level type: int + stability: experimental brief: > The delay time level for delay message, which determines the message delay time. examples: 3 tag: tech-specific-rocketmq - id: rocketmq.message.delivery_timestamp type: int + stability: experimental brief: > The timestamp in milliseconds that the delay message is expected to be delivered to consumer. examples: 1665987217045 tag: tech-specific-rocketmq - id: rocketmq.message.group type: string + stability: experimental brief: > It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. examples: 'myMessageGroup' tag: tech-specific-rocketmq - id: rocketmq.message.keys type: string[] + stability: experimental brief: > Key(s) of message, another way to mark message besides message id. examples: ['keyA', 'keyB'] tag: tech-specific-rocketmq - id: rocketmq.message.tag type: string + stability: experimental brief: > The secondary classifier of message besides topic. examples: tagA @@ -231,17 +258,20 @@ groups: - id: transaction value: 'transaction' brief: 'Transaction message' + stability: experimental brief: > Type of message. tag: tech-specific-rocketmq - id: rocketmq.namespace type: string + stability: experimental brief: > Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' tag: tech-specific-rocketmq - id: gcp_pubsub.message.ordering_key type: string + stability: experimental brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' @@ -282,21 +312,25 @@ groups: - id: rocketmq value: 'rocketmq' brief: 'Apache RocketMQ' + stability: experimental tag: messaging-generic - id: servicebus.message.delivery_count type: int + stability: experimental brief: > Number of deliveries that have been attempted for this message. examples: 2 tag: tech-specific-servicebus - id: servicebus.message.enqueued_time type: int + stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 tag: tech-specific-servicebus - id: servicebus.destination.subscription_name type: string + stability: experimental brief: > The name of the subscription in the topic messages are received from. examples: "mySubscription" @@ -323,18 +357,21 @@ groups: tag: tech-specific-servicebus - id: eventhubs.message.enqueued_time type: int + stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 tag: tech-specific-eventhubs - id: eventhubs.destination.partition.id type: string + stability: experimental brief: > The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. examples: '1' tag: tech-specific-eventhubs - id: eventhubs.consumer.group type: string + stability: experimental brief: > The name of the consumer group the event consumer is associated with. examples: 'indexer' diff --git a/model/registry/network.yaml b/model/registry/network.yaml index 7715506bcc..e7520bae9c 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -7,18 +7,22 @@ groups: attributes: - id: carrier.icc type: string + stability: experimental brief: "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network." examples: "DE" - id: carrier.mcc type: string + stability: experimental brief: "The mobile carrier country code." examples: "310" - id: carrier.mnc type: string + stability: experimental brief: "The mobile carrier network code." examples: "001" - id: carrier.name type: string + stability: experimental brief: "The name of the mobile carrier." examples: "sprint" - id: connection.subtype @@ -88,6 +92,7 @@ groups: - id: lte_ca brief: LTE CA value: "lte_ca" + stability: experimental brief: 'This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.' examples: 'LTE' - id: connection.type @@ -104,6 +109,7 @@ groups: value: "unavailable" - id: unknown value: "unknown" + stability: experimental brief: 'The internet connection type.' examples: 'wifi' - id: local.address @@ -190,5 +196,6 @@ groups: value: 'transmit' - id: receive value: 'receive' + stability: experimental brief: "The network IO operation direction." examples: ["transmit"] diff --git a/model/registry/oci.yaml b/model/registry/oci.yaml index 24e0cb93f2..00d0e28c2b 100644 --- a/model/registry/oci.yaml +++ b/model/registry/oci.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: digest type: string + stability: experimental brief: > The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. diff --git a/model/registry/os.yaml b/model/registry/os.yaml index af8dbfcd2a..113901906a 100644 --- a/model/registry/os.yaml +++ b/model/registry/os.yaml @@ -47,23 +47,28 @@ groups: brief: "IBM z/OS" brief: > The operating system type. + stability: experimental - id: description type: string + stability: experimental brief: > Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. examples: ['Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'] - id: name type: string + stability: experimental brief: 'Human readable operating system name.' examples: ['iOS', 'Android', 'Ubuntu'] - id: version type: string + stability: experimental brief: > The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). examples: ['14.2.1', '18.04.1'] - id: build_id type: string + stability: experimental brief: 'Unique identifier for a particular build or compilation of the operating system.' examples: ['TQ3C.230805.001.B2', '20E247', '22621'] diff --git a/model/registry/process.yaml b/model/registry/process.yaml index e4b5c230bd..4279a9e33a 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -7,16 +7,19 @@ groups: attributes: - id: pid type: int + stability: experimental brief: > Process identifier (PID). examples: [1234] - id: parent_pid type: int + stability: experimental brief: > Parent Process identifier (PPID). examples: [111] - id: executable.name type: string + stability: experimental brief: > The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the @@ -24,6 +27,7 @@ groups: examples: ['otelcol'] - id: executable.path type: string + stability: experimental brief: > The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the @@ -31,6 +35,7 @@ groups: examples: ['/usr/bin/cmd/otelcol'] - id: command type: string + stability: experimental brief: > The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. @@ -38,6 +43,7 @@ groups: examples: ['cmd/otelcol'] - id: command_line type: string + stability: experimental brief: > The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. @@ -46,6 +52,7 @@ groups: examples: ['C:\cmd\otecol --config="my directory\config.yaml"'] - id: command_args type: string[] + stability: experimental brief: > All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid @@ -55,23 +62,27 @@ groups: examples: ['cmd/otecol', '--config=config.yaml'] - id: owner type: string + stability: experimental brief: > The username of the user that owns the process. examples: 'root' - id: runtime.name type: string + stability: experimental brief: > The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. examples: ['OpenJDK Runtime Environment'] - id: runtime.version type: string + stability: experimental brief: > The version of the runtime of this process, as returned by the runtime without modification. examples: '14.0.2' - id: runtime.description type: string + stability: experimental brief: > An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. diff --git a/model/registry/rpc.yaml b/model/registry/rpc.yaml index 64f1f9a667..cfc1e45017 100644 --- a/model/registry/rpc.yaml +++ b/model/registry/rpc.yaml @@ -39,9 +39,11 @@ groups: value: data_loss - id: unauthenticated value: unauthenticated + stability: experimental brief: "The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values." - id: connect_rpc.request.metadata type: template[string[]] + stability: experimental brief: > Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. note: > @@ -50,6 +52,7 @@ groups: examples: ['rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - id: connect_rpc.response.metadata type: template[string[]] + stability: experimental brief: > Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. note: > @@ -110,9 +113,11 @@ groups: - id: unauthenticated brief: UNAUTHENTICATED value: 16 + stability: experimental brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." - id: grpc.request.metadata type: template[string[]] + stability: experimental brief: > gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. note: > @@ -121,6 +126,7 @@ groups: examples: ['rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]'] - id: grpc.response.metadata type: template[string[]] + stability: experimental brief: > gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. note: > @@ -129,14 +135,17 @@ groups: examples: ['rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]'] - id: jsonrpc.error_code type: int + stability: experimental brief: "`error.code` property of response if it is an error response." examples: [-32700, 100] - id: jsonrpc.error_message type: string + stability: experimental brief: "`error.message` property of response if it is an error response." examples: ['Parse error', 'User already exists'] - id: jsonrpc.request_id type: string + stability: experimental brief: > `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), @@ -145,10 +154,12 @@ groups: examples: ['10', 'request-7', ''] - id: jsonrpc.version type: string + stability: experimental brief: "Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted." examples: ['2.0', '1.0'] - id: method type: string + stability: experimental brief: 'The name of the (logical) method being called, must be equal to the $method part in the span name.' note: > This is the logical name of the method from the RPC interface perspective, @@ -159,6 +170,7 @@ groups: examples: "exampleMethod" - id: service type: string + stability: experimental brief: 'The full (logical) name of the service being called, including its package name, if applicable.' note: > This is the logical name of the service from the RPC interface perspective, @@ -188,3 +200,4 @@ groups: - id: connect_rpc value: 'connect_rpc' brief: 'Connect RPC' + stability: experimental diff --git a/model/registry/source.yaml b/model/registry/source.yaml index 263a491cab..2f9a967919 100644 --- a/model/registry/source.yaml +++ b/model/registry/source.yaml @@ -12,6 +12,7 @@ groups: attributes: - id: address type: string + stability: experimental brief: "Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." note: > When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent @@ -19,5 +20,6 @@ groups: examples: ['source.example.com', '10.1.2.80', '/tmp/my.sock'] - id: port type: int + stability: experimental brief: 'Source port number' examples: [3389, 2888] diff --git a/model/registry/thread.yaml b/model/registry/thread.yaml index f6b5b5a509..688b0ec8e2 100644 --- a/model/registry/thread.yaml +++ b/model/registry/thread.yaml @@ -7,11 +7,13 @@ groups: attributes: - id: id type: int + stability: experimental brief: > Current "managed" thread ID (as opposed to OS thread ID). examples: 42 - id: name type: string + stability: experimental brief: > Current thread name. examples: main diff --git a/model/registry/tls.yaml b/model/registry/tls.yaml index 421479d18a..1f0c880bc2 100644 --- a/model/registry/tls.yaml +++ b/model/registry/tls.yaml @@ -8,6 +8,7 @@ groups: brief: > String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. type: string + stability: experimental note: > The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). @@ -18,29 +19,34 @@ groups: ] - id: client.certificate type: string + stability: experimental brief: > PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. examples: ["MII..."] - id: client.certificate_chain type: string[] + stability: experimental brief: > Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. examples: ["MII...", "MI..."] - id: client.hash.md5 type: string + stability: experimental brief: > Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. examples: ["0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"] - id: client.hash.sha1 type: string + stability: experimental brief: > Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. examples: ["9E393D93138888D288266C2D915214D1D1CCEB2A"] - id: client.hash.sha256 type: string + stability: experimental brief: > Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. @@ -48,31 +54,38 @@ groups: ["0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"] - id: client.issuer type: string + stability: experimental brief: "Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client." examples: ["CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"] - id: client.ja3 type: string + stability: experimental brief: "A hash that identifies clients based on how they perform an SSL/TLS handshake." examples: ["d4e5b18d6b55c71272893221c96ba240"] - id: client.not_after type: string + stability: experimental brief: "Date/Time indicating when client certificate is no longer considered valid." examples: ["2021-01-01T00:00:00.000Z"] - id: client.not_before type: string + stability: experimental brief: "Date/Time indicating when client certificate is first considered valid." examples: ["1970-01-01T00:00:00.000Z"] - id: client.server_name type: string + stability: experimental brief: "Also called an SNI, this tells the server which hostname to which the client is attempting to connect to." examples: ["opentelemetry.io"] - id: client.subject type: string + stability: experimental brief: "Distinguished name of subject of the x.509 certificate presented by the client." examples: ["CN=myclient, OU=Documentation Team, DC=example, DC=com"] - id: client.supported_ciphers type: string[] + stability: experimental brief: Array of ciphers offered by the client during the client hello. examples: [ @@ -81,10 +94,12 @@ groups: - id: curve brief: "String indicating the curve used for the given cipher, when applicable" type: string + stability: experimental examples: ["secp256r1"] - id: established brief: "Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel." type: boolean + stability: experimental examples: [true] - id: next_protocol brief: > @@ -92,6 +107,7 @@ groups: Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. type: string + stability: experimental examples: ["http/1.1"] - id: protocol.name brief: > @@ -103,40 +119,48 @@ groups: value: ssl - id: tls value: tls + stability: experimental - id: protocol.version brief: > Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) type: string + stability: experimental examples: ["1.2", "3"] - id: resumed brief: "Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation." type: boolean + stability: experimental examples: [true] - id: server.certificate type: string + stability: experimental brief: > PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. examples: ["MII..."] - id: server.certificate_chain type: string[] + stability: experimental brief: > Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. examples: ["MII...", "MI..."] - id: server.hash.md5 type: string + stability: experimental brief: > Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. examples: ["0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"] - id: server.hash.sha1 type: string + stability: experimental brief: > Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. examples: ["9E393D93138888D288266C2D915214D1D1CCEB2A"] - id: server.hash.sha256 type: string + stability: experimental brief: > Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. @@ -144,22 +168,27 @@ groups: ["0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"] - id: server.issuer type: string + stability: experimental brief: "Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client." examples: ["CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"] - id: server.ja3s type: string + stability: experimental brief: "A hash that identifies servers based on how they perform an SSL/TLS handshake." examples: ["d4e5b18d6b55c71272893221c96ba240"] - id: server.not_after type: string + stability: experimental brief: "Date/Time indicating when server certificate is no longer considered valid." examples: ["2021-01-01T00:00:00.000Z"] - id: server.not_before type: string + stability: experimental brief: "Date/Time indicating when server certificate is first considered valid." examples: ["1970-01-01T00:00:00.000Z"] - id: server.subject type: string + stability: experimental brief: "Distinguished name of subject of the x.509 certificate presented by the server." examples: ["CN=myserver, OU=Documentation Team, DC=example, DC=com"] diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 7e07ad7936..624ad90ba3 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -6,6 +6,7 @@ groups: attributes: - id: domain type: string + stability: experimental brief: > Domain extracted from the `url.full`, such as "opentelemetry.io". note: > @@ -16,6 +17,7 @@ groups: examples: ["www.foo.bar", "opentelemetry.io", "3.12.167.2", "[1080:0:0:0:8:800:200C:417A]"] - id: extension type: string + stability: experimental brief: > The file extension extracted from the `url.full`, excluding the leading dot. note: > @@ -44,6 +46,7 @@ groups: examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] - id: original type: string + stability: experimental brief: > Unmodified original URL as seen in the event source. note: > @@ -63,6 +66,7 @@ groups: Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. - id: port type: int + stability: experimental brief: > Port extracted from the `url.full` examples: [443] @@ -76,6 +80,7 @@ groups: Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. - id: registered_domain type: string + stability: experimental brief: > The highest registered url domain, stripped of the subdomain. examples: ["example.com", "foo.co.uk"] @@ -91,6 +96,7 @@ groups: examples: ["https", "ftp", "telnet"] - id: subdomain type: string + stability: experimental brief: > The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the @@ -101,6 +107,7 @@ groups: such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. - id: top_level_domain type: string + stability: experimental brief: > The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. diff --git a/model/registry/user-agent.yaml b/model/registry/user-agent.yaml index f783d379e5..5503454d22 100644 --- a/model/registry/user-agent.yaml +++ b/model/registry/user-agent.yaml @@ -14,6 +14,7 @@ groups: 'YourApp/1.0.0 grpc-java-okhttp/1.27.2'] - id: name type: string + stability: experimental brief: > Name of the user-agent extracted from original. Usually refers to the browser's name. examples: ['Safari', 'YourApp'] @@ -24,6 +25,7 @@ groups: `user_agent.version` - id: version type: string + stability: experimental brief: > Version of the user-agent extracted from original. Usually refers to the browser's version examples: ['14.1.2', '1.0.0'] diff --git a/model/resource/android.yaml b/model/resource/android.yaml index dcc236d846..cf4040f514 100644 --- a/model/resource/android.yaml +++ b/model/resource/android.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: os.api_level type: string + stability: experimental brief: > Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found diff --git a/model/resource/cloud_provider/aws/ecs.yaml b/model/resource/cloud_provider/aws/ecs.yaml index a40f950c18..a3c4b3f8b1 100644 --- a/model/resource/cloud_provider/aws/ecs.yaml +++ b/model/resource/cloud_provider/aws/ecs.yaml @@ -7,11 +7,13 @@ groups: attributes: - id: container.arn type: string + stability: experimental brief: > The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). examples: ['arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'] - id: cluster.arn type: string + stability: experimental brief: > The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] @@ -23,10 +25,12 @@ groups: value: "ec2" - id: fargate value: "fargate" + stability: experimental brief: > The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. - id: task.arn type: string + stability: experimental brief: > The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). examples: [ @@ -35,11 +39,13 @@ groups: ] - id: task.family type: string + stability: experimental brief: > The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. examples: ['opentelemetry-family'] - id: task.id type: string + stability: experimental brief: > The ID of a running ECS task. The ID MUST be extracted from `task.arn`. requirement_level: @@ -47,6 +53,7 @@ groups: examples: [ '10838bed-421f-43ef-870a-f43feacbbb5b', '23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' ] - id: task.revision type: string + stability: experimental brief: > The revision for the task definition used to create the ECS task. examples: ["8", "26"] diff --git a/model/resource/cloud_provider/aws/eks.yaml b/model/resource/cloud_provider/aws/eks.yaml index 2c897253ee..8eafc481aa 100644 --- a/model/resource/cloud_provider/aws/eks.yaml +++ b/model/resource/cloud_provider/aws/eks.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: cluster.arn type: string + stability: experimental brief: > The ARN of an EKS cluster. examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] diff --git a/model/resource/cloud_provider/aws/logs.yaml b/model/resource/cloud_provider/aws/logs.yaml index 8a433629bb..35889e137c 100644 --- a/model/resource/cloud_provider/aws/logs.yaml +++ b/model/resource/cloud_provider/aws/logs.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: group.names type: string[] + stability: experimental brief: > The name(s) of the AWS log group(s) an application is writing to. examples: ['/aws/lambda/my-function', 'opentelemetry-service'] @@ -16,6 +17,7 @@ groups: group. - id: group.arns type: string[] + stability: experimental brief: > The Amazon Resource Name(s) (ARN) of the AWS log group(s). examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'] @@ -24,11 +26,13 @@ groups: [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). - id: stream.names type: string[] + stability: experimental brief: > The name(s) of the AWS log stream(s) an application is writing to. examples: ['logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] - id: stream.arns type: string[] + stability: experimental brief: > The ARN(s) of the AWS log stream(s). examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] diff --git a/model/resource/cloud_provider/gcp/cloud_run.yaml b/model/resource/cloud_provider/gcp/cloud_run.yaml index e4da8f5929..269f4a6f84 100644 --- a/model/resource/cloud_provider/gcp/cloud_run.yaml +++ b/model/resource/cloud_provider/gcp/cloud_run.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: job.execution type: string + stability: experimental brief: > The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) @@ -16,6 +17,7 @@ groups: examples: ['job-name-xxxx', 'sample-job-mdw84'] - id: job.task_index type: int + stability: experimental brief: > The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) diff --git a/model/resource/cloud_provider/gcp/gce.yaml b/model/resource/cloud_provider/gcp/gce.yaml index 879d0ea388..22b96628dc 100644 --- a/model/resource/cloud_provider/gcp/gce.yaml +++ b/model/resource/cloud_provider/gcp/gce.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: instance.name type: string + stability: experimental brief: > The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in @@ -17,6 +18,7 @@ groups: examples: ['instance-1', 'my-vm-name'] - id: instance.hostname type: string + stability: experimental brief: > The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). examples: ['my-host1234.example.com', 'sample-vm.us-west1-b.c.my-project.internal'] diff --git a/model/resource/cloud_provider/heroku.yaml b/model/resource/cloud_provider/heroku.yaml index e73eddc1e7..c8f7e34143 100644 --- a/model/resource/cloud_provider/heroku.yaml +++ b/model/resource/cloud_provider/heroku.yaml @@ -7,18 +7,21 @@ groups: attributes: - id: release.creation_timestamp type: string + stability: experimental brief: > Time and date the release was created examples: [ '2022-10-23T18:00:42Z' ] requirement_level: opt_in - id: release.commit type: string + stability: experimental brief: > Commit hash for the current release examples: [ 'e6134959463efd8966b20e75b913cafe3f5ec' ] requirement_level: opt_in - id: app.id type: string + stability: experimental brief: > Unique identifier for the application examples: [ '2daa2797-e42b-4624-9322-ec3f968df4da' ] diff --git a/model/resource/deployment_environment.yaml b/model/resource/deployment_environment.yaml index 7ada3f9798..bc2574386a 100644 --- a/model/resource/deployment_environment.yaml +++ b/model/resource/deployment_environment.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: environment type: string + stability: experimental brief: > Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). diff --git a/model/resource/faas.yaml b/model/resource/faas.yaml index 7f1a02e0e0..e73ee38646 100644 --- a/model/resource/faas.yaml +++ b/model/resource/faas.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: name type: string + stability: experimental requirement_level: required brief: > The name of the single function that this runtime instance executes. @@ -30,6 +31,7 @@ groups: examples: ['my-function', 'myazurefunctionapp/some-function-name'] - id: version type: string + stability: experimental brief: The immutable version of the function being executed. note: | Depending on the cloud provider and platform, use: @@ -44,6 +46,7 @@ groups: examples: ['26', 'pinkfroid-00002'] - id: instance type: string + stability: experimental brief: > The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. @@ -52,6 +55,7 @@ groups: examples: ['2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'] - id: max_memory type: int + stability: experimental brief: > The amount of memory available to the serverless function converted to Bytes. note: > diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index 99ed64f024..a11a30a048 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: namespace type: string + stability: experimental brief: > A namespace for `service.name`. note: > @@ -20,6 +21,7 @@ groups: examples: ["Shop"] - id: instance.id type: string + stability: experimental brief: > The string ID of the service instance. note: | diff --git a/model/resource/telemetry_experimental.yaml b/model/resource/telemetry_experimental.yaml index 8f7b23554b..6569c8ff87 100644 --- a/model/resource/telemetry_experimental.yaml +++ b/model/resource/telemetry_experimental.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: distro.name type: string + stability: experimental brief: > The name of the auto instrumentation agent or distribution, if used. note: | @@ -15,6 +16,7 @@ groups: examples: ["parts-unlimited-java"] - id: distro.version type: string + stability: experimental brief: > The version string of the auto instrumentation agent or distribution, if used. examples: ["1.2.3"] diff --git a/model/resource/webengine.yaml b/model/resource/webengine.yaml index 5e0cdf8fab..10485dcc18 100644 --- a/model/resource/webengine.yaml +++ b/model/resource/webengine.yaml @@ -7,17 +7,20 @@ groups: attributes: - id: name type: string + stability: experimental requirement_level: required brief: > The name of the web engine. examples: ['WildFly'] - id: version type: string + stability: experimental brief: > The version of the web engine. examples: ['21.0.0'] - id: description type: string + stability: experimental brief: > Additional description of the web engine (e.g. detailed version and edition information). examples: ['WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'] diff --git a/model/scope/exporter/exporter.yaml b/model/scope/exporter/exporter.yaml index 0a47d625a9..259061d3ad 100644 --- a/model/scope/exporter/exporter.yaml +++ b/model/scope/exporter/exporter.yaml @@ -22,11 +22,11 @@ groups: attributes: - id: name type: string - stability: "deprecated" - brief: Deprecated, use the `otel.scope.name` attribute. + deprecated: use the `otel.scope.name` attribute. + brief: examples: ['io.opentelemetry.contrib.mongodb'] - id: version type: string - stability: "deprecated" - brief: Deprecated, use the `otel.scope.version` attribute. + deprecated: use the `otel.scope.version` attribute. + brief: examples: ['1.0.0'] diff --git a/model/session.yaml b/model/session.yaml index f221265338..ee09ffe1f3 100644 --- a/model/session.yaml +++ b/model/session.yaml @@ -16,11 +16,13 @@ groups: attributes: - id: id type: string + stability: experimental brief: "A unique id to identify a session." examples: "00112233-4455-6677-8899-aabbccddeeff" requirement_level: opt_in - id: previous_id type: string + stability: experimental brief: "The previous `session.id` for this user, when known." examples: "00112233-4455-6677-8899-aabbccddeeff" requirement_level: opt_in diff --git a/model/trace/aws/lambda.yaml b/model/trace/aws/lambda.yaml index 73e77ea747..795736f5ed 100644 --- a/model/trace/aws/lambda.yaml +++ b/model/trace/aws/lambda.yaml @@ -7,6 +7,7 @@ groups: attributes: - id: invoked_arn type: string + stability: experimental brief: > The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). diff --git a/model/trace/cloudevents.yaml b/model/trace/cloudevents.yaml index 6fcf7ae268..931b082f94 100644 --- a/model/trace/cloudevents.yaml +++ b/model/trace/cloudevents.yaml @@ -9,28 +9,33 @@ groups: attributes: - id: event_id type: string + stability: experimental requirement_level: required brief: > The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. examples: ['123e4567-e89b-12d3-a456-426614174000', '0001'] - id: event_source type: string + stability: experimental requirement_level: required brief: > The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. examples: ['https://github.com/cloudevents', '/cloudevents/spec/pull/123', 'my-service' ] - id: event_spec_version type: string + stability: experimental brief: > The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. examples: '1.0' - id: event_type type: string + stability: experimental brief: > The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. examples: ['com.github.pull_request.opened', 'com.example.object.deleted.v2'] - id: event_subject type: string + stability: experimental brief: > The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). examples: 'mynewfile.jpg' diff --git a/model/trace/compatibility.yaml b/model/trace/compatibility.yaml index 2e3fe12dc7..b24b39a339 100644 --- a/model/trace/compatibility.yaml +++ b/model/trace/compatibility.yaml @@ -8,6 +8,7 @@ groups: attributes: - id: ref_type brief: 'Parent-child Reference type' + stability: experimental note: > The causal relationship between a child Span and a parent Span. type: diff --git a/model/trace/faas.yaml b/model/trace/faas.yaml index 84b7141b38..3eb9b53354 100644 --- a/model/trace/faas.yaml +++ b/model/trace/faas.yaml @@ -20,6 +20,7 @@ groups: call to invoke the lambda, which is often HTTP). - id: invocation_id type: string + stability: experimental brief: 'The invocation ID of the current function invocation.' examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' - ref: cloud.resource_id @@ -33,6 +34,7 @@ groups: attributes: - id: collection type: string + stability: experimental requirement_level: required brief: > The name of the source on which the triggering operation was performed. @@ -40,6 +42,7 @@ groups: and in Cosmos DB to the database name. examples: ['myBucketName', 'myDbName'] - id: operation + stability: experimental requirement_level: required type: allow_custom_values: true @@ -56,6 +59,7 @@ groups: brief: 'Describes the type of the operation that was performed on the data.' - id: time type: string + stability: experimental brief: > A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) @@ -63,6 +67,7 @@ groups: examples: "2020-01-23T13:47:06Z" - id: name type: string + stability: experimental brief: > The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of @@ -76,7 +81,6 @@ groups: source operation such as a database or filesystem read/write. constraints: - include: trace.http.server - attributes: [] - id: faas_span.pubsub type: span @@ -85,7 +89,6 @@ groups: sent to a messaging system. constraints: - include: messaging - attributes: [] - id: faas_span.timer prefix: faas @@ -95,6 +98,7 @@ groups: attributes: - id: time type: string + stability: experimental brief: > A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) @@ -102,6 +106,7 @@ groups: examples: "2020-01-23T13:47:06Z" - id: cron type: string + stability: experimental brief: > A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). @@ -116,6 +121,7 @@ groups: attributes: - id: coldstart type: boolean + stability: experimental brief: > A boolean that is true if the serverless function is executed for the first time (aka cold-start). diff --git a/model/trace/feature-flag.yaml b/model/trace/feature-flag.yaml index 50706ba2d7..b6bc1ba1dc 100644 --- a/model/trace/feature-flag.yaml +++ b/model/trace/feature-flag.yaml @@ -8,16 +8,19 @@ groups: attributes: - id: key type: string + stability: experimental requirement_level: required brief: The unique identifier of the feature flag. examples: ["logo-color"] - id: provider_name type: string + stability: experimental requirement_level: recommended brief: The name of the service provider that performs the flag evaluation. examples: ["Flag Manager"] - id: variant type: string + stability: experimental requirement_level: recommended examples: ["red", "true", "on"] brief: > diff --git a/model/trace/instrumentation/aws-sdk.yml b/model/trace/instrumentation/aws-sdk.yml index 90b6d1c967..552914670a 100644 --- a/model/trace/instrumentation/aws-sdk.yml +++ b/model/trace/instrumentation/aws-sdk.yml @@ -28,6 +28,7 @@ groups: - PutItem - id: request_id type: string + stability: experimental brief: "The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`." examples: - 79b9da39-b7ae-508a-a6bc-864b2829c622 @@ -56,12 +57,14 @@ groups: - PutItem - id: table_names type: string[] + stability: experimental brief: The keys in the `RequestItems` object field. examples: - Users - Cats - id: consumed_capacity type: string[] + stability: experimental brief: "The JSON-serialized value of each item in the `ConsumedCapacity` response field." examples: - '{ @@ -91,6 +94,7 @@ groups: }' - id: item_collection_metrics type: string + stability: experimental brief: "The JSON-serialized value of the `ItemCollectionMetrics` response field." examples: - '{ @@ -120,21 +124,25 @@ groups: }' - id: provisioned_read_capacity type: double + stability: experimental brief: "The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter." examples: - 1.0 - 2.0 - id: provisioned_write_capacity type: double + stability: experimental brief: "The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter." examples: - 1.0 - 2.0 - id: consistent_read type: boolean + stability: experimental brief: "The value of the `ConsistentRead` request parameter." - id: projection type: string + stability: experimental brief: "The value of the `ProjectionExpression` request parameter." examples: - Title @@ -142,22 +150,26 @@ groups: - Title, Description, RelatedItems, ProductReviews - id: limit type: int + stability: experimental brief: "The value of the `Limit` request parameter." examples: - 10 - id: attributes_to_get type: string[] + stability: experimental brief: "The value of the `AttributesToGet` request parameter." examples: - lives - id - id: index_name type: string + stability: experimental brief: "The value of the `IndexName` request parameter." examples: - name_to_group - id: select type: string + stability: experimental brief: "The value of the `Select` request parameter." examples: - ALL_ATTRIBUTES @@ -190,6 +202,7 @@ groups: attributes: - id: global_secondary_indexes type: string[] + stability: experimental brief: "The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field" examples: - '{ @@ -211,6 +224,7 @@ groups: }' - id: local_secondary_indexes type: string[] + stability: experimental brief: "The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field." examples: - '{ @@ -295,12 +309,14 @@ groups: attributes: - id: exclusive_start_table type: string + stability: experimental brief: "The value of the `ExclusiveStartTableName` request parameter." examples: - Users - CatsTable - id: table_count type: int + stability: experimental brief: "The the number of items in the `TableNames` response parameter." examples: - 20 @@ -324,6 +340,7 @@ groups: attributes: - id: scan_forward type: boolean + stability: experimental brief: "The value of the `ScanIndexForward` request parameter." - ref: aws.dynamodb.table_names brief: "A single-element array with the value of the TableName request parameter." @@ -345,21 +362,25 @@ groups: attributes: - id: segment type: int + stability: experimental brief: "The value of the `Segment` request parameter." examples: - 10 - id: total_segments type: int + stability: experimental brief: "The value of the `TotalSegments` request parameter." examples: - 100 - id: count type: int + stability: experimental brief: "The value of the `Count` response parameter." examples: - 10 - id: scanned_count type: int + stability: experimental brief: "The value of the `ScannedCount` response parameter." examples: - 50 @@ -396,6 +417,7 @@ groups: attributes: - id: attribute_definitions type: string[] + stability: experimental brief: "The JSON-serialized value of each item in the `AttributeDefinitions` request field." examples: - '{ @@ -404,6 +426,7 @@ groups: }' - id: global_secondary_index_updates type: string[] + stability: experimental brief: "The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field." examples: - '{ @@ -440,6 +463,7 @@ groups: attributes: - id: bucket type: string + stability: experimental brief: "The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." examples: - some-bucket-name @@ -448,6 +472,7 @@ groups: This applies to almost all S3 operations except `list-buckets`. - id: key type: string + stability: experimental brief: "The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." examples: - someFile.yml @@ -470,6 +495,7 @@ groups: - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - id: copy_source type: string + stability: experimental brief: "The source object (in the form `bucket`/`key`) for the copy operation." examples: - someFile.yml @@ -482,6 +508,7 @@ groups: - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - id: upload_id type: string + stability: experimental brief: "Upload ID that identifies the multipart upload." examples: - 'dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ' @@ -497,6 +524,7 @@ groups: - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - id: delete type: string + stability: experimental brief: "The delete request container that specifies the objects to be deleted." examples: - 'Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean' @@ -506,6 +534,7 @@ groups: [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). - id: part_number type: int + stability: experimental brief: "The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000." examples: - 3456 diff --git a/model/trace/instrumentation/graphql.yml b/model/trace/instrumentation/graphql.yml index 88af65e98e..f3f28d1585 100644 --- a/model/trace/instrumentation/graphql.yml +++ b/model/trace/instrumentation/graphql.yml @@ -9,9 +9,11 @@ groups: - id: operation.name brief: "The name of the operation being executed." type: string + stability: experimental examples: 'findBookById' - id: operation.type brief: "The type of the operation being executed." + stability: experimental type: allow_custom_values: false members: @@ -28,5 +30,6 @@ groups: - id: document brief: "The GraphQL document being executed." type: string + stability: experimental note: The value may be sanitized to exclude sensitive information. examples: 'query findBookById { bookById(id: ?) { name } }' diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index de36d6767a..42a3211d26 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -100,16 +100,20 @@ groups: value: "SENT" - id: received value: "RECEIVED" + stability: experimental brief: "Whether this is a received or sent message." - id: id type: int + stability: experimental brief: "MUST be calculated as two different counters starting from `1` one for sent messages and one for received message." note: "This way we guarantee that the values will be consistent between different implementations." - id: compressed_size type: int + stability: experimental brief: "Compressed size of the message in bytes." - id: uncompressed_size type: int + stability: experimental brief: "Uncompressed size of the message in bytes." - id: rpc.connect_rpc From 0e945f169e26ca502bb2233f6e8c941a31eac83d Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:30:13 +0100 Subject: [PATCH 372/482] [chore] Improve check/fix make targets (#787) --- .prettierignore | 1 + CONTRIBUTING.md | 32 +++++++------- Makefile | 7 +-- docs/cloudevents/cloudevents-spans.md | 8 ++-- docs/database/database-metrics.md | 18 ++++---- docs/database/database-spans.md | 2 +- docs/dotnet/dotnet-aspnetcore-metrics.md | 14 +++--- docs/dotnet/dotnet-dns-metrics.md | 2 +- docs/dotnet/dotnet-http-metrics.md | 14 +++--- docs/exceptions/exceptions-logs.md | 2 +- docs/exceptions/exceptions-spans.md | 2 +- docs/faas/aws-lambda.md | 18 ++++---- docs/faas/faas-metrics.md | 22 +++++----- docs/faas/faas-spans.md | 18 ++++---- docs/general/attributes.md | 26 ++++++------ docs/general/logs.md | 4 +- docs/general/metrics.md | 20 ++++----- docs/http/http-metrics.md | 14 +++--- docs/http/http-spans.md | 28 ++++++------ docs/messaging/kafka.md | 2 +- docs/messaging/messaging-metrics.md | 12 +++--- docs/messaging/messaging-spans.md | 42 +++++++++--------- docs/mobile/events.md | 4 +- docs/resource/README.md | 4 +- docs/resource/process.md | 14 +++--- docs/rpc/rpc-metrics.md | 26 ++++++------ docs/rpc/rpc-spans.md | 14 +++--- docs/runtime/README.md | 2 +- docs/runtime/jvm-metrics.md | 36 ++++++++-------- docs/system/hardware-metrics.md | 32 +++++++------- docs/system/process-metrics.md | 20 ++++----- docs/system/system-metrics.md | 54 ++++++++++++------------ 32 files changed, 258 insertions(+), 256 deletions(-) diff --git a/.prettierignore b/.prettierignore index aa4edb3751..001890f677 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ /.github +/.chloggen # for the first iteration, we only reformat /docs/cloud* and will add the rest in individual PRs /docs/** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0639de51d0..8e5b78e834 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,23 +13,23 @@ requirements and recommendations. - [Sign the CLA](#sign-the-cla) - [How to Contribute](#how-to-contribute) - * [Prerequisites](#prerequisites) - * [1. Modify the YAML model](#1-modify-the-yaml-model) - + [Schema files](#schema-files) - * [2. Update the markdown files](#2-update-the-markdown-files) - + [Hugo frontmatter](#hugo-frontmatter) - * [3. Verify the changes before committing](#3-verify-the-changes-before-committing) - * [4. Changelog](#4-changelog) - + [When to add a Changelog Entry](#when-to-add-a-changelog-entry) + - [Prerequisites](#prerequisites) + - [1. Modify the YAML model](#1-modify-the-yaml-model) + - [Schema files](#schema-files) + - [2. Update the markdown files](#2-update-the-markdown-files) + - [Hugo frontmatter](#hugo-frontmatter) + - [3. Verify the changes before committing](#3-verify-the-changes-before-committing) + - [4. Changelog](#4-changelog) + - [When to add a Changelog Entry](#when-to-add-a-changelog-entry) - [Examples](#examples) - + [Adding a Changelog Entry](#adding-a-changelog-entry) - * [5. Getting your PR merged](#5-getting-your-pr-merged) + - [Adding a Changelog Entry](#adding-a-changelog-entry) + - [5. Getting your PR merged](#5-getting-your-pr-merged) - [Automation](#automation) - * [Consistency Checks](#consistency-checks) - * [Auto formatting](#auto-formatting) - * [Markdown style](#markdown-style) - * [Misspell check](#misspell-check) - * [Markdown link check](#markdown-link-check) + - [Consistency Checks](#consistency-checks) + - [Auto formatting](#auto-formatting) + - [Markdown style](#markdown-style) + - [Misspell check](#misspell-check) + - [Markdown link check](#markdown-link-check) - [Updating the referenced specification version](#updating-the-referenced-specification-version) - [Making a Release](#making-a-release) - [Merging existing ECS conventions](#merging-existing-ecs-conventions) @@ -320,7 +320,7 @@ make markdown-link-check - Add `next` as a version in `schema-next.yaml` version. - Run `make chlog-update VERSION=v{version}` - `make chlog-update` will clean up all the current `.yaml` files inside the - `.chloggen` folder automatically + `.chloggen` folder automatically - Double check that `CONTRIBUTING.md` is updated with the proper `v{version}` - Send staging tag as PR for review. - Create a tag `v{version}` on the merged PR and push remote. diff --git a/Makefile b/Makefile index b0a1e81e95..3ef76b3827 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ markdown-toc: @for f in $(ALL_DOCS); do \ if grep -q '' $$f; then \ echo markdown-toc: processing $$f; \ - npx --no -- markdown-toc --no-first-h1 --no-stripHeadingTags -i $$f || exit 1; \ + npx --no -- markdown-toc --bullets "-" --no-first-h1 --no-stripHeadingTags -i $$f || exit 1; \ else \ echo markdown-toc: no TOC markers, skipping $$f; \ fi; \ @@ -117,12 +117,13 @@ fix-format: # Run all checks in order of speed / likely failure. .PHONY: check -check: misspell markdownlint markdown-link-check check-format +check: misspell markdownlint check-format markdown-toc markdown-link-check + git diff --exit-code ':*.md' || (echo 'Generated markdown Table of Contents is out of date, please run "make markdown-toc" and commit the changes in this PR.' && exit 1) @echo "All checks complete" # Attempt to fix issues / regenerate tables. .PHONY: fix -fix: table-generation misspell-correction fix-format +fix: table-generation misspell-correction fix-format markdown-toc @echo "All autofixes complete" .PHONY: install-tools diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 1236b745ad..44f112fe7a 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -13,10 +13,10 @@ linkTitle: CloudEvents Spans - [Definitions](#definitions) - [Overview](#overview) - [Conventions](#conventions) - * [Spans](#spans) - + [Creation](#creation) - + [Processing](#processing) - * [Attributes](#attributes) + - [Spans](#spans) + - [Creation](#creation) + - [Processing](#processing) + - [Attributes](#attributes) diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 1f21ddf074..402607fdfd 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -16,15 +16,15 @@ and attributes but more may be added in the future. - [Connection pools](#connection-pools) - * [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) - * [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) - * [Metric: `db.client.connections.idle.min`](#metric-dbclientconnectionsidlemin) - * [Metric: `db.client.connections.max`](#metric-dbclientconnectionsmax) - * [Metric: `db.client.connections.pending_requests`](#metric-dbclientconnectionspending_requests) - * [Metric: `db.client.connections.timeouts`](#metric-dbclientconnectionstimeouts) - * [Metric: `db.client.connections.create_time`](#metric-dbclientconnectionscreate_time) - * [Metric: `db.client.connections.wait_time`](#metric-dbclientconnectionswait_time) - * [Metric: `db.client.connections.use_time`](#metric-dbclientconnectionsuse_time) + - [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) + - [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) + - [Metric: `db.client.connections.idle.min`](#metric-dbclientconnectionsidlemin) + - [Metric: `db.client.connections.max`](#metric-dbclientconnectionsmax) + - [Metric: `db.client.connections.pending_requests`](#metric-dbclientconnectionspending_requests) + - [Metric: `db.client.connections.timeouts`](#metric-dbclientconnectionstimeouts) + - [Metric: `db.client.connections.create_time`](#metric-dbclientconnectionscreate_time) + - [Metric: `db.client.connections.wait_time`](#metric-dbclientconnectionswait_time) + - [Metric: `db.client.connections.use_time`](#metric-dbclientconnectionsuse_time) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index e8e224fc74..5965c90a41 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -11,7 +11,7 @@ linkTitle: Client Calls - [Common attributes](#common-attributes) - * [Notes and well-known identifiers for `db.system`](#notes-and-well-known-identifiers-for-dbsystem) + - [Notes and well-known identifiers for `db.system`](#notes-and-well-known-identifiers-for-dbsystem) - [Semantic Conventions for specific database technologies](#semantic-conventions-for-specific-database-technologies) diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index e217a1664c..b09a34d8b8 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -12,15 +12,15 @@ This article defines semantic conventions for ASP.NET Core metrics. - [Server](#server) - [Routing](#routing) - * [Metric: `aspnetcore.routing.match_attempts`](#metric-aspnetcoreroutingmatch_attempts) + - [Metric: `aspnetcore.routing.match_attempts`](#metric-aspnetcoreroutingmatch_attempts) - [Exceptions](#exceptions) - * [Metric: `aspnetcore.diagnostics.exceptions`](#metric-aspnetcorediagnosticsexceptions) + - [Metric: `aspnetcore.diagnostics.exceptions`](#metric-aspnetcorediagnosticsexceptions) - [Rate-limiting](#rate-limiting) - * [Metric: `aspnetcore.rate_limiting.active_request_leases`](#metric-aspnetcorerate_limitingactive_request_leases) - * [Metric: `aspnetcore.rate_limiting.request_lease.duration`](#metric-aspnetcorerate_limitingrequest_leaseduration) - * [Metric: `aspnetcore.rate_limiting.queued_requests`](#metric-aspnetcorerate_limitingqueued_requests) - * [Metric: `aspnetcore.rate_limiting.request.time_in_queue`](#metric-aspnetcorerate_limitingrequesttime_in_queue) - * [Metric: `aspnetcore.rate_limiting.requests`](#metric-aspnetcorerate_limitingrequests) + - [Metric: `aspnetcore.rate_limiting.active_request_leases`](#metric-aspnetcorerate_limitingactive_request_leases) + - [Metric: `aspnetcore.rate_limiting.request_lease.duration`](#metric-aspnetcorerate_limitingrequest_leaseduration) + - [Metric: `aspnetcore.rate_limiting.queued_requests`](#metric-aspnetcorerate_limitingqueued_requests) + - [Metric: `aspnetcore.rate_limiting.request.time_in_queue`](#metric-aspnetcorerate_limitingrequesttime_in_queue) + - [Metric: `aspnetcore.rate_limiting.requests`](#metric-aspnetcorerate_limitingrequests) diff --git a/docs/dotnet/dotnet-dns-metrics.md b/docs/dotnet/dotnet-dns-metrics.md index c0bb6b7aa3..4240445dd1 100644 --- a/docs/dotnet/dotnet-dns-metrics.md +++ b/docs/dotnet/dotnet-dns-metrics.md @@ -11,7 +11,7 @@ This article defines semantic conventions for DNS metrics emitted by .NET. - [DNS metrics](#dns-metrics) - * [Metric: `dns.lookup.duration`](#metric-dnslookupduration) + - [Metric: `dns.lookup.duration`](#metric-dnslookupduration) diff --git a/docs/dotnet/dotnet-http-metrics.md b/docs/dotnet/dotnet-http-metrics.md index ee7cb4d399..47bf1a71b7 100644 --- a/docs/dotnet/dotnet-http-metrics.md +++ b/docs/dotnet/dotnet-http-metrics.md @@ -11,14 +11,14 @@ This article defines semantic conventions for HTTP metrics emitted by .NET compo - [HTTP client](#http-client) - * [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) - * [Metric: `http.client.open_connections`](#metric-httpclientopen_connections) - * [Metric: `http.client.connection.duration`](#metric-httpclientconnectionduration) - * [Metric: `http.client.request.time_in_queue`](#metric-httpclientrequesttime_in_queue) - * [Metric: `http.client.active_requests`](#metric-httpclientactive_requests) + - [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) + - [Metric: `http.client.open_connections`](#metric-httpclientopen_connections) + - [Metric: `http.client.connection.duration`](#metric-httpclientconnectionduration) + - [Metric: `http.client.request.time_in_queue`](#metric-httpclientrequesttime_in_queue) + - [Metric: `http.client.active_requests`](#metric-httpclientactive_requests) - [HTTP server](#http-server) - * [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) - * [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) + - [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) + - [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 11656ea1df..0746762191 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -14,7 +14,7 @@ emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry - [Recording an Exception](#recording-an-exception) - [Attributes](#attributes) - * [Stacktrace Representation](#stacktrace-representation) + - [Stacktrace Representation](#stacktrace-representation) diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index 18a91996a5..ef9d3849e1 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -13,7 +13,7 @@ exceptions associated with spans. - [Recording an Exception](#recording-an-exception) - [Attributes](#attributes) - * [Stacktrace Representation](#stacktrace-representation) + - [Stacktrace Representation](#stacktrace-representation) diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 45b68d67f3..c2219b9e4e 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -14,18 +14,18 @@ use cases. - [All triggers](#all-triggers) - * [AWS X-Ray Active Tracing Considerations](#aws-x-ray-active-tracing-considerations) - + [`xray-lambda` Propagator Functionality](#xray-lambda-propagator-functionality) - + [`xray-lambda` Propagator Configuration](#xray-lambda-propagator-configuration) + - [AWS X-Ray Active Tracing Considerations](#aws-x-ray-active-tracing-considerations) + - [`xray-lambda` Propagator Functionality](#xray-lambda-propagator-functionality) + - [`xray-lambda` Propagator Configuration](#xray-lambda-propagator-configuration) - [API Gateway](#api-gateway) - [SQS](#sqs) - * [SQS Event](#sqs-event) - * [SQS Message](#sqs-message) + - [SQS Event](#sqs-event) + - [SQS Message](#sqs-message) - [Examples](#examples) - * [API Gateway Request Proxy (Lambda tracing passive)](#api-gateway-request-proxy-lambda-tracing-passive) - * [API Gateway Request Proxy (Lambda tracing active)](#api-gateway-request-proxy-lambda-tracing-active) - * [SQS (Lambda tracing passive)](#sqs-lambda-tracing-passive) - * [SQS (Lambda tracing active)](#sqs-lambda-tracing-active) + - [API Gateway Request Proxy (Lambda tracing passive)](#api-gateway-request-proxy-lambda-tracing-passive) + - [API Gateway Request Proxy (Lambda tracing active)](#api-gateway-request-proxy-lambda-tracing-active) + - [SQS (Lambda tracing passive)](#sqs-lambda-tracing-passive) + - [SQS (Lambda tracing active)](#sqs-lambda-tracing-active) - [Resource Detector](#resource-detector) diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index e84a0921dc..d6046b04f9 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -18,18 +18,18 @@ operations. By adding FaaS attributes to metric events it allows for finely tune - [Metric Instruments](#metric-instruments) - * [FaaS Instance](#faas-instance) - + [Metric: `faas.invoke_duration`](#metric-faasinvoke_duration) - + [Metric: `faas.init_duration`](#metric-faasinit_duration) - + [Metric: `faas.coldstarts`](#metric-faascoldstarts) - + [Metric: `faas.errors`](#metric-faaserrors) - + [Metric: `faas.invocations`](#metric-faasinvocations) - + [Metric: `faas.timeouts`](#metric-faastimeouts) - + [Metric: `faas.mem_usage`](#metric-faasmem_usage) - + [Metric: `faas.cpu_usage`](#metric-faascpu_usage) - + [Metric: `faas.net_io`](#metric-faasnet_io) + - [FaaS Instance](#faas-instance) + - [Metric: `faas.invoke_duration`](#metric-faasinvoke_duration) + - [Metric: `faas.init_duration`](#metric-faasinit_duration) + - [Metric: `faas.coldstarts`](#metric-faascoldstarts) + - [Metric: `faas.errors`](#metric-faaserrors) + - [Metric: `faas.invocations`](#metric-faasinvocations) + - [Metric: `faas.timeouts`](#metric-faastimeouts) + - [Metric: `faas.mem_usage`](#metric-faasmem_usage) + - [Metric: `faas.cpu_usage`](#metric-faascpu_usage) + - [Metric: `faas.net_io`](#metric-faasnet_io) - [References](#references) - * [Metric References](#metric-references) + - [Metric References](#metric-references) diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 8088cf7c42..34a03528db 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -16,18 +16,18 @@ See also the [additional instructions for instrumenting AWS Lambda](aws-lambda.m - [General Attributes](#general-attributes) - * [Function Name](#function-name) - * [Difference between invocation and instance](#difference-between-invocation-and-instance) + - [Function Name](#function-name) + - [Difference between invocation and instance](#difference-between-invocation-and-instance) - [Incoming Invocations](#incoming-invocations) - * [Incoming FaaS Span attributes](#incoming-faas-span-attributes) - * [Resource attributes as incoming FaaS span attributes](#resource-attributes-as-incoming-faas-span-attributes) + - [Incoming FaaS Span attributes](#incoming-faas-span-attributes) + - [Resource attributes as incoming FaaS span attributes](#resource-attributes-as-incoming-faas-span-attributes) - [Outgoing Invocations](#outgoing-invocations) - [Function Trigger Type](#function-trigger-type) - * [Datasource](#datasource) - * [HTTP](#http) - * [PubSub](#pubsub) - * [Timer](#timer) - * [Other](#other) + - [Datasource](#datasource) + - [HTTP](#http) + - [PubSub](#pubsub) + - [Timer](#timer) + - [Other](#other) - [Example](#example) diff --git a/docs/general/attributes.md b/docs/general/attributes.md index e9f9dddad7..3ae6cbfdfd 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -16,20 +16,20 @@ Particular operations may refer to or require some of these attributes. - [Server, client and shared network attributes](#server-client-and-shared-network-attributes) - * [Address and port attributes](#address-and-port-attributes) - * [Server attributes](#server-attributes) - + [`server.address`](#serveraddress) - * [Client attributes](#client-attributes) - * [Source and destination attributes](#source-and-destination-attributes) - + [Source](#source) - + [Destination](#destination) - * [Other network attributes](#other-network-attributes) - + [`network.peer.*` and `network.local.*` attributes](#networkpeer-and-networklocal-attributes) + - [Address and port attributes](#address-and-port-attributes) + - [Server attributes](#server-attributes) + - [`server.address`](#serveraddress) + - [Client attributes](#client-attributes) + - [Source and destination attributes](#source-and-destination-attributes) + - [Source](#source) + - [Destination](#destination) + - [Other network attributes](#other-network-attributes) + - [`network.peer.*` and `network.local.*` attributes](#networkpeer-and-networklocal-attributes) - [Client/server examples using `network.peer.*`](#clientserver-examples-using--networkpeer) - * [Simple client/server example](#simple-clientserver-example) - * [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) - * [Client/server example with forward proxy](#clientserver-example-with-forward-proxy) - + [Network connection and carrier attributes](#network-connection-and-carrier-attributes) + - [Simple client/server example](#simple-clientserver-example) + - [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) + - [Client/server example with forward proxy](#clientserver-example-with-forward-proxy) + - [Network connection and carrier attributes](#network-connection-and-carrier-attributes) - [General remote service attributes](#general-remote-service-attributes) - [General identity attributes](#general-identity-attributes) - [General thread attributes](#general-thread-attributes) diff --git a/docs/general/logs.md b/docs/general/logs.md index c66136624d..152950057a 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -16,8 +16,8 @@ They may be used in any Log Record they apply to. - [General log identification attributes](#general-log-identification-attributes) - [Log Media](#log-media) - * [Log File](#log-file) - * [I/O Stream](#io-stream) + - [Log File](#log-file) + - [I/O Stream](#io-stream) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 74699fbad0..2f235e23ce 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -10,17 +10,17 @@ aliases: [docs/specs/semconv/general/metrics-general] - [General Guidelines](#general-guidelines) - * [Name Reuse Prohibition](#name-reuse-prohibition) - * [Units](#units) - * [Naming rules for Counters and UpDownCounters](#naming-rules-for-counters-and-updowncounters) - + [Pluralization](#pluralization) - + [Use `count` Instead of Pluralization for UpDownCounters](#use-count-instead-of-pluralization-for-updowncounters) - + [Do not use `total`](#do-not-use-total) + - [Name Reuse Prohibition](#name-reuse-prohibition) + - [Units](#units) + - [Naming rules for Counters and UpDownCounters](#naming-rules-for-counters-and-updowncounters) + - [Pluralization](#pluralization) + - [Use `count` Instead of Pluralization for UpDownCounters](#use-count-instead-of-pluralization-for-updowncounters) + - [Do not use `total`](#do-not-use-total) - [General Metric Semantic Conventions](#general-metric-semantic-conventions) - * [Instrument Naming](#instrument-naming) - * [Instrument Units](#instrument-units) - * [Instrument Types](#instrument-types) - * [Consistent UpDownCounter timeseries](#consistent-updowncounter-timeseries) + - [Instrument Naming](#instrument-naming) + - [Instrument Units](#instrument-units) + - [Instrument Types](#instrument-types) + - [Consistent UpDownCounter timeseries](#consistent-updowncounter-timeseries) diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index eae37608ed..aed8fc81dc 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -15,14 +15,14 @@ operations. By adding HTTP attributes to metric events it allows for finely tune - [HTTP Server](#http-server) - * [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) - * [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) - * [Metric: `http.server.request.body.size`](#metric-httpserverrequestbodysize) - * [Metric: `http.server.response.body.size`](#metric-httpserverresponsebodysize) + - [Metric: `http.server.request.duration`](#metric-httpserverrequestduration) + - [Metric: `http.server.active_requests`](#metric-httpserveractive_requests) + - [Metric: `http.server.request.body.size`](#metric-httpserverrequestbodysize) + - [Metric: `http.server.response.body.size`](#metric-httpserverresponsebodysize) - [HTTP Client](#http-client) - * [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) - * [Metric: `http.client.request.body.size`](#metric-httpclientrequestbodysize) - * [Metric: `http.client.response.body.size`](#metric-httpclientresponsebodysize) + - [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) + - [Metric: `http.client.request.body.size`](#metric-httpclientrequestbodysize) + - [Metric: `http.client.response.body.size`](#metric-httpclientresponsebodysize) diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 4b5edb5b99..1668199fa2 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -18,22 +18,22 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Status](#status) - [Common Attributes](#common-attributes) - [HTTP client](#http-client) - * [HTTP client span duration](#http-client-span-duration) - * [HTTP request retries and redirects](#http-request-retries-and-redirects) + - [HTTP client span duration](#http-client-span-duration) + - [HTTP request retries and redirects](#http-request-retries-and-redirects) - [HTTP server](#http-server) - * [HTTP server definitions](#http-server-definitions) - + [Setting `server.address` and `server.port` attributes](#setting-serveraddress-and-serverport-attributes) - + [Simple client/server example](#simple-clientserver-example) - + [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) - * [HTTP Server semantic conventions](#http-server-semantic-conventions) + - [HTTP server definitions](#http-server-definitions) + - [Setting `server.address` and `server.port` attributes](#setting-serveraddress-and-serverport-attributes) + - [Simple client/server example](#simple-clientserver-example) + - [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) + - [HTTP Server semantic conventions](#http-server-semantic-conventions) - [Examples](#examples) - * [HTTP client-server example](#http-client-server-example) - * [HTTP client retries examples](#http-client-retries-examples) - * [HTTP client authorization retry examples](#http-client-authorization-retry-examples) - * [HTTP client redirects examples](#http-client-redirects-examples) - * [HTTP client call: DNS error](#http-client-call-dns-error) - * [HTTP client call: Internal Server Error](#http-client-call-internal-server-error) - * [HTTP server call: connection dropped before response body was sent](#http-server-call-connection-dropped-before-response-body-was-sent) + - [HTTP client-server example](#http-client-server-example) + - [HTTP client retries examples](#http-client-retries-examples) + - [HTTP client authorization retry examples](#http-client-authorization-retry-examples) + - [HTTP client redirects examples](#http-client-redirects-examples) + - [HTTP client call: DNS error](#http-client-call-dns-error) + - [HTTP client call: Internal Server Error](#http-client-call-internal-server-error) + - [HTTP server call: connection dropped before response body was sent](#http-server-call-connection-dropped-before-response-body-was-sent) diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index ffb30d89c2..47deec0d23 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -10,7 +10,7 @@ linkTitle: Kafka - [Span attributes](#span-attributes) - [Examples](#examples) - * [Apache Kafka with Quarkus or Spring Boot Example](#apache-kafka-with-quarkus-or-spring-boot-example) + - [Apache Kafka with Quarkus or Spring Boot Example](#apache-kafka-with-quarkus-or-spring-boot-example) diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index d715d1100d..f650cfd9bf 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -8,13 +8,13 @@ - [Common attributes](#common-attributes) - [Producer metrics](#producer-metrics) - * [Metric: `messaging.publish.duration`](#metric-messagingpublishduration) - * [Metric: `messaging.publish.messages`](#metric-messagingpublishmessages) + - [Metric: `messaging.publish.duration`](#metric-messagingpublishduration) + - [Metric: `messaging.publish.messages`](#metric-messagingpublishmessages) - [Consumer metrics](#consumer-metrics) - * [Metric: `messaging.receive.duration`](#metric-messagingreceiveduration) - * [Metric: `messaging.receive.messages`](#metric-messagingreceivemessages) - * [Metric: `messaging.process.duration`](#metric-messagingprocessduration) - * [Metric: `messaging.process.messages`](#metric-messagingprocessmessages) + - [Metric: `messaging.receive.duration`](#metric-messagingreceiveduration) + - [Metric: `messaging.receive.messages`](#metric-messagingreceivemessages) + - [Metric: `messaging.process.duration`](#metric-messagingprocessduration) + - [Metric: `messaging.process.messages`](#metric-messagingprocessmessages) diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index b93932c8b6..7cff828c2c 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -7,30 +7,30 @@ - [Definitions](#definitions) - * [Message](#message) - * [Producer](#producer) - * [Consumer](#consumer) - * [Intermediary](#intermediary) - * [Destinations](#destinations) - * [Message consumption](#message-consumption) - * [Conversations](#conversations) - * [Temporary and anonymous destinations](#temporary-and-anonymous-destinations) + - [Message](#message) + - [Producer](#producer) + - [Consumer](#consumer) + - [Intermediary](#intermediary) + - [Destinations](#destinations) + - [Message consumption](#message-consumption) + - [Conversations](#conversations) + - [Temporary and anonymous destinations](#temporary-and-anonymous-destinations) - [Conventions](#conventions) - * [Context propagation](#context-propagation) - * [Span name](#span-name) - * [Operation names](#operation-names) - * [Span kind](#span-kind) - * [Trace structure](#trace-structure) - + [Producer spans](#producer-spans) - + [Consumer spans](#consumer-spans) + - [Context propagation](#context-propagation) + - [Span name](#span-name) + - [Operation names](#operation-names) + - [Span kind](#span-kind) + - [Trace structure](#trace-structure) + - [Producer spans](#producer-spans) + - [Consumer spans](#consumer-spans) - [Messaging attributes](#messaging-attributes) - * [Consumer attributes](#consumer-attributes) - * [Per-message attributes](#per-message-attributes) - * [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems) + - [Consumer attributes](#consumer-attributes) + - [Per-message attributes](#per-message-attributes) + - [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems) - [Examples](#examples) - * [Topic with multiple consumers](#topic-with-multiple-consumers) - * [Batch receiving](#batch-receiving) - * [Batch publishing](#batch-publishing) + - [Topic with multiple consumers](#topic-with-multiple-consumers) + - [Batch receiving](#batch-receiving) + - [Batch publishing](#batch-publishing) - [Semantic Conventions for specific messaging technologies](#semantic-conventions-for-specific-messaging-technologies) diff --git a/docs/mobile/events.md b/docs/mobile/events.md index 70a5d6fdc3..e626f2c9c3 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -9,8 +9,8 @@ events on mobile platforms. All mobile events MUST use a namespace of - [Lifecycle instrumentation](#lifecycle-instrumentation) - * [iOS](#ios) - * [Android](#android) + - [iOS](#ios) + - [Android](#android) diff --git a/docs/resource/README.md b/docs/resource/README.md index 5dd529d264..5c62168b6c 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -19,8 +19,8 @@ This document defines standard attributes for resources. These attributes are ty - [TODOs](#todos) - [Document Conventions](#document-conventions) - [Attributes with Special Handling](#attributes-with-special-handling) - * [Semantic Attributes with Dedicated Environment Variable](#semantic-attributes-with-dedicated-environment-variable) - * [Semantic Attributes with SDK-provided Default Value](#semantic-attributes-with-sdk-provided-default-value) + - [Semantic Attributes with Dedicated Environment Variable](#semantic-attributes-with-dedicated-environment-variable) + - [Semantic Attributes with SDK-provided Default Value](#semantic-attributes-with-sdk-provided-default-value) - [Service](#service) - [Service (Experimental)](#service-experimental) - [Telemetry SDK](#telemetry-sdk) diff --git a/docs/resource/process.md b/docs/resource/process.md index 8156fbcd2a..36403a2de4 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -8,13 +8,13 @@ - [Process](#process) - [Process runtimes](#process-runtimes) - * [Erlang Runtimes](#erlang-runtimes) - * [Go Runtimes](#go-runtimes) - * [Java runtimes](#java-runtimes) - * [JavaScript runtimes](#javascript-runtimes) - * [.NET Runtimes](#net-runtimes) - * [Python Runtimes](#python-runtimes) - * [Ruby Runtimes](#ruby-runtimes) + - [Erlang Runtimes](#erlang-runtimes) + - [Go Runtimes](#go-runtimes) + - [Java runtimes](#java-runtimes) + - [JavaScript runtimes](#javascript-runtimes) + - [.NET Runtimes](#net-runtimes) + - [Python Runtimes](#python-runtimes) + - [Ruby Runtimes](#ruby-runtimes) diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 106e2e6c4a..693653d92e 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -17,20 +17,20 @@ metrics can be filtered for finer grain analysis. - [Metric instruments](#metric-instruments) - * [RPC Server](#rpc-server) - + [Metric: `rpc.server.duration`](#metric-rpcserverduration) - + [Metric: `rpc.server.request.size`](#metric-rpcserverrequestsize) - + [Metric: `rpc.server.response.size`](#metric-rpcserverresponsesize) - + [Metric: `rpc.server.requests_per_rpc`](#metric-rpcserverrequests_per_rpc) - + [Metric: `rpc.server.responses_per_rpc`](#metric-rpcserverresponses_per_rpc) - * [RPC Client](#rpc-client) - + [Metric: `rpc.client.duration`](#metric-rpcclientduration) - + [Metric: `rpc.client.request.size`](#metric-rpcclientrequestsize) - + [Metric: `rpc.client.response.size`](#metric-rpcclientresponsesize) - + [Metric: `rpc.client.requests_per_rpc`](#metric-rpcclientrequests_per_rpc) - + [Metric: `rpc.client.responses_per_rpc`](#metric-rpcclientresponses_per_rpc) + - [RPC Server](#rpc-server) + - [Metric: `rpc.server.duration`](#metric-rpcserverduration) + - [Metric: `rpc.server.request.size`](#metric-rpcserverrequestsize) + - [Metric: `rpc.server.response.size`](#metric-rpcserverresponsesize) + - [Metric: `rpc.server.requests_per_rpc`](#metric-rpcserverrequests_per_rpc) + - [Metric: `rpc.server.responses_per_rpc`](#metric-rpcserverresponses_per_rpc) + - [RPC Client](#rpc-client) + - [Metric: `rpc.client.duration`](#metric-rpcclientduration) + - [Metric: `rpc.client.request.size`](#metric-rpcclientrequestsize) + - [Metric: `rpc.client.response.size`](#metric-rpcclientresponsesize) + - [Metric: `rpc.client.requests_per_rpc`](#metric-rpcclientrequests_per_rpc) + - [Metric: `rpc.client.responses_per_rpc`](#metric-rpcclientresponses_per_rpc) - [Attributes](#attributes) - * [Service name](#service-name) + - [Service name](#service-name) - [Semantic Conventions for specific RPC technologies](#semantic-conventions-for-specific-rpc-technologies) diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index c3a9554350..0fc18c483d 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -14,13 +14,13 @@ This document defines how to describe remote procedure calls - [Common remote procedure call conventions](#common-remote-procedure-call-conventions) - * [Span name](#span-name) - * [Common attributes](#common-attributes) - + [Service name](#service-name) - * [Client attributes](#client-attributes) - * [Server attributes](#server-attributes) - * [Events](#events) - * [Distinction from HTTP spans](#distinction-from-http-spans) + - [Span name](#span-name) + - [Common attributes](#common-attributes) + - [Service name](#service-name) + - [Client attributes](#client-attributes) + - [Server attributes](#server-attributes) + - [Events](#events) + - [Distinction from HTTP spans](#distinction-from-http-spans) - [Semantic Conventions for specific RPC technologies](#semantic-conventions-for-specific-rpc-technologies) diff --git a/docs/runtime/README.md b/docs/runtime/README.md index 24d221e3b6..8b8b2ebb1b 100644 --- a/docs/runtime/README.md +++ b/docs/runtime/README.md @@ -14,7 +14,7 @@ runtime environment spans, metrics and logs. - [Metrics](#metrics) - * [Attributes](#attributes) + - [Attributes](#attributes) diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 780c15afd3..3d27e0a24a 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -13,29 +13,29 @@ This document describes semantic conventions for JVM metrics in OpenTelemetry. - [JVM Memory](#jvm-memory) - * [Metric: `jvm.memory.used`](#metric-jvmmemoryused) - * [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) - * [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) - * [Metric: `jvm.memory.used_after_last_gc`](#metric-jvmmemoryused_after_last_gc) + - [Metric: `jvm.memory.used`](#metric-jvmmemoryused) + - [Metric: `jvm.memory.committed`](#metric-jvmmemorycommitted) + - [Metric: `jvm.memory.limit`](#metric-jvmmemorylimit) + - [Metric: `jvm.memory.used_after_last_gc`](#metric-jvmmemoryused_after_last_gc) - [JVM Garbage Collection](#jvm-garbage-collection) - * [Metric: `jvm.gc.duration`](#metric-jvmgcduration) + - [Metric: `jvm.gc.duration`](#metric-jvmgcduration) - [JVM Threads](#jvm-threads) - * [Metric: `jvm.thread.count`](#metric-jvmthreadcount) + - [Metric: `jvm.thread.count`](#metric-jvmthreadcount) - [JVM Classes](#jvm-classes) - * [Metric: `jvm.class.loaded`](#metric-jvmclassloaded) - * [Metric: `jvm.class.unloaded`](#metric-jvmclassunloaded) - * [Metric: `jvm.class.count`](#metric-jvmclasscount) + - [Metric: `jvm.class.loaded`](#metric-jvmclassloaded) + - [Metric: `jvm.class.unloaded`](#metric-jvmclassunloaded) + - [Metric: `jvm.class.count`](#metric-jvmclasscount) - [JVM CPU](#jvm-cpu) - * [Metric: `jvm.cpu.time`](#metric-jvmcputime) - * [Metric: `jvm.cpu.count`](#metric-jvmcpucount) - * [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) + - [Metric: `jvm.cpu.time`](#metric-jvmcputime) + - [Metric: `jvm.cpu.count`](#metric-jvmcpucount) + - [Metric: `jvm.cpu.recent_utilization`](#metric-jvmcpurecent_utilization) - [Experimental](#experimental) - * [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) - * [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) - * [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) - * [Metric: `jvm.buffer.memory.usage`](#metric-jvmbuffermemoryusage) - * [Metric: `jvm.buffer.memory.limit`](#metric-jvmbuffermemorylimit) - * [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) + - [Metric: `jvm.memory.init`](#metric-jvmmemoryinit) + - [Metric: `jvm.system.cpu.utilization`](#metric-jvmsystemcpuutilization) + - [Metric: `jvm.system.cpu.load_1m`](#metric-jvmsystemcpuload_1m) + - [Metric: `jvm.buffer.memory.usage`](#metric-jvmbuffermemoryusage) + - [Metric: `jvm.buffer.memory.limit`](#metric-jvmbuffermemorylimit) + - [Metric: `jvm.buffer.count`](#metric-jvmbuffercount) diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index a5c9f8ac01..f109d5f240 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -14,22 +14,22 @@ when creating instruments not explicitly defined in the specification. - [Common hardware attributes](#common-hardware-attributes) - [Metric Instruments](#metric-instruments) - * [`hw.` - Common hardware metrics](#hw---common-hardware-metrics) - * [`hw.host.` - Physical host metrics](#hwhost---physical-host-metrics) - * [`hw.battery.` - Battery metrics](#hwbattery---battery-metrics) - * [`hw.cpu.` - Physical processor metrics](#hwcpu---physical-processor-metrics) - * [`hw.disk_controller.` - Disk controller metrics](#hwdisk_controller---disk-controller-metrics) - * [`hw.enclosure.` - Enclosure metrics](#hwenclosure---enclosure-metrics) - * [`hw.fan.` - Fan metrics](#hwfan---fan-metrics) - * [`hw.gpu.` - GPU metrics](#hwgpu---gpu-metrics) - * [`hw.logical_disk.`- Logical disk metrics](#hwlogical_disk--logical-disk-metrics) - * [`hw.memory.` - Memory module metrics](#hwmemory---memory-module-metrics) - * [`hw.network.` - Network adapter metrics](#hwnetwork---network-adapter-metrics) - * [`hw.physical_disk.`- Physical disk metrics](#hwphysical_disk--physical-disk-metrics) - * [`hw.power_supply.` - Power supply metrics](#hwpower_supply---power-supply-metrics) - * [`hw.tape_drive.` - Tape drive metrics](#hwtape_drive---tape-drive-metrics) - * [`hw.temperature.` - Temperature sensor metrics](#hwtemperature---temperature-sensor-metrics) - * [`hw.voltage.` - Voltage sensor metrics](#hwvoltage---voltage-sensor-metrics) + - [`hw.` - Common hardware metrics](#hw---common-hardware-metrics) + - [`hw.host.` - Physical host metrics](#hwhost---physical-host-metrics) + - [`hw.battery.` - Battery metrics](#hwbattery---battery-metrics) + - [`hw.cpu.` - Physical processor metrics](#hwcpu---physical-processor-metrics) + - [`hw.disk_controller.` - Disk controller metrics](#hwdisk_controller---disk-controller-metrics) + - [`hw.enclosure.` - Enclosure metrics](#hwenclosure---enclosure-metrics) + - [`hw.fan.` - Fan metrics](#hwfan---fan-metrics) + - [`hw.gpu.` - GPU metrics](#hwgpu---gpu-metrics) + - [`hw.logical_disk.`- Logical disk metrics](#hwlogical_disk--logical-disk-metrics) + - [`hw.memory.` - Memory module metrics](#hwmemory---memory-module-metrics) + - [`hw.network.` - Network adapter metrics](#hwnetwork---network-adapter-metrics) + - [`hw.physical_disk.`- Physical disk metrics](#hwphysical_disk--physical-disk-metrics) + - [`hw.power_supply.` - Power supply metrics](#hwpower_supply---power-supply-metrics) + - [`hw.tape_drive.` - Tape drive metrics](#hwtape_drive---tape-drive-metrics) + - [`hw.temperature.` - Temperature sensor metrics](#hwtemperature---temperature-sensor-metrics) + - [`hw.voltage.` - Voltage sensor metrics](#hwvoltage---voltage-sensor-metrics) diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 35e343349e..31b1367200 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -20,16 +20,16 @@ metrics](/docs/runtime/README.md#metrics). - [Process Metrics](#process-metrics) - * [Metric: `process.cpu.time`](#metric-processcputime) - * [Metric: `process.cpu.utilization`](#metric-processcpuutilization) - * [Metric: `process.memory.usage`](#metric-processmemoryusage) - * [Metric: `process.memory.virtual`](#metric-processmemoryvirtual) - * [Metric: `process.disk.io`](#metric-processdiskio) - * [Metric: `process.network.io`](#metric-processnetworkio) - * [Metric: `process.thread.count`](#metric-processthreadcount) - * [Metric: `process.open_file_descriptor.count`](#metric-processopen_file_descriptorcount) - * [Metric: `process.context_switches`](#metric-processcontext_switches) - * [Metric: `process.paging.faults`](#metric-processpagingfaults) + - [Metric: `process.cpu.time`](#metric-processcputime) + - [Metric: `process.cpu.utilization`](#metric-processcpuutilization) + - [Metric: `process.memory.usage`](#metric-processmemoryusage) + - [Metric: `process.memory.virtual`](#metric-processmemoryvirtual) + - [Metric: `process.disk.io`](#metric-processdiskio) + - [Metric: `process.network.io`](#metric-processnetworkio) + - [Metric: `process.thread.count`](#metric-processthreadcount) + - [Metric: `process.open_file_descriptor.count`](#metric-processopen_file_descriptorcount) + - [Metric: `process.context_switches`](#metric-processcontext_switches) + - [Metric: `process.paging.faults`](#metric-processpagingfaults) diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 4f682cc030..38be351b98 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -22,40 +22,40 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam - [Processor Metrics](#processor-metrics) - * [Metric: `system.cpu.time`](#metric-systemcputime) - * [Metric: `system.cpu.utilization`](#metric-systemcpuutilization) - * [Metric: `system.cpu.physical.count`](#metric-systemcpuphysicalcount) - * [Metric: `system.cpu.logical.count`](#metric-systemcpulogicalcount) - * [Metric: `system.cpu.frequency`](#metric-systemcpufrequency) + - [Metric: `system.cpu.time`](#metric-systemcputime) + - [Metric: `system.cpu.utilization`](#metric-systemcpuutilization) + - [Metric: `system.cpu.physical.count`](#metric-systemcpuphysicalcount) + - [Metric: `system.cpu.logical.count`](#metric-systemcpulogicalcount) + - [Metric: `system.cpu.frequency`](#metric-systemcpufrequency) - [Memory Metrics](#memory-metrics) - * [Metric: `system.memory.usage`](#metric-systemmemoryusage) - * [Metric: `system.memory.limit`](#metric-systemmemorylimit) - * [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) + - [Metric: `system.memory.usage`](#metric-systemmemoryusage) + - [Metric: `system.memory.limit`](#metric-systemmemorylimit) + - [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) - [Paging/Swap Metrics](#pagingswap-metrics) - * [Metric: `system.paging.usage`](#metric-systempagingusage) - * [Metric: `system.paging.utilization`](#metric-systempagingutilization) - * [Metric: `system.paging.faults`](#metric-systempagingfaults) - * [Metric: `system.paging.operations`](#metric-systempagingoperations) + - [Metric: `system.paging.usage`](#metric-systempagingusage) + - [Metric: `system.paging.utilization`](#metric-systempagingutilization) + - [Metric: `system.paging.faults`](#metric-systempagingfaults) + - [Metric: `system.paging.operations`](#metric-systempagingoperations) - [Disk Controller Metrics](#disk-controller-metrics) - * [Metric: `system.disk.io`](#metric-systemdiskio) - * [Metric: `system.disk.operations`](#metric-systemdiskoperations) - * [Metric: `system.disk.io_time`](#metric-systemdiskio_time) - * [Metric: `system.disk.operation_time`](#metric-systemdiskoperation_time) - * [Metric: `system.disk.merged`](#metric-systemdiskmerged) + - [Metric: `system.disk.io`](#metric-systemdiskio) + - [Metric: `system.disk.operations`](#metric-systemdiskoperations) + - [Metric: `system.disk.io_time`](#metric-systemdiskio_time) + - [Metric: `system.disk.operation_time`](#metric-systemdiskoperation_time) + - [Metric: `system.disk.merged`](#metric-systemdiskmerged) - [Filesystem Metrics](#filesystem-metrics) - * [Metric: `system.filesystem.usage`](#metric-systemfilesystemusage) - * [Metric: `system.filesystem.utilization`](#metric-systemfilesystemutilization) + - [Metric: `system.filesystem.usage`](#metric-systemfilesystemusage) + - [Metric: `system.filesystem.utilization`](#metric-systemfilesystemutilization) - [Network Metrics](#network-metrics) - * [Metric: `system.network.dropped`](#metric-systemnetworkdropped) - * [Metric: `system.network.packets`](#metric-systemnetworkpackets) - * [Metric: `system.network.errors`](#metric-systemnetworkerrors) - * [Metric: `system.network.io`](#metric-systemnetworkio) - * [Metric: `system.network.connections`](#metric-systemnetworkconnections) + - [Metric: `system.network.dropped`](#metric-systemnetworkdropped) + - [Metric: `system.network.packets`](#metric-systemnetworkpackets) + - [Metric: `system.network.errors`](#metric-systemnetworkerrors) + - [Metric: `system.network.io`](#metric-systemnetworkio) + - [Metric: `system.network.connections`](#metric-systemnetworkconnections) - [Aggregate System Process Metrics](#aggregate-system-process-metrics) - * [Metric: `system.process.count`](#metric-systemprocesscount) - * [Metric: `system.process.created`](#metric-systemprocesscreated) + - [Metric: `system.process.count`](#metric-systemprocesscount) + - [Metric: `system.process.created`](#metric-systemprocesscreated) - [`system.{os}.` - OS Specific System Metrics](#systemos---os-specific-system-metrics) - * [Metric: `system.linux.memory.available`](#metric-systemlinuxmemoryavailable) + - [Metric: `system.linux.memory.available`](#metric-systemlinuxmemoryavailable) From 153b768fa620e3d69dd179bc0bec63d558213dc7 Mon Sep 17 00:00:00 2001 From: Miguel Luna <39376769+mlunadia@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:07:21 +0000 Subject: [PATCH 373/482] moving android to the registry attributes (#544) Signed-off-by: Miguel Luna <39376769+mlunadia@users.noreply.github.com> Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> Co-authored-by: Chris Mark Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/android.md | 8 ++++++++ docs/resource/android.md | 2 +- model/registry/android.yaml | 15 +++++++++++++++ model/resource/android.yaml | 9 +-------- 5 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 docs/attributes-registry/android.md create mode 100644 model/registry/android.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index ada3b9534f..113725054e 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -27,6 +27,7 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: +* [Android](android.md) * [Browser](browser.md) * [Client](client.md) * [Cloud](cloud.md) diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md new file mode 100644 index 0000000000..e8539f2b73 --- /dev/null +++ b/docs/attributes-registry/android.md @@ -0,0 +1,8 @@ +# Android + +## Android Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | + diff --git a/docs/resource/android.md b/docs/resource/android.md index 39daee5a8f..aa635d29ef 100644 --- a/docs/resource/android.md +++ b/docs/resource/android.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | Recommended | +| [`android.os.api_level`](../attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/android.yaml b/model/registry/android.yaml new file mode 100644 index 0000000000..cfdcac8a46 --- /dev/null +++ b/model/registry/android.yaml @@ -0,0 +1,15 @@ +groups: + - id: registry.android + prefix: android + type: attribute_group + brief: > + The Android platform on which the Android application is running. + attributes: + - id: os.api_level + type: string + stability: experimental + brief: > + Uniquely identifies the framework API revision offered by a version + (`os.version`) of the android operating system. More information can be found + [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). + examples: ['33', '32'] diff --git a/model/resource/android.yaml b/model/resource/android.yaml index cf4040f514..0f2b756eb9 100644 --- a/model/resource/android.yaml +++ b/model/resource/android.yaml @@ -5,11 +5,4 @@ groups: brief: > The Android platform on which the Android application is running. attributes: - - id: os.api_level - type: string - stability: experimental - brief: > - Uniquely identifies the framework API revision offered by a version - (`os.version`) of the android operating system. More information can be found - [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). - examples: ['33', '32'] + - ref: android.os.api_level From 6c79a1d9107c1833d95177beda84947ce1902792 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 6 Mar 2024 11:46:13 -0800 Subject: [PATCH 374/482] Deprecate db.connection_string (#769) --- .chloggen/769.yaml | 4 ++++ docs/attributes-registry/db.md | 10 +++++++++- docs/database/database-metrics.md | 18 +++++++++--------- docs/database/database-spans.md | 1 - docs/database/mongodb.md | 1 - docs/database/redis.md | 1 - docs/database/sql.md | 1 - model/metrics/database-metrics.yaml | 4 ++-- model/registry/db.yaml | 8 -------- model/registry/deprecated/db.yaml | 13 +++++++++++++ model/trace/database.yaml | 2 -- 11 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 .chloggen/769.yaml create mode 100644 model/registry/deprecated/db.yaml diff --git a/.chloggen/769.yaml b/.chloggen/769.yaml new file mode 100644 index 0000000000..8789e89f94 --- /dev/null +++ b/.chloggen/769.yaml @@ -0,0 +1,4 @@ +change_type: deprecation +component: db +note: Deprecate `db.connection_string` attribute in favor of `server.address` and `server.port` +issues: [724, 769] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index c178bbe971..5441b91de9 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -14,6 +14,7 @@ - [MSSQL Attributes](#mssql-attributes) - [Redis Attributes](#redis-attributes) - [SQL Attributes](#sql-attributes) +- [Deprecated DB Attributes](#deprecated-db-attributes) @@ -22,7 +23,6 @@ | Attribute | Type | Description | Examples | |---|---|---|---| -| `db.connection_string` | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | | `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | @@ -221,3 +221,11 @@ **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + +## Deprecated DB Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | + \ No newline at end of file diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 402607fdfd..cd476652e0 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -52,7 +52,7 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | | `state` | string | The state of a connection in the pool | `idle` | Required | `state` MUST be one of the following: @@ -75,7 +75,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.idle.min` @@ -91,7 +91,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.max` @@ -107,7 +107,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.pending_requests` @@ -123,7 +123,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.timeouts` @@ -139,7 +139,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.create_time` @@ -155,7 +155,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.wait_time` @@ -171,7 +171,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | ### Metric: `db.client.connections.use_time` @@ -187,7 +187,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, then the [db.connection_string](/docs/database/database-spans.md#common-attributes) should be used | `myDataSource` | Required | +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 5965c90a41..6324709e0c 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -73,7 +73,6 @@ Some database systems may allow a connection to switch to a different `db.user`, | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.connection_string`](../attributes-registry/db.md) | string | The connection string used to connect to the database. It is recommended to remove embedded credentials. | `Server=(localdb)\v11.0;Integrated Security=true;` | Recommended | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: If different from the `server.address` | | [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | | [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index ebb2a5a883..71558732c8 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -26,7 +26,6 @@ described on this page. | :---------------------- | :----------------------------------------------------------- | | Span name | `"products.findAndModify"` | | `db.system` | `"mongodb"` | -| `db.connection_string` | not set | | `db.user` | `"the_user"` | | `server.address` | `"mongodb0.example.com"` | | `server.port` | `27017` | diff --git a/docs/database/redis.md b/docs/database/redis.md index 62637688e3..838d50822e 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -34,7 +34,6 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an |:--------------------------| :-------------------------------------------- | | Span name | `"HMSET myhash"` | | `db.system` | `"redis"` | -| `db.connection_string` | not set | | `db.user` | not set | | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | diff --git a/docs/database/sql.md b/docs/database/sql.md index 5eaddacf39..d60e3e158e 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -29,7 +29,6 @@ This is an example of attributes for a MySQL database span: |:------------------------| :----------------------------------------------------------- | | Span name | `"SELECT ShopDb.orders"` | | `db.system` | `"mysql"` | -| `db.connection_string` | `"Server=shopdb.example.com;Database=ShopDb;Uid=billing_user;TableCache=true;UseCompression=True;MinimumPoolSize=10;MaximumPoolSize=50;"` | | `db.user` | `"billing_user"` | | `server.address` | `"shopdb.example.com"` | | `server.port` | `3306` | diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index 0691e6c625..bfcc7020ec 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -22,8 +22,8 @@ groups: brief: > The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, - then the [db.connection_string](/docs/database/database-spans.md#common-attributes) - should be used + instrumentation should use a combination of `server.address` and `server.port` attributes + formatted as `server.address:server.port`. examples: ["myDataSource"] - id: metric.db.client.connections.usage diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 6926fa53b6..a94eef9471 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -81,14 +81,6 @@ groups: value MUST NOT be set. examples: 'mytable' tag: tech-specific-cassandra - - id: connection_string - type: string - stability: experimental - brief: > - The connection string used to connect to the database. - It is recommended to remove embedded credentials. - examples: 'Server=(localdb)\v11.0;Integrated Security=true;' - tag: db-generic - id: cosmosdb.client_id type: string stability: experimental diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml new file mode 100644 index 0000000000..a3718cf6bc --- /dev/null +++ b/model/registry/deprecated/db.yaml @@ -0,0 +1,13 @@ +groups: + - id: attributes.db.deprecated + prefix: db + type: attribute_group + brief: > + "Describes deprecated db attributes." + attributes: + - id: connection_string + type: string + brief: 'Deprecated, use `server.address`, `server.port` attributes instead.' + deprecated: > + "Removed in favor of `server.address` and `server.port`." + examples: Server=(localdb)\v11.0;Integrated Security=true; diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 8637fbed28..74ea98ceb2 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -7,8 +7,6 @@ groups: attributes: - ref: db.system requirement_level: required - - - ref: db.connection_string - ref: db.user - ref: db.name requirement_level: From 88d66b53e14590b0fac57455bde49d763817f86f Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 7 Mar 2024 08:23:54 -0800 Subject: [PATCH 375/482] Move DNS lookup metric outside of .NET semconv (#785) --- .chloggen/785.yaml | 4 ++ docs/attributes-registry/dns.md | 14 +++++++ docs/dns/dns-metrics.md | 55 +++++++++++++++++++++++++++ docs/dotnet/dotnet-dns-metrics.md | 7 +--- model/metrics/dns.yaml | 23 +++++++++++ model/metrics/dotnet/dotnet-http.yaml | 38 ------------------ model/registry/dns.yaml | 18 +++++++++ 7 files changed, 116 insertions(+), 43 deletions(-) create mode 100644 .chloggen/785.yaml create mode 100644 docs/attributes-registry/dns.md create mode 100644 docs/dns/dns-metrics.md create mode 100644 model/metrics/dns.yaml create mode 100644 model/registry/dns.yaml diff --git a/.chloggen/785.yaml b/.chloggen/785.yaml new file mode 100644 index 0000000000..f00ba848ef --- /dev/null +++ b/.chloggen/785.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: dns +note: Introduces common DNS lookup duration metric and attributes. +issues: [404] diff --git a/docs/attributes-registry/dns.md b/docs/attributes-registry/dns.md new file mode 100644 index 0000000000..eeb6e10d5e --- /dev/null +++ b/docs/attributes-registry/dns.md @@ -0,0 +1,14 @@ + + +# DNS + +## DNS Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | + +**[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. + \ No newline at end of file diff --git a/docs/dns/dns-metrics.md b/docs/dns/dns-metrics.md new file mode 100644 index 0000000000..46262286cc --- /dev/null +++ b/docs/dns/dns-metrics.md @@ -0,0 +1,55 @@ + + +# Semantic Conventions for DNS queries + +**Status**: [Experimental][DocumentStatus] + +This document defines semantic conventions to apply when instrumenting DNS queries. + + + + + +- [Metrics](#metrics) + - [Metric: `dns.lookup.duration`](#metric-dnslookupduration) + + + +## Metrics + +### Metric: `dns.lookup.duration` + +**Status**: [Experimental][DocumentStatus] + +This metric is optional. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`dns.question.name`](../attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `dot.net` | Required | +| [`error.type`](../attributes-registry/error.md) | string | Describes the error the DNS lookup failed with. [2] | `host_not_found`; `no_recovery`; `java.net.UnknownHostException` | Conditionally Required: if and only if an error has occurred. | + +**[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. + +**[2]:** Instrumentations SHOULD use error code such as one of errors reported by `getaddrinfo`([Linux or other POSIX systems](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) / [Windows](https://learn.microsoft.com/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo)) or one reported by the runtime or client library. If error code is not available, the full name of exception type SHOULD be used. + +`error.type` 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 | +|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-dns-metrics.md b/docs/dotnet/dotnet-dns-metrics.md index 4240445dd1..6df6fb85d3 100644 --- a/docs/dotnet/dotnet-dns-metrics.md +++ b/docs/dotnet/dotnet-dns-metrics.md @@ -19,19 +19,17 @@ This article defines semantic conventions for DNS metrics emitted by .NET. ### Metric: `dns.lookup.duration` -this metric SHOULD be specified with +This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | | `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. [1] | **[1]:** Meter name: `System.Net.NameResolution`; Added in: .NET 8.0 - - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `dot.net` | Required | @@ -55,6 +53,5 @@ for more details. | Value | Description | |---|---| | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/metrics/dns.yaml b/model/metrics/dns.yaml new file mode 100644 index 0000000000..627213d90f --- /dev/null +++ b/model/metrics/dns.yaml @@ -0,0 +1,23 @@ +groups: + - id: metric.dns.lookup.duration + type: metric + metric_name: dns.lookup.duration + stability: experimental + brief: Measures the time taken to perform a DNS lookup. + instrument: histogram + unit: "s" + attributes: + - ref: dns.question.name + requirement_level: required + examples: ["www.example.com", "dot.net"] + - ref: error.type + requirement_level: + conditionally_required: if and only if an error has occurred. + brief: Describes the error the DNS lookup failed with. + note: > + Instrumentations SHOULD use error code such as one of errors reported by + `getaddrinfo`([Linux or other POSIX systems](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) / + [Windows](https://learn.microsoft.com/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo)) or one reported by the + runtime or client library. + If error code is not available, the full name of exception type SHOULD be used. + examples: ["host_not_found", "no_recovery", "java.net.UnknownHostException"] diff --git a/model/metrics/dotnet/dotnet-http.yaml b/model/metrics/dotnet/dotnet-http.yaml index 9a326bb5d7..6b3723ddb8 100644 --- a/model/metrics/dotnet/dotnet-http.yaml +++ b/model/metrics/dotnet/dotnet-http.yaml @@ -1,42 +1,4 @@ groups: - - id: metric.dotnet.dns.lookup.duration - type: metric - metric_name: dns.lookup.duration - brief: Measures the time taken to perform a DNS lookup. - instrument: histogram - unit: "s" - note: | - Meter name: `System.Net.NameResolution`; Added in: .NET 8.0 - attributes: - - id: dns.question.name - type: string - brief: The name being queried. - requirement_level: required - examples: ["www.example.com", "dot.net"] - note: > - The name being queried. - - If the name field contains non-printable - characters (below 32 or above 126), those characters should be represented - as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. - Tabs, carriage returns, and line feeds should be converted to \t, \r, and - \n respectively. - - ref: error.type - brief: One of the resolution errors or the full name of exception type. - requirement_level: - conditionally_required: if and only if an error has occurred. - note: | - The following errors codes are reported: - - - "host_not_found" - - "try_again" - - "address_family_not_supported" - - "no_recovery" - - See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) - for more details. - examples: ["host_not_found", "no_recovery", "System.Net.Sockets.SocketException"] - - id: dotnet.http.client.common.attributes type: attribute_group brief: "Common HTTP client attributes" diff --git a/model/registry/dns.yaml b/model/registry/dns.yaml new file mode 100644 index 0000000000..d4042c4add --- /dev/null +++ b/model/registry/dns.yaml @@ -0,0 +1,18 @@ +groups: + - id: registry.dns + type: attribute_group + prefix: dns + brief: > + This document defines the shared attributes used to report a DNS query. + attributes: + - id: question.name + type: string + stability: experimental + brief: The name being queried. + examples: ["www.example.com", "opentelemetry.io"] + note: > + If the name field contains non-printable + characters (below 32 or above 126), those characters should be represented + as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. + Tabs, carriage returns, and line feeds should be converted to \t, \r, and + \n respectively. From 3d409a7d4abe03e6b3df0c9c34e6086481b5a71a Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 7 Mar 2024 18:04:52 +0100 Subject: [PATCH 376/482] move faas to registry (#525) Co-authored-by: Joao Grassi Co-authored-by: Josh Suereth --- docs/attributes-registry/README.md | 1 + docs/attributes-registry/faas.md | 93 ++++++++++++++ docs/faas/faas-metrics.md | 18 +-- docs/faas/faas-spans.md | 28 ++--- docs/resource/faas.md | 8 +- model/faas-common.yaml | 68 +--------- model/registry/faas.yaml | 195 +++++++++++++++++++++++++++++ model/resource/faas.yaml | 62 +-------- model/trace/faas.yaml | 84 +++---------- 9 files changed, 343 insertions(+), 214 deletions(-) create mode 100644 docs/attributes-registry/faas.md create mode 100644 model/registry/faas.yaml diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 113725054e..00ff6ad8e6 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -39,6 +39,7 @@ Currently, the following namespaces exist: * [Disk](disk.md) * [Error](error.md) * [Exception](exception.md) +* [FaaS](faas.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/faas.md b/docs/attributes-registry/faas.md new file mode 100644 index 0000000000..4f8f5e4ea8 --- /dev/null +++ b/docs/attributes-registry/faas.md @@ -0,0 +1,93 @@ + + +# FaaS + +## FaaS Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | +| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | +| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | +| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | +| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | +| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | +| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [1] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | +| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | +| `faas.invoked_name` | string | The name of the invoked function. [2] | `my-function` | +| `faas.invoked_provider` | string | The cloud provider of the invoked function. [3] | `alibaba_cloud` | +| `faas.invoked_region` | string | The cloud region of the invoked function. [4] | `eu-central-1` | +| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [5] | `134217728` | +| `faas.name` | string | The name of the single function that this runtime instance executes. [6] | `my-function`; `myazurefunctionapp/some-function-name` | +| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | +| `faas.version` | string | The immutable version of the function being executed. [7] | `26`; `pinkfroid-00002` | + +**[1]:** * **AWS Lambda:** Use the (full) log stream name. + +**[2]:** SHOULD be equal to the `faas.name` resource attribute of the invoked function. + +**[3]:** SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. + +**[4]:** SHOULD be equal to the `cloud.region` resource attribute of the invoked function. + +**[5]:** It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). + +**[6]:** This is the name of the function as configured/deployed on the FaaS +platform and is usually different from the name of the callback +function (which may be stored in the +[`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) +span attributes). + +For some cloud providers, the above definition is ambiguous. The following +definition of function name MUST be used for this attribute +(and consequently the span name) for the listed cloud providers/products: + +* **Azure:** The full name `/`, i.e., function app name + followed by a forward slash followed by the function name (this form + can also be seen in the resource JSON for the function). + This means that a span attribute MUST be used, as an Azure function + app can host multiple functions that would usually share + a TracerProvider (see also the `cloud.resource_id` attribute). + +**[7]:** Depending on the cloud provider and platform, use: + +* **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + (an integer represented as a decimal string). +* **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) + (i.e., the function name plus the revision suffix). +* **Google Cloud Functions:** The value of the + [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). +* **Azure Functions:** Not applicable. Do not set this attribute. + +`faas.document.operation` 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 | +|---|---| +| `insert` | When a new object is created. | +| `edit` | When an object is modified. | +| `delete` | When an object is deleted. | + +`faas.invoked_provider` 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 | +|---|---| +| `alibaba_cloud` | Alibaba Cloud | +| `aws` | Amazon Web Services | +| `azure` | Microsoft Azure | +| `gcp` | Google Cloud Platform | +| `tencent_cloud` | Tencent Cloud | + +`faas.trigger` MUST be one of the following: + +| Value | Description | +|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | +| `http` | To provide an answer to an inbound HTTP request | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | +| `timer` | A function is scheduled to be executed regularly | +| `other` | If none of the others apply | + \ No newline at end of file diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index d6046b04f9..22dbc92556 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -58,7 +58,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -88,7 +88,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -114,7 +114,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -140,7 +140,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -166,7 +166,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -192,7 +192,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -218,7 +218,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -248,7 +248,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: @@ -274,7 +274,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | `faas.trigger` MUST be one of the following: diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 34a03528db..ee38715df3 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -42,8 +42,8 @@ If Spans following this convention are produced, a Resource of type `faas` MUST | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | -| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | -| `faas.trigger` | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | +| [`faas.invocation_id`](../attributes-registry/faas.md) | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | **[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. @@ -122,8 +122,8 @@ For incoming FaaS spans, the span kind MUST be `Server`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | Recommended | -| `faas.trigger` | string | Type of the trigger which caused this function invocation. [1] | `datasource` | Required | +| [`faas.coldstart`](../attributes-registry/faas.md) | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | Recommended | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [1] | `datasource` | Required | **[1]:** For the server/consumer span on the incoming side, `faas.trigger` MUST be set. @@ -161,9 +161,9 @@ which the invoked FaaS instance reports about itself, if it's instrumented. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.invoked_name` | string | The name of the invoked function. [1] | `my-function` | Required | -| `faas.invoked_provider` | string | The cloud provider of the invoked function. [2] | `alibaba_cloud` | Required | -| `faas.invoked_region` | string | The cloud region of the invoked function. [3] | `eu-central-1` | Conditionally Required: [4] | +| [`faas.invoked_name`](../attributes-registry/faas.md) | string | The name of the invoked function. [1] | `my-function` | Required | +| [`faas.invoked_provider`](../attributes-registry/faas.md) | string | The cloud provider of the invoked function. [2] | `alibaba_cloud` | Required | +| [`faas.invoked_region`](../attributes-registry/faas.md) | string | The cloud region of the invoked function. [3] | `eu-central-1` | Conditionally Required: [4] | **[1]:** SHOULD be equal to the `faas.name` resource attribute of the invoked function. @@ -196,13 +196,13 @@ This section describes how to handle the span creation and additional attributes A datasource function is triggered as a response to some data source operation such as a database or filesystem read/write. FaaS instrumentations that produce `faas` spans with trigger `datasource`, SHOULD use the following set of attributes. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | Required | -| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | Recommended | -| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | Required | -| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | +| [`faas.document.collection`](../attributes-registry/faas.md) | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | Required | +| [`faas.document.name`](../attributes-registry/faas.md) | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | Recommended | +| [`faas.document.operation`](../attributes-registry/faas.md) | string | Describes the type of the operation that was performed on the data. | `insert` | Required | +| [`faas.document.time`](../attributes-registry/faas.md) | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | `faas.document.operation` 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. @@ -232,8 +232,8 @@ A function is scheduled to be executed regularly. The following additional attri | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | Recommended | -| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | +| [`faas.cron`](../attributes-registry/faas.md) | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | Recommended | +| [`faas.time`](../attributes-registry/faas.md) | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | ### Other diff --git a/docs/resource/faas.md b/docs/resource/faas.md index c83eabc193..b354c2fdad 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -17,10 +17,10 @@ See also: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | -| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | -| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | -| `faas.name` | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | -| `faas.version` | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | Recommended | +| [`faas.instance`](../attributes-registry/faas.md) | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | +| [`faas.max_memory`](../attributes-registry/faas.md) | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | +| [`faas.name`](../attributes-registry/faas.md) | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | +| [`faas.version`](../attributes-registry/faas.md) | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | Recommended | **[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. diff --git a/model/faas-common.yaml b/model/faas-common.yaml index 11a8b430c0..9d951485b2 100644 --- a/model/faas-common.yaml +++ b/model/faas-common.yaml @@ -4,66 +4,12 @@ groups: brief: "Describes FaaS attributes." prefix: faas attributes: - - id: trigger - brief: 'Type of the trigger which caused this function invocation.' - type: - allow_custom_values: false - members: - - id: datasource - value: 'datasource' - brief: 'A response to some data source operation such as a database or filesystem read/write' - - id: http - value: 'http' - brief: 'To provide an answer to an inbound HTTP request' - - id: pubsub - value: 'pubsub' - brief: 'A function is set to be executed when messages are sent to a messaging system' - - id: timer - value: 'timer' - brief: 'A function is scheduled to be executed regularly' - - id: other - value: 'other' - brief: 'If none of the others apply' - stability: experimental - - id: invoked_name - type: string - stability: experimental + - ref: faas.trigger + - ref: faas.invoked_name requirement_level: required - brief: > - The name of the invoked function. - note: > - SHOULD be equal to the `faas.name` resource attribute of the - invoked function. - examples: 'my-function' - - id: invoked_provider - type: - allow_custom_values: true - members: - - id: 'alibaba_cloud' - value: 'alibaba_cloud' - brief: 'Alibaba Cloud' - - id: 'aws' - value: 'aws' - brief: 'Amazon Web Services' - - id: 'azure' - value: 'azure' - brief: 'Microsoft Azure' - - id: 'gcp' - value: 'gcp' - brief: 'Google Cloud Platform' - - id: 'tencent_cloud' - value: 'tencent_cloud' - brief: 'Tencent Cloud' - stability: experimental + - ref: faas.invoked_provider requirement_level: required - brief: > - The cloud provider of the invoked function. - note: > - SHOULD be equal to the `cloud.provider` resource attribute of the - invoked function. - - id: invoked_region - type: string - stability: experimental + - ref: faas.invoked_region requirement_level: conditionally_required: > For some cloud providers, like AWS or GCP, the region in which a @@ -73,9 +19,3 @@ groups: `faas.invoked_region` MUST be set accordingly. If the region is unknown to the client or not required for identifying the invoked function, setting `faas.invoked_region` is optional. - brief: > - The cloud region of the invoked function. - note: > - SHOULD be equal to the `cloud.region` resource attribute of the - invoked function. - examples: 'eu-central-1' diff --git a/model/registry/faas.yaml b/model/registry/faas.yaml new file mode 100644 index 0000000000..12c5816a20 --- /dev/null +++ b/model/registry/faas.yaml @@ -0,0 +1,195 @@ +groups: + - id: registry.faas + brief: FaaS attributes + type: attribute_group + prefix: faas + attributes: + - id: name + type: string + stability: experimental + brief: > + The name of the single function that this runtime instance executes. + note: | + This is the name of the function as configured/deployed on the FaaS + platform and is usually different from the name of the callback + function (which may be stored in the + [`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) + span attributes). + + For some cloud providers, the above definition is ambiguous. The following + definition of function name MUST be used for this attribute + (and consequently the span name) for the listed cloud providers/products: + + * **Azure:** The full name `/`, i.e., function app name + followed by a forward slash followed by the function name (this form + can also be seen in the resource JSON for the function). + This means that a span attribute MUST be used, as an Azure function + app can host multiple functions that would usually share + a TracerProvider (see also the `cloud.resource_id` attribute). + examples: ['my-function', 'myazurefunctionapp/some-function-name'] + - id: version + type: string + stability: experimental + brief: The immutable version of the function being executed. + note: | + Depending on the cloud provider and platform, use: + + * **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + (an integer represented as a decimal string). + * **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) + (i.e., the function name plus the revision suffix). + * **Google Cloud Functions:** The value of the + [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). + * **Azure Functions:** Not applicable. Do not set this attribute. + examples: ['26', 'pinkfroid-00002'] + - id: instance + type: string + stability: experimental + brief: > + The execution environment ID as a string, that will be potentially reused + for other invocations to the same function/function version. + note: > + * **AWS Lambda:** Use the (full) log stream name. + examples: ['2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'] + - id: max_memory + type: int + stability: experimental + brief: > + The amount of memory available to the serverless function converted to Bytes. + note: > + It's recommended to set this attribute since e.g. too little memory can easily + stop a Java AWS Lambda function from working correctly. + On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` + provides this information (which must be multiplied by 1,048,576). + examples: 134217728 + - id: trigger + stability: experimental + brief: > + Type of the trigger which caused this function invocation. + type: + allow_custom_values: false + members: + - id: datasource + value: 'datasource' + brief: 'A response to some data source operation such as a database or filesystem read/write' + - id: http + value: 'http' + brief: 'To provide an answer to an inbound HTTP request' + - id: pubsub + value: 'pubsub' + brief: 'A function is set to be executed when messages are sent to a messaging system' + - id: timer + value: 'timer' + brief: 'A function is scheduled to be executed regularly' + - id: other + value: 'other' + brief: 'If none of the others apply' + - id: invoked_name + type: string + stability: experimental + brief: > + The name of the invoked function. + note: > + SHOULD be equal to the `faas.name` resource attribute of the + invoked function. + examples: 'my-function' + - id: invoked_provider + stability: experimental + type: + allow_custom_values: true + members: + - id: 'alibaba_cloud' + value: 'alibaba_cloud' + brief: 'Alibaba Cloud' + - id: 'aws' + value: 'aws' + brief: 'Amazon Web Services' + - id: 'azure' + value: 'azure' + brief: 'Microsoft Azure' + - id: 'gcp' + value: 'gcp' + brief: 'Google Cloud Platform' + - id: 'tencent_cloud' + value: 'tencent_cloud' + brief: 'Tencent Cloud' + brief: > + The cloud provider of the invoked function. + note: > + SHOULD be equal to the `cloud.provider` resource attribute of the + invoked function. + - id: invoked_region + type: string + stability: experimental + brief: > + The cloud region of the invoked function. + note: > + SHOULD be equal to the `cloud.region` resource attribute of the + invoked function. + examples: 'eu-central-1' + - id: invocation_id + type: string + stability: experimental + brief: > + The invocation ID of the current function invocation. + examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' + - id: time + type: string + stability: experimental + brief: > + A string containing the function invocation time in the + [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) + format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + examples: "2020-01-23T13:47:06Z" + - id: cron + type: string + stability: experimental + brief: > + A string containing the schedule period as + [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). + examples: "0/5 * * * ? *" + - id: coldstart + type: boolean + stability: experimental + brief: > + A boolean that is true if the serverless function is executed for the + first time (aka cold-start). + - id: document.collection + type: string + stability: experimental + brief: > + The name of the source on which the triggering operation was performed. + For example, in Cloud Storage or S3 corresponds to the bucket name, + and in Cosmos DB to the database name. + examples: ['myBucketName', 'myDbName'] + - id: document.operation + stability: experimental + type: + allow_custom_values: true + members: + - id: insert + value: 'insert' + brief: 'When a new object is created.' + - id: edit + value: 'edit' + brief: 'When an object is modified.' + - id: delete + value: 'delete' + brief: 'When an object is deleted.' + brief: 'Describes the type of the operation that was performed on the data.' + - id: document.time + type: string + stability: experimental + brief: > + A string containing the time when the data was accessed in the + [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) + format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + examples: "2020-01-23T13:47:06Z" + - id: document.name + type: string + stability: experimental + brief: > + The document name/table subjected to the operation. + For example, in Cloud Storage or S3 is the name of + the file, and in Cosmos DB the table name. + examples: ["myFile.txt", "myTableName"] diff --git a/model/resource/faas.yaml b/model/resource/faas.yaml index e73ee38646..ab028c89bb 100644 --- a/model/resource/faas.yaml +++ b/model/resource/faas.yaml @@ -5,63 +5,9 @@ groups: brief: > A serverless instance. attributes: - - id: name - type: string - stability: experimental + - ref: faas.name requirement_level: required - brief: > - The name of the single function that this runtime instance executes. - note: | - This is the name of the function as configured/deployed on the FaaS - platform and is usually different from the name of the callback - function (which may be stored in the - [`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) - span attributes). - - For some cloud providers, the above definition is ambiguous. The following - definition of function name MUST be used for this attribute - (and consequently the span name) for the listed cloud providers/products: - - * **Azure:** The full name `/`, i.e., function app name - followed by a forward slash followed by the function name (this form - can also be seen in the resource JSON for the function). - This means that a span attribute MUST be used, as an Azure function - app can host multiple functions that would usually share - a TracerProvider (see also the `cloud.resource_id` attribute). - examples: ['my-function', 'myazurefunctionapp/some-function-name'] - - id: version - type: string - stability: experimental - brief: The immutable version of the function being executed. - note: | - Depending on the cloud provider and platform, use: - - * **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) - (an integer represented as a decimal string). - * **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) - (i.e., the function name plus the revision suffix). - * **Google Cloud Functions:** The value of the - [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). - * **Azure Functions:** Not applicable. Do not set this attribute. - examples: ['26', 'pinkfroid-00002'] - - id: instance - type: string - stability: experimental - brief: > - The execution environment ID as a string, that will be potentially reused - for other invocations to the same function/function version. - note: > - * **AWS Lambda:** Use the (full) log stream name. - examples: ['2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'] - - id: max_memory - type: int - stability: experimental - brief: > - The amount of memory available to the serverless function converted to Bytes. - note: > - It's recommended to set this attribute since e.g. too little memory can easily - stop a Java AWS Lambda function from working correctly. - On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` - provides this information (which must be multiplied by 1,048,576). - examples: 134217728 + - ref: faas.version + - ref: faas.instance + - ref: faas.max_memory - ref: cloud.resource_id diff --git a/model/trace/faas.yaml b/model/trace/faas.yaml index 3eb9b53354..58dba9d979 100644 --- a/model/trace/faas.yaml +++ b/model/trace/faas.yaml @@ -18,11 +18,7 @@ groups: trigger that corresponding incoming would have (i.e., this has nothing to do with the underlying transport used to make the API call to invoke the lambda, which is often HTTP). - - id: invocation_id - type: string - stability: experimental - brief: 'The invocation ID of the current function invocation.' - examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' + - ref: faas.invocation_id - ref: cloud.resource_id - id: faas_span.datasource @@ -32,47 +28,12 @@ groups: Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write. attributes: - - id: collection - type: string - stability: experimental + - ref: faas.document.collection requirement_level: required - brief: > - The name of the source on which the triggering operation was performed. - For example, in Cloud Storage or S3 corresponds to the bucket name, - and in Cosmos DB to the database name. - examples: ['myBucketName', 'myDbName'] - - id: operation - stability: experimental + - ref: faas.document.operation requirement_level: required - type: - allow_custom_values: true - members: - - id: insert - value: 'insert' - brief: 'When a new object is created.' - - id: edit - value: 'edit' - brief: 'When an object is modified.' - - id: delete - value: 'delete' - brief: 'When an object is deleted.' - brief: 'Describes the type of the operation that was performed on the data.' - - id: time - type: string - stability: experimental - brief: > - A string containing the time when the data was accessed in the - [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) - format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). - examples: "2020-01-23T13:47:06Z" - - id: name - type: string - stability: experimental - brief: > - The document name/table subjected to the operation. - For example, in Cloud Storage or S3 is the name of - the file, and in Cosmos DB the table name. - examples: ["myFile.txt", "myTableName"] + - ref: faas.document.time + - ref: faas.document.name - id: faas_span.http type: span @@ -96,21 +57,8 @@ groups: brief: > Semantic Convention for FaaS scheduled to be executed regularly. attributes: - - id: time - type: string - stability: experimental - brief: > - A string containing the function invocation time in the - [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) - format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). - examples: "2020-01-23T13:47:06Z" - - id: cron - type: string - stability: experimental - brief: > - A string containing the schedule period as - [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). - examples: "0/5 * * * ? *" + - ref: faas.time + - ref: faas.cron - id: faas_span.in span_kind: server @@ -119,12 +67,7 @@ groups: brief: > Contains additional attributes for incoming FaaS spans. attributes: - - id: coldstart - type: boolean - stability: experimental - brief: > - A boolean that is true if the serverless function is executed for the - first time (aka cold-start). + - ref: faas.coldstart - ref: faas.trigger requirement_level: required note: | @@ -146,5 +89,16 @@ groups: Contains additional attributes for outgoing FaaS spans. attributes: - ref: faas.invoked_name + requirement_level: required - ref: faas.invoked_provider + requirement_level: required - ref: faas.invoked_region + requirement_level: + conditionally_required: > + For some cloud providers, like AWS or GCP, the region in which a + function is hosted is essential to uniquely identify the function + and also part of its endpoint. Since it's part of the endpoint + being called, the region is always known to clients. In these cases, + `faas.invoked_region` MUST be set accordingly. If the region is + unknown to the client or not required for identifying the invoked + function, setting `faas.invoked_region` is optional. From a3252cb6058a428f0616b6e649765cd4d04f8578 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:29:44 +0100 Subject: [PATCH 377/482] Clarify metric attributes should be namespaced (#786) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> Co-authored-by: Chris Mark Co-authored-by: Liudmila Molkova --- .chloggen/clarify-metric-namespace.yaml | 5 +++++ docs/general/metrics.md | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100755 .chloggen/clarify-metric-namespace.yaml diff --git a/.chloggen/clarify-metric-namespace.yaml b/.chloggen/clarify-metric-namespace.yaml new file mode 100755 index 0000000000..7fffee1683 --- /dev/null +++ b/.chloggen/clarify-metric-namespace.yaml @@ -0,0 +1,5 @@ +change_type: 'enhancement' +component: metrics +note: Clarify metric attributes should be namespaced. +issues: [394] +subtext: diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 2f235e23ce..d76440f253 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -11,6 +11,7 @@ aliases: [docs/specs/semconv/general/metrics-general] - [General Guidelines](#general-guidelines) - [Name Reuse Prohibition](#name-reuse-prohibition) + - [Metric attributes](#metric-attributes) - [Units](#units) - [Naming rules for Counters and UpDownCounters](#naming-rules-for-counters-and-updowncounters) - [Pluralization](#pluralization) @@ -89,6 +90,26 @@ When introducing a new metric name check all existing schema files to make sure the name does not appear as a key of any "rename_metrics" section (keys denote old metric names in rename operations). +### Metric attributes + +Metric attributes SHOULD follow the general [attribute naming rules](attribute-naming.md). +In particular, metric attributes SHOULD have a namespace. + +Metric attributes SHOULD be added under the metric namespace when their usage and +semantics are exclusive to the metric. + +Examples: + +Attributes `mode` and `mountpoint` for metric `system.filesystem.usage` +should be namespaced as `system.filesystem.mode` and `system.filesystem.mountpoint`. + +Metrics can also have attributes outside of their namespace. + +Examples: + +Metric `http.server.request.duration` uses attributes from the registry such as +`server.port`, `error.type`. + ### Units Conventional metrics or metrics that have their units included in From c8b61636277c9577a8e1948f1df70b4da8716d2d Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 8 Mar 2024 08:41:04 -0800 Subject: [PATCH 378/482] Deprecate `db.jdbc.driver_classname` attribute since it's not used (#796) --- .chloggen/796.yaml | 4 ++++ docs/attributes-registry/db.md | 10 +--------- docs/database/mssql.md | 1 - docs/database/sql.md | 1 - model/registry/db.yaml | 7 ------- model/registry/deprecated/db.yaml | 7 ++++++- model/trace/database.yaml | 2 -- 7 files changed, 11 insertions(+), 21 deletions(-) create mode 100644 .chloggen/796.yaml diff --git a/.chloggen/796.yaml b/.chloggen/796.yaml new file mode 100644 index 0000000000..725dc48513 --- /dev/null +++ b/.chloggen/796.yaml @@ -0,0 +1,4 @@ +change_type: deprecation +component: db +note: Deprecate `db.jdbc.driver_classname` attribute +issues: [796] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 5441b91de9..be7f5753d0 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -9,7 +9,6 @@ - [Cassandra Attributes](#cassandra-attributes) - [CosmosDB Attributes](#cosmosdb-attributes) - [Elasticsearch Attributes](#elasticsearch-attributes) -- [JDBC Attributes](#jdbc-attributes) - [MongoDB Attributes](#mongodb-attributes) - [MSSQL Attributes](#mssql-attributes) - [Redis Attributes](#redis-attributes) @@ -178,14 +177,6 @@ **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -## JDBC Attributes - - -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.jdbc.driver_classname` | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | - - ## MongoDB Attributes @@ -228,4 +219,5 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | +| `db.jdbc.driver_classname` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | \ No newline at end of file diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 6eeaf08030..e0ad3c6727 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,7 +17,6 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.jdbc.driver_classname`](../attributes-registry/db.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | | [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | | [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [2] | `public.users`; `customers` | Recommended | diff --git a/docs/database/sql.md b/docs/database/sql.md index d60e3e158e..17b8dcc892 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,7 +15,6 @@ described on this page. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`db.jdbc.driver_classname`](../attributes-registry/db.md) | string | The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | Recommended | | [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | Recommended | **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/model/registry/db.yaml b/model/registry/db.yaml index a94eef9471..4185c279ab 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -192,13 +192,6 @@ groups: in order to map the path part values to their names. examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] tag: tech-specific-elasticsearch - - id: jdbc.driver_classname - type: string - stability: experimental - brief: > - The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. - examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - tag: tech-specific-jdbc - id: mongodb.collection type: string stability: experimental diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index a3718cf6bc..1dd6996704 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -9,5 +9,10 @@ groups: type: string brief: 'Deprecated, use `server.address`, `server.port` attributes instead.' deprecated: > - "Removed in favor of `server.address` and `server.port`." + "Replaced by `server.address` and `server.port`." examples: Server=(localdb)\v11.0;Integrated Security=true; + - id: jdbc.driver_classname + type: string + brief: 'Removed, no replacement at this time.' + deprecated: 'Removed as not used.' + examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 74ea98ceb2..5d7d4fc269 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -183,8 +183,6 @@ groups: attributes: - ref: db.sql.table tag: tech-specific - - ref: db.jdbc.driver_classname - tag: tech-specific - id: db.cosmosdb type: span From 3edef610fc777ea238ecb0e13ee610c681278e34 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Mon, 11 Mar 2024 16:23:23 +0100 Subject: [PATCH 379/482] Align `system.cpu.state`'s definition with this of `process.cpu.state` (#765) --- .chloggen/add_cpu_state_constraint.yaml | 22 ++++++++++++++++++++++ docs/system/system-metrics.md | 4 ++-- model/metrics/system-metrics.yaml | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100755 .chloggen/add_cpu_state_constraint.yaml diff --git a/.chloggen/add_cpu_state_constraint.yaml b/.chloggen/add_cpu_state_constraint.yaml new file mode 100755 index 0000000000..87edf707f1 --- /dev/null +++ b/.chloggen/add_cpu_state_constraint.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'enhancement' + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: 'system' + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Align `system.cpu.state`'s definition with this of `process.cpu.state`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [563] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 38be351b98..ebb3bf3c3a 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -87,7 +87,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | -| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | Recommended | +| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | Recommended | `system.cpu.state` 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. @@ -116,7 +116,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | -| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | Recommended | +| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | Recommended | `system.cpu.state` 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. diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 49a3a765b4..2424b1aa41 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -35,8 +35,8 @@ groups: value: 'interrupt' - id: steal value: 'steal' + brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." stability: experimental - brief: "The state of the CPU" examples: ["idle", "interrupt"] - id: logical_number type: int From ac0c577d20c894113eba23a344da7371cfb95a58 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Mon, 11 Mar 2024 16:58:33 +0100 Subject: [PATCH 380/482] [chore] Fix double `the` typos (#806) Co-authored-by: Reiley Yang --- docs/attributes-registry/url.md | 4 ++-- docs/database/dynamodb.md | 4 ++-- model/registry/url.yaml | 2 +- model/trace/instrumentation/aws-sdk.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index d2aa233eeb..630c8fc639 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -19,7 +19,7 @@ linkTitle: URL | `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | | `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | | `url.scheme` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | -| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | +| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | | `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | **[1]:** In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. @@ -42,4 +42,4 @@ linkTitle: URL **[8]:** The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. **[9]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). - \ No newline at end of file + diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 137ebc6f37..932f5e5fc0 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -99,7 +99,7 @@ These attributes are filled in for all DynamoDB request types. |---|---|---|---|---| | `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | Recommended | | `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | -| `aws.dynamodb.table_count` | int | The the number of items in the `TableNames` response parameter. | `20` | Recommended | +| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | Recommended | ## DynamoDB.PutItem @@ -164,7 +164,7 @@ These attributes are filled in for all DynamoDB request types. |---|---|---|---|---| | `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | Recommended | | `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | +| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | | `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | | `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | diff --git a/model/registry/url.yaml b/model/registry/url.yaml index 624ad90ba3..e0bd823f1c 100644 --- a/model/registry/url.yaml +++ b/model/registry/url.yaml @@ -99,7 +99,7 @@ groups: stability: experimental brief: > The subdomain portion of a fully qualified domain name includes all of the names except the host name - under the registered_domain. In a partially qualified domain, or if the the qualification level of the + under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. examples: ["east", "sub2.sub1"] note: > diff --git a/model/trace/instrumentation/aws-sdk.yml b/model/trace/instrumentation/aws-sdk.yml index 552914670a..1817c66281 100644 --- a/model/trace/instrumentation/aws-sdk.yml +++ b/model/trace/instrumentation/aws-sdk.yml @@ -317,7 +317,7 @@ groups: - id: table_count type: int stability: experimental - brief: "The the number of items in the `TableNames` response parameter." + brief: "The number of items in the `TableNames` response parameter." examples: - 20 - ref: aws.dynamodb.limit @@ -427,7 +427,7 @@ groups: - id: global_secondary_index_updates type: string[] stability: experimental - brief: "The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field." + brief: "The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field." examples: - '{ "Create": { From 1f4dfa34561820e79fe8aba7ddbc45d21069898c Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:09:12 +0100 Subject: [PATCH 381/482] [chore] Pin markdown-link-check version (#808) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90d26767c2..dd8bc20cb2 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "devDependencies": { "gulp": "^4.0.2", "js-yaml": "^4.1.0", - "markdown-link-check": "^3.11.2", + "markdown-link-check": "3.11.2", "markdown-toc": "^1.2.0", "markdownlint": "^0.29.0", "markdownlint-cli": "0.31.0", From e24b332c18e24294e23c4575740dd6e7abf2ce98 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 12 Mar 2024 10:19:40 -0700 Subject: [PATCH 382/482] Two fixes to the HTTP semconv migration guide (#804) Co-authored-by: Liudmila Molkova --- .chloggen/804.yaml | 22 ++++++++++++++++++++++ docs/http/migration-guide.md | 4 +++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .chloggen/804.yaml diff --git a/.chloggen/804.yaml b/.chloggen/804.yaml new file mode 100644 index 0000000000..81b0ce5a1d --- /dev/null +++ b/.chloggen/804.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: http + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Two fixes to the HTTP semconv migration guide + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [ 802 ] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/http/migration-guide.md b/docs/http/migration-guide.md index 16336c73b3..65fea1a3fe 100644 --- a/docs/http/migration-guide.md +++ b/docs/http/migration-guide.md @@ -85,7 +85,9 @@ References: | `http.scheme` → `url.scheme` | Now factors in [X-Forwarded-Proto][], [Forwarded#proto][] headers | | `http.client_ip` → `client.address` | If `http.client_ip` was unknown (i.e., no [X-Forwarded-For][], [Forwarded#for][] headers), then `net.sock.peer.addr` → `client.address`; now must be provided to sampler | | `net.host.name` → `server.address` | Now based only on [Host][Host header], [:authority][HTTP/2 authority], [X-Forwarded-Host][], [Forwarded#host][] headers | -| `net.host.port` → `server.port` | Now based only on [Host][Host header], [:authority][HTTP/2 authority], [X-Forwarded-Host][X-Forwarded-Host], [Forwarded#host][] headers | +| `net.host.port` → `server.port` | • Now based only on [Host][Host header], [:authority][HTTP/2 authority], [X-Forwarded-Host][X-Forwarded-Host], [Forwarded#host][] headers
• Now captured even when same as default port for scheme | +| `net.sock.host.addr` → `network.local.address` | | +| `net.sock.host.port` → `network.local.port` | No longer defaults to `server.port` when `network.local.address` is set. | References: From e74c9982f03c56b5a3be8d6b9c38aa52bd6005e9 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 13 Mar 2024 03:42:47 -0700 Subject: [PATCH 383/482] Introduce common `messaging.destination.partition.id` instead of per-system ones (#798) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/798.yaml | 4 ++++ docs/attributes-registry/messaging.md | 12 ++++++++++-- docs/messaging/azure-messaging.md | 2 +- docs/messaging/kafka.md | 2 +- model/registry/deprecated/messaging.yaml | 11 +++++++++++ model/registry/messaging.yaml | 23 ++++++++--------------- model/trace/messaging.yaml | 12 ++++++++---- schema-next.yaml | 6 ++++++ 8 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 .chloggen/798.yaml create mode 100644 model/registry/deprecated/messaging.yaml diff --git a/.chloggen/798.yaml b/.chloggen/798.yaml new file mode 100644 index 0000000000..95e89a8b1f --- /dev/null +++ b/.chloggen/798.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: messaging +note: Introduce common `messaging.destination.partition.id` instead of `messaging.kafka.destination.partition` +issues: [798] diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 4d349029b7..7e3491b8d3 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -12,6 +12,7 @@ - [RocketMQ Attributes](#rocketmq-attributes) - [Azure Event Hubs Attributes](#azure-event-hubs-attributes) - [Azure Service Bus Attributes](#azure-service-bus-attributes) +- [Deprecated Messaging Attributes](#deprecated-messaging-attributes) @@ -24,6 +25,7 @@ | `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | | `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | | `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | +| `messaging.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | | `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | | `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | | `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | @@ -93,7 +95,6 @@ size should be used. | Attribute | Type | Description | Examples | |---|---|---|---| | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | -| `messaging.kafka.destination.partition` | int | Partition the message is sent to. | `2` | | `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | | `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | | `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | @@ -148,7 +149,6 @@ size should be used. | Attribute | Type | Description | Examples | |---|---|---|---| | `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | -| `messaging.eventhubs.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. | `1` | | `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | @@ -171,3 +171,11 @@ size should be used. | `dead_letter` | Message is sent to dead letter queue | | `defer` | Message is deferred | + +## Deprecated Messaging Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `messaging.kafka.destination.partition` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Deprecated, use `messaging.destination.partition.id` instead." | `2` | + \ No newline at end of file diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index e7317d7b3a..e9b49cc5cf 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -54,8 +54,8 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id messages are sent to or received from, unique within the Event Hub." | `1` | Conditionally Required: If available. | | [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | Conditionally Required: If not default ("$Default"). | -| [`messaging.eventhubs.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. | `1` | Conditionally Required: If available. | | [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 47deec0d23..4f6866ed83 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -27,8 +27,8 @@ For Apache Kafka, the following additional attributes are defined: | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id the message (or batch) is sent to or received from."" | `1` | Recommended | | [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | Recommended | -| [`messaging.kafka.destination.partition`](../attributes-registry/messaging.md) | int | Partition the message is sent to. | `2` | Recommended | | [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | | [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | Recommended | | [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | Conditionally Required: [2] | diff --git a/model/registry/deprecated/messaging.yaml b/model/registry/deprecated/messaging.yaml new file mode 100644 index 0000000000..015f428818 --- /dev/null +++ b/model/registry/deprecated/messaging.yaml @@ -0,0 +1,11 @@ +groups: + - id: attributes.messaging.deprecated + type: attribute_group + brief: "Describes deprecated messaging attributes." + attributes: + - id: messaging.kafka.destination.partition + type: int + brief: > + "Deprecated, use `messaging.destination.partition.id` instead." + examples: 2 + deprecated: "Replaced by `messaging.destination.partition.id`." diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 4afd4d5320..5e6846abd7 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -66,6 +66,13 @@ groups: the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] tag: messaging-generic + - id: destination.partition.id + type: string + stability: experimental + brief: > + The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. + examples: '1' + tag: messaging-generic - id: kafka.consumer.group type: string stability: experimental @@ -74,13 +81,6 @@ groups: Only applies to consumers, not producers. examples: 'my-group' tag: tech-specific-kafka - - id: kafka.destination.partition - type: int - stability: experimental - brief: > - Partition the message is sent to. - examples: 2 - tag: tech-specific-kafka - id: kafka.message.key type: string stability: experimental @@ -273,7 +273,7 @@ groups: type: string stability: experimental brief: > - The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. + The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' tag: tech-specific-gcp-pubsub - id: system @@ -362,13 +362,6 @@ groups: The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 tag: tech-specific-eventhubs - - id: eventhubs.destination.partition.id - type: string - stability: experimental - brief: > - The identifier of the partition messages are sent to or received from, unique to the Event Hub which contains it. - examples: '1' - tag: tech-specific-eventhubs - id: eventhubs.consumer.group type: string stability: experimental diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 3a8543d540..362eaab9f4 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -109,12 +109,14 @@ groups: brief: > Attributes for Apache Kafka attributes: + - ref: messaging.destination.partition.id + brief: > + "String representation of the partition id the message (or batch) is sent to or received from."" + tag: tech-specific-kafka - ref: messaging.kafka.message.key tag: tech-specific-kafka - ref: messaging.kafka.consumer.group tag: tech-specific-kafka - - ref: messaging.kafka.destination.partition - tag: tech-specific-kafka - ref: messaging.kafka.message.offset tag: tech-specific-kafka - ref: messaging.kafka.message.tombstone @@ -186,10 +188,12 @@ groups: brief: > Attributes for Azure Event Hubs attributes: - - ref: messaging.eventhubs.message.enqueued_time - - ref: messaging.eventhubs.destination.partition.id + - ref: messaging.destination.partition.id + brief: > + "String representation of the partition id messages are sent to or received from, unique within the Event Hub." requirement_level: conditionally_required: If available. + - ref: messaging.eventhubs.message.enqueued_time - ref: messaging.eventhubs.consumer.group requirement_level: conditionally_required: If not default ("$Default"). diff --git a/schema-next.yaml b/schema-next.yaml index 441f34e983..b6e3a405d9 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,12 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/798 + - rename_attributes: + attribute_map: + messaging.kafka.destination.partition: messaging.destination.partition.id metrics: changes: # https://github.com/open-telemetry/semantic-conventions/pull/484 From cfff890ccd9cf6d75b9010896302791b0e7affc8 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:12:31 +0100 Subject: [PATCH 384/482] Move HTTP client metrics out of .NET conventions (#801) --- .../move-dotnet-metrics-experimental.yaml | 4 + docs/attributes-registry/http.md | 8 ++ docs/dotnet/dotnet-http-metrics.md | 20 +-- docs/http/http-metrics.md | 126 ++++++++++++++++++ model/metrics/dotnet/dotnet-http.yaml | 111 --------------- model/metrics/http.yaml | 66 +++++++++ model/registry/http.yaml | 13 ++ 7 files changed, 221 insertions(+), 127 deletions(-) create mode 100755 .chloggen/move-dotnet-metrics-experimental.yaml delete mode 100644 model/metrics/dotnet/dotnet-http.yaml diff --git a/.chloggen/move-dotnet-metrics-experimental.yaml b/.chloggen/move-dotnet-metrics-experimental.yaml new file mode 100755 index 0000000000..f2812b3aa1 --- /dev/null +++ b/.chloggen/move-dotnet-metrics-experimental.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: http +note: Extracts common HTTP client metrics from .NET conventions. +issues: [800] diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 8b7665bb9c..9363bed226 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -8,6 +8,7 @@ | Attribute | Type | Description | Examples | |---|---|---|---| +| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | | `http.request.body.size` | 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` | | `http.request.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | | `http.request.method` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request method. [2] | `GET`; `POST`; `HEAD` | @@ -46,6 +47,13 @@ The attribute value MUST consist of either multiple header values as an array of **[5]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. +`http.connection.state` 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 | +|---|---| +| `active` | active state. | +| `idle` | idle state. | + `http.request.method` 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 | diff --git a/docs/dotnet/dotnet-http-metrics.md b/docs/dotnet/dotnet-http-metrics.md index 47bf1a71b7..e4e4f7c28c 100644 --- a/docs/dotnet/dotnet-http-metrics.md +++ b/docs/dotnet/dotnet-http-metrics.md @@ -43,15 +43,13 @@ Notes: ### Metric: `http.client.open_connections` - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | | `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client. [1] | **[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 - - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | @@ -75,7 +73,6 @@ Notes: |---|---| | `active` | active state. | | `idle` | idle state. | - ### Metric: `http.client.connection.duration` @@ -83,15 +80,13 @@ this metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | | `http.client.connection.duration` | Histogram | `s` | The duration of the successfully established outbound HTTP connections. [1] | **[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 - - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -107,7 +102,6 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. **[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. **[4]:** If not the default (`80` for `http` scheme, `443` for `https`). - ### Metric: `http.client.request.time_in_queue` @@ -115,15 +109,13 @@ this metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | | `http.client.request.time_in_queue` | Histogram | `s` | The amount of time requests spent on a queue waiting for an available connection. [1] | **[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 - - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | @@ -157,19 +149,16 @@ If the HTTP request method isn't known, it sets the `http.request.method` attrib | `PUT` | PUT method. | | `TRACE` | TRACE method. | | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | - ### Metric: `http.client.active_requests` - + | Name | Instrument Type | Unit (UCUM) | Description | | -------- | --------------- | ----------- | -------------- | | `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. [1] | **[1]:** Meter name: `System.Net.Http`; Added in: .NET 8.0 - - | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | @@ -200,7 +189,6 @@ If the HTTP request method isn't known, it sets the `http.request.method` attrib | `PUT` | PUT method. | | `TRACE` | TRACE method. | | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | - ## HTTP server diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index aed8fc81dc..dd429a32fb 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -23,6 +23,9 @@ operations. By adding HTTP attributes to metric events it allows for finely tune - [Metric: `http.client.request.duration`](#metric-httpclientrequestduration) - [Metric: `http.client.request.body.size`](#metric-httpclientrequestbodysize) - [Metric: `http.client.response.body.size`](#metric-httpclientresponsebodysize) + - [Metric: `http.client.open_connections`](#metric-httpclientopen_connections) + - [Metric: `http.client.connection.duration`](#metric-httpclientconnectionduration) + - [Metric: `http.client.active_requests`](#metric-httpclientactive_requests) @@ -701,4 +704,127 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +### Metric: `http.client.open_connections` + +**Status**: [Experimental][DocumentStatus] + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`http.connection.state`](../attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [1] | `3.1.1` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | + +**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`http.connection.state` 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 | +|---|---| +| `active` | active state. | +| `idle` | idle state. | + + +### Metric: `http.client.connection.duration` + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + +**Status**: [Experimental][DocumentStatus] + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.connection.duration` | Histogram | `s` | The duration of the successfully established outbound HTTP connections. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [1] | `3.1.1` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | + +**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + + +### Metric: `http.client.active_requests` + +**Status**: [Experimental][DocumentStatus] + +This metric is optional. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. | + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | +| [`server.port`](../attributes-registry/server.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` | Required | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | + +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`http.request.method` 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 | +|---|---| +| `CONNECT` | CONNECT method. | +| `DELETE` | DELETE method. | +| `GET` | GET method. | +| `HEAD` | HEAD method. | +| `OPTIONS` | OPTIONS method. | +| `PATCH` | PATCH method. | +| `POST` | POST method. | +| `PUT` | PUT method. | +| `TRACE` | TRACE method. | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | + + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/metrics/dotnet/dotnet-http.yaml b/model/metrics/dotnet/dotnet-http.yaml deleted file mode 100644 index 6b3723ddb8..0000000000 --- a/model/metrics/dotnet/dotnet-http.yaml +++ /dev/null @@ -1,111 +0,0 @@ -groups: - - id: dotnet.http.client.common.attributes - type: attribute_group - brief: "Common HTTP client attributes" - attributes: - - ref: url.scheme - examples: ['http', 'https', 'ftp'] - - ref: server.address - 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: > - If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then - `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - - ref: server.port - requirement_level: - conditionally_required: If not the 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. - - - id: dotnet.http.client.connection.attributes - type: attribute_group - brief: "Common HTTP client attributes" - extends: dotnet.http.client.common.attributes - attributes: - - ref: network.protocol.version - brief: HTTP protocol version of the connection in the connection pool. - note: > - HTTP 1.0 and 1.1 requests share connections in the connection pool and are both reported as version `1.1`. - So, the `network.protocol.version` value reported on connection metrics is different than the one reported - on request-level metrics or spans for HTTP 1.0 requests. - examples: ["1.1", "2", "3"] - - - id: dotnet.http.client.request.attributes - type: attribute_group - brief: "Common HTTP client attributes" - extends: dotnet.http.client.common.attributes - attributes: - - ref: http.request.method - note: > - HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) - and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - - If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. - It's not possible at the moment to override the list of known HTTP methods. - - - id: metric.dotnet.http.client.open_connections - type: metric - metric_name: http.client.open_connections - brief: "Number of outbound HTTP connections that are currently active or idle on the client." - instrument: updowncounter - unit: "{connection}" - note: > - Meter name: `System.Net.Http`; Added in: .NET 8.0 - extends: dotnet.http.client.connection.attributes - attributes: - - id: http.connection.state - type: - members: - - id: active - value: "active" - brief: 'active state.' - - id: idle - value: "idle" - brief: 'idle state.' - brief: State of the HTTP connection in the HTTP connection pool. - requirement_level: required - examples: ["active", "idle"] - - ref: network.peer.address - brief: Remote IP address of the socket connection. - examples: ["10.1.2.80"] - - - id: metric.dotnet.http.client.connection.duration - type: metric - metric_name: http.client.connection.duration - brief: "The duration of the successfully established outbound HTTP connections." - instrument: histogram - unit: "s" - note: > - Meter name: `System.Net.Http`; Added in: .NET 8.0 - extends: dotnet.http.client.connection.attributes - attributes: - - ref: network.peer.address - - - id: metric.dotnet.http.client.active_requests - type: metric - metric_name: http.client.active_requests - brief: "Number of active HTTP requests." - instrument: updowncounter - unit: "{request}" - note: > - Meter name: `System.Net.Http`; Added in: .NET 8.0 - extends: dotnet.http.client.request.attributes - - - id: metric.dotnet.http.client.request.time_in_queue - type: metric - metric_name: http.client.request.time_in_queue - brief: "The amount of time requests spent on a queue waiting for an available connection." - instrument: histogram - unit: "s" - note: > - Meter name: `System.Net.Http`; Added in: .NET 8.0 - extends: dotnet.http.client.connection.attributes - attributes: - - ref: http.request.method - note: > - HTTP request method value is one of the "known" methods listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) - and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - - If the HTTP request method isn't known, it sets the `http.request.method` attribute to `_OTHER`. - It's not possible at the moment to override the list of known HTTP methods. diff --git a/model/metrics/http.yaml b/model/metrics/http.yaml index d22e7836b8..ba1ca5a522 100644 --- a/model/metrics/http.yaml +++ b/model/metrics/http.yaml @@ -124,3 +124,69 @@ 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. extends: metric_attributes.http.client + + - id: metric.http.client.open_connections + type: metric + metric_name: http.client.open_connections + stability: experimental + brief: "Number of outbound HTTP connections that are currently active or idle on the client." + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: http.connection.state + requirement_level: required + - ref: network.peer.address + requirement_level: recommended + - ref: network.protocol.version + requirement_level: recommended + - ref: server.address + requirement_level: required + - ref: server.port + requirement_level: required + brief: > + Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + - ref: url.scheme + requirement_level: opt_in + examples: ["http", "https"] + + - id: metric.http.client.connection.duration + type: metric + metric_name: http.client.connection.duration + stability: experimental + brief: "The duration of the successfully established outbound HTTP connections." + instrument: histogram + unit: "s" + attributes: + - ref: network.peer.address + requirement_level: recommended + - ref: network.protocol.version + requirement_level: recommended + - ref: server.address + requirement_level: required + - ref: server.port + requirement_level: required + brief: > + Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + - ref: url.scheme + requirement_level: opt_in + examples: ["http", "https"] + + - id: metric.http.client.active_requests + type: metric + metric_name: http.client.active_requests + stability: experimental + brief: "Number of active HTTP requests." + instrument: updowncounter + unit: "{request}" + attributes: + - ref: http.request.method + requirement_level: recommended + - ref: server.address + requirement_level: required + - ref: server.port + requirement_level: required + brief: > + Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + - ref: url.scheme + requirement_level: opt_in + examples: ["http", "https"] diff --git a/model/registry/http.yaml b/model/registry/http.yaml index 2cb8e8b894..a4d4839eba 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -133,3 +133,16 @@ groups: 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](/docs/http/http-spans.md#http-server-definitions) if there is one. + - id: connection.state + type: + allow_custom_values: true + members: + - id: active + value: "active" + brief: 'active state.' + - id: idle + value: "idle" + brief: 'idle state.' + brief: State of the HTTP connection in the HTTP connection pool. + stability: experimental + examples: ["active", "idle"] From f9dfdd50ce886dc6246e9b745406640ed37d30c1 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 18 Mar 2024 03:37:59 -0700 Subject: [PATCH 385/482] Database: clarify network attributes usage on common semconv (#768) --- .chloggen/768.yaml | 7 ++++ docs/database/cassandra.md | 4 +++ docs/database/database-spans.md | 41 +++++----------------- docs/database/elasticsearch.md | 18 ++++++---- docs/database/redis.md | 4 +++ model/trace/database.yaml | 60 +++++++++++++++++++++++---------- 6 files changed, 77 insertions(+), 57 deletions(-) create mode 100644 .chloggen/768.yaml diff --git a/.chloggen/768.yaml b/.chloggen/768.yaml new file mode 100644 index 0000000000..7cceacd08b --- /dev/null +++ b/.chloggen/768.yaml @@ -0,0 +1,7 @@ +change_type: breaking + +component: db + +note: Remove `network.transport` and `network.type` attributes from database semantic conventions, clarify when `network.peer.address|port` should be populated. + +issues: [690, 768] diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 6193ee0d21..6e83dd1a69 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -25,11 +25,15 @@ described on this page. | [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | Recommended | | [`db.cassandra.table`](../attributes-registry/db.md) | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | | [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [2] | `mykeyspace` | Conditionally Required: If applicable. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | **[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. **[2]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. +**[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + `db.cassandra.consistency_level` MUST be one of the following: | Value | Description | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 6324709e0c..a37429f009 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -79,12 +79,10 @@ Some database systems may allow a connection to switch to a different `db.user`, | [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | | [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Conditionally Required: [8] | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | Recommended: If applicable for this database system. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). @@ -92,19 +90,14 @@ Some database systems may allow a connection to switch to a different `db.user`, **[3]:** Should be collected by default only if there is sanitization that excludes sensitive information. -**[4]:** The value SHOULD be normalized to lowercase. +**[4]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[5]:** The value SHOULD be normalized to lowercase. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. - -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. - -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. `db.system` 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. @@ -162,22 +155,6 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `clickhouse` | ClickHouse | | `spanner` | Cloud Spanner | | `trino` | Trino | - -`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | - -`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | ### Notes and well-known identifiers for `db.system` diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index e7bd336158..4603978dda 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -32,9 +32,11 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [8] | `80`; `8080`; `443` | Conditionally Required: [9] | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [10] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [7] | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | Conditionally Required: [10] | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [11] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. @@ -61,13 +63,15 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[7]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[8]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[9]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[10]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +**[10]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[11]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. diff --git a/docs/database/redis.md b/docs/database/redis.md index 838d50822e..895a293895 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -19,10 +19,14 @@ described on this page. |---|---|---|---|---| | [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | Conditionally Required: If other than the default database (`0`). | | [`db.statement`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | Recommended: [2] | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | **[1]:** For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. **[2]:** Should be collected by default only if there is sanitization that excludes sensitive information. + +**[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. ## Example diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 5d7d4fc269..e824438bf9 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -1,9 +1,7 @@ groups: - - id: db - type: span - brief: > - This document defines the attributes used to perform database client calls. - span_kind: client + - id: db.common.attributes + type: attribute_group + brief: This group defines the attributes used to perform database client calls. attributes: - ref: db.system requirement_level: required @@ -24,15 +22,41 @@ groups: - ref: server.port requirement_level: conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. + - ref: db.instance.id + requirement_level: + recommended: If different from the `server.address` - ref: network.peer.address + brief: Peer address of the database node where the operation was performed. + requirement_level: + recommended: If applicable for this database system. + note: > + Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. + Network peer address and port are useful when the application interacts with individual database nodes directly. + + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - ref: network.peer.port requirement_level: - recommended: If `network.peer.address` is set. - - ref: network.transport - - ref: network.type - - ref: db.instance.id + recommended: if and only if `network.peer.address` is set. + + - id: db.tech_specific.network.attributes + type: attribute_group + brief: This group documents attributes that describe database call along with network information. + extends: db.common.attributes + attributes: + - ref: network.peer.address requirement_level: - recommended: If different from the `server.address` + recommended + note: > + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + tag: tech-specific + - ref: network.peer.port + tag: tech-specific + + - id: db + type: span + brief: This span defines the attributes used to perform database client calls. + span_kind: client + extends: db.common.attributes - id: db.mssql type: span @@ -45,7 +69,7 @@ groups: - id: db.cassandra type: span - extends: db + extends: db.tech_specific.network.attributes brief: > Attributes for Cassandra attributes: @@ -72,7 +96,7 @@ groups: - id: db.hbase type: span - extends: db + extends: db.common.attributes brief: > Attributes for HBase attributes: @@ -85,7 +109,7 @@ groups: - id: db.couchdb type: span - extends: db + extends: db.common.attributes brief: > Attributes for CouchDB attributes: @@ -103,7 +127,7 @@ groups: - id: db.redis type: span - extends: db + extends: db.tech_specific.network.attributes brief: > Attributes for Redis attributes: @@ -122,7 +146,7 @@ groups: - id: db.mongodb type: span - extends: db + extends: db.common.attributes brief: > Attributes for MongoDB attributes: @@ -132,7 +156,7 @@ groups: - id: db.elasticsearch type: span - extends: db + extends: db.tech_specific.network.attributes brief: > Attributes for Elasticsearch attributes: @@ -177,7 +201,7 @@ groups: - id: db.sql type: span - extends: 'db' + extends: db.common.attributes brief: > Attributes for SQL databases attributes: @@ -186,7 +210,7 @@ groups: - id: db.cosmosdb type: span - extends: db + extends: db.common.attributes prefix: db.cosmosdb brief: > Attributes for Cosmos DB. From 0220d78f63e088a50fe8e4f827b97a28a42aeb23 Mon Sep 17 00:00:00 2001 From: Kamal Marhubi Date: Mon, 18 Mar 2024 11:30:24 -0400 Subject: [PATCH 386/482] trace/http: Add http.{request,response}.size attributes (#84) Co-authored-by: Liudmila Molkova Co-authored-by: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/http-request-response-size.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/http.md | 2 ++ model/registry/http.yaml | 14 ++++++++++++++ 3 files changed, 38 insertions(+) create mode 100755 .chloggen/http-request-response-size.yaml diff --git a/.chloggen/http-request-response-size.yaml b/.chloggen/http-request-response-size.yaml new file mode 100755 index 0000000000..c823b94a91 --- /dev/null +++ b/.chloggen/http-request-response-size.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: http + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add `http.request.size` and `http.response.size` attributes for the total number of bytes in http messages + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [38, 84] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 9363bed226..31fb5b6355 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -14,8 +14,10 @@ | `http.request.method` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request method. [2] | `GET`; `POST`; `HEAD` | | `http.request.method_original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | | `http.request.resend_count` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | +| `http.request.size` | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | | `http.response.body.size` | 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` | | `http.response.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | +| `http.response.size` | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | | `http.response.status_code` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | | `http.route` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | diff --git a/model/registry/http.yaml b/model/registry/http.yaml index a4d4839eba..ee0ff93293 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -95,6 +95,13 @@ groups: was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). examples: 3 + - id: request.size + type: int + brief: > + The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), + framing (HTTP/2 and HTTP/3), headers, and request body if any. + examples: 1437 + stability: experimental - id: response.body.size type: int brief: > @@ -118,6 +125,13 @@ groups: or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. examples: ['http.response.header.content-type=["application/json"]', 'http.response.header.my-custom-header=["abc", "def"]'] + - id: response.size + type: int + brief: > + The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), + framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. + examples: 1437 + stability: experimental - id: response.status_code stability: stable type: int From 4f25eb5e5423edb065f3d24023b7f34617457b33 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:21:40 +0100 Subject: [PATCH 387/482] Add Issue templates and automation scripts (#777) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 77 +++++++++++++++++++ .github/ISSUE_TEMPLATE/change_proposal.yaml | 64 +++++++++++++++ .github/ISSUE_TEMPLATE/new-conventions.yaml | 73 ++++++++++++++++++ .github/workflows/checks.yml | 9 +++ .../generate-registry-area-labels.yml | 24 ++++++ .github/workflows/prepare-new-issue.yml | 22 ++++++ .../scripts/generate-registry-area-labels.sh | 34 ++++++++ .../workflows/scripts/get-registry-areas.sh | 16 ++++ .../workflows/scripts/prepare-new-issue.sh | 62 +++++++++++++++ .yamllint | 5 ++ Makefile | 6 ++ .../scripts/update-issue-template-areas.sh | 43 +++++++++++ 12 files changed, 435 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml create mode 100644 .github/ISSUE_TEMPLATE/change_proposal.yaml create mode 100644 .github/ISSUE_TEMPLATE/new-conventions.yaml create mode 100644 .github/workflows/generate-registry-area-labels.yml create mode 100644 .github/workflows/prepare-new-issue.yml create mode 100755 .github/workflows/scripts/generate-registry-area-labels.sh create mode 100755 .github/workflows/scripts/get-registry-areas.sh create mode 100755 .github/workflows/scripts/prepare-new-issue.sh create mode 100755 internal/tools/scripts/update-issue-template-areas.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000000..08dca47531 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,77 @@ +name: Bug report +description: Create a report to help us improve +labels: ["bug", "triage:needs-triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your bug as quickly as possible. + + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/semantic-conventions/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug) to see if an existing issue covers your bug. + - type: dropdown + id: area + attributes: + label: Area(s) + description: Which area(s) does your bug report concern? If none fits, please select `area:other` + multiple: true + options: + - area:other + # NOTE: The list below is autogenerated using `make generate-gh-issue-templates` + # DO NOT manually edit it. + # Start semconv area list + - area:android + - area:browser + - area:client + - area:cloud + - area:code + - area:container + - area:db + - area:destination + - area:device + - area:disk + - area:dns + - area:error + - area:exception + - area:faas + - area:host + - area:http + - area:k8s + - area:messaging + - area:network + - area:oci + - area:os + - area:process + - area:rpc + - area:server + - area:source + - area:thread + - area:tls + - area:url + - area:user-agent + # End semconv area list + - type: textarea + attributes: + label: What happened? + description: Please provide as much detail as you reasonably can. + value: | + ## Description + + ## Steps to Reproduce (if any) + + ## Expected Result + + ## Actual Result + validations: + required: true + + - type: input + attributes: + label: Semantic convention version + description: What version did you use? (e.g., `v1.24.0`, `1eb551b`, etc) + validations: + required: true + + - type: textarea + attributes: + label: Additional context + description: Any additional information you think may be relevant to this issue. diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml new file mode 100644 index 0000000000..edaa3a4a75 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -0,0 +1,64 @@ +name: Propose changes to existing conventions +description: Propose changes you'd like to be added to existing conventions +labels: ["enhancement", "triage:needs-triage"] +body: + - type: dropdown + id: area + attributes: + label: Area(s) + description: Which area(s) does your change request concern? + multiple: true + options: + # NOTE: The list below is autogenerated using `make generate-gh-issue-templates` + # DO NOT manually edit it. + # Start semconv area list + - area:android + - area:browser + - area:client + - area:cloud + - area:code + - area:container + - area:db + - area:destination + - area:device + - area:disk + - area:dns + - area:error + - area:exception + - area:faas + - area:host + - area:http + - area:k8s + - area:messaging + - area:network + - area:oci + - area:os + - area:process + - area:rpc + - area:server + - area:source + - area:thread + - area:tls + - area:url + - area:user-agent + # End semconv area list + - type: textarea + attributes: + label: Is your change request related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + validations: + required: true + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + - type: textarea + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml new file mode 100644 index 0000000000..8a72b6bff2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -0,0 +1,73 @@ +name: Propose new semantic conventions +description: Propose new conventions you'd like to be part of the OpenTelemetry project +labels: ["enhancement", "triage:needs-triage", "experts needed"] +body: + - type: markdown + attributes: + value: | + Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage the proposal as quickly as possible. + + Before filing the proposal, please be sure you have searched through [existing issues](https://github.com/open-telemetry/semantic-conventions/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aenhancement+label%3Aarea:new) to see if an existing issue covers your proposal. + + Additionally, make sure to read and follow the guidelines on [Project Proposal](https://github.com/open-telemetry/community/blob/main/project-management.md#project-management), in case the proposal is for a new set of conventions/working group. + - type: dropdown + id: area + attributes: + label: Area(s) + description: Which area(s) does your new conventions concern? If none fits, please select `area:new` + multiple: true + options: + - area:new + # NOTE: The list below is autogenerated using `make generate-gh-issue-templates` + # DO NOT manually edit it. + # Start semconv area list + - area:android + - area:browser + - area:client + - area:cloud + - area:code + - area:container + - area:db + - area:destination + - area:device + - area:disk + - area:dns + - area:error + - area:exception + - area:faas + - area:host + - area:http + - area:k8s + - area:messaging + - area:network + - area:oci + - area:os + - area:process + - area:rpc + - area:server + - area:source + - area:thread + - area:tls + - area:url + - area:user-agent + # End semconv area list + - type: textarea + attributes: + label: Is your change request related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + validations: + required: true + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + - type: textarea + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a387a9db22..dd48bff2ce 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -97,3 +97,12 @@ jobs: - uses: actions/checkout@v1 - name: verify schemas run: make schema-check + + areas-dropdown-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Components dropdown in issue templates + run: | + make generate-gh-issue-templates + git diff --exit-code '.github/ISSUE_TEMPLATE' || (echo 'Dropdowns in issue templates is out of date, please run "make generate-gh-issue-templates" and commit the changes in this PR.' && exit 1) diff --git a/.github/workflows/generate-registry-area-labels.yml b/.github/workflows/generate-registry-area-labels.yml new file mode 100644 index 0000000000..58f3b62b3a --- /dev/null +++ b/.github/workflows/generate-registry-area-labels.yml @@ -0,0 +1,24 @@ +name: 'Generate registry area labels' +on: + push: + branches: [main] + paths: + - model/registry/** + - ./.github/workflows/generate-registry-area-labels.yml + - ./.github/workflows/scripts/generate-registry-area-labels.sh + workflow_dispatch: + +jobs: + generate-component-labels: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'open-telemetry' }} + steps: + - uses: actions/checkout@v4 + + - name: Run update permissions + run: chmod +x ./.github/workflows/scripts/generate-registry-area-labels.sh + + - name: Generate registry area labels + run: ./.github/workflows/scripts/generate-registry-area-labels.sh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/prepare-new-issue.yml b/.github/workflows/prepare-new-issue.yml new file mode 100644 index 0000000000..345b7dcd1e --- /dev/null +++ b/.github/workflows/prepare-new-issue.yml @@ -0,0 +1,22 @@ +name: 'Prepare new issue' +on: + issues: + types: [opened] + +jobs: + prepare-new-issue: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'open-telemetry' }} + steps: + - uses: actions/checkout@v4 + + - name: Run update permissions + run: chmod +x ./.github/workflows/scripts/prepare-new-issue.sh + + - name: Run prepare-new-issue.sh + run: ./.github/workflows/scripts/prepare-new-issue.sh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE: ${{ github.event.issue.number }} + BODY: ${{ github.event.issue.body }} + OPENER: ${{ github.event.issue.user.login }} diff --git a/.github/workflows/scripts/generate-registry-area-labels.sh b/.github/workflows/scripts/generate-registry-area-labels.sh new file mode 100755 index 0000000000..bd45812bc5 --- /dev/null +++ b/.github/workflows/scripts/generate-registry-area-labels.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +# Create labels for all semantic convention areas that are in model/registry. +# Existing labels are not affected. +# +# Note that there is a 50-character limit on labels, so some areas may +# not have a corresponding label. + +set -euo pipefail + +CUR_DIRECTORY=$(dirname "$0") +AREAS=$(sh "${CUR_DIRECTORY}/get-registry-areas.sh") + +echo -e "\nStarting to create area labels" +echo -e "--------------------------------\n" + +for AREA in ${AREAS}; do + LABEL_NAME=$(basename "${AREA}" .yaml) + + if (( "${#LABEL_NAME}" > 50 )); then + echo "'${LABEL_NAME}' exceeds GitHubs 50-character limit on labels, skipping" + continue + fi + echo "area:${LABEL_NAME}" + + # gh label create "area:${LABEL_NAME}" -c "#425cc7" +done + +echo -e "\nLabels created successfully" +echo -e "--------------------------------\n" + diff --git a/.github/workflows/scripts/get-registry-areas.sh b/.github/workflows/scripts/get-registry-areas.sh new file mode 100755 index 0000000000..b4fd8b6e18 --- /dev/null +++ b/.github/workflows/scripts/get-registry-areas.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +# Get a list of the semantic conventions areas from the registry. + +CUR_DIRECTORY=$(dirname "$0") +REPO_DIR="$( cd "$CUR_DIRECTORY/../../../" && pwd )" +REGISTRY_DIR="$( cd "$REPO_DIR/model/registry" && pwd )" + + +for entry in $(ls $REGISTRY_DIR | egrep '\.yaml$' | sort) +do + echo "$entry" +done diff --git a/.github/workflows/scripts/prepare-new-issue.sh b/.github/workflows/scripts/prepare-new-issue.sh new file mode 100755 index 0000000000..c8af7d0b4a --- /dev/null +++ b/.github/workflows/scripts/prepare-new-issue.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +# + +# This script extracts the "Area" from the issue body and adds it as a label +# on newly created issues. The area from the issue body comes from +# the "Area" drop-down field in the ISSUE_TEMPLATE, which is auto-generated +# from the files inside model/registry. + +# TODO: This script can be later used to also auto-assign the correct code-owner +# once that is implemented. + +set -euo pipefail + +if [[ -z "${ISSUE:-}" || -z "${BODY:-}" || -z "${OPENER:-}" ]]; then + echo "Missing one of ISSUE, BODY, or OPENER, please ensure all are set." + exit 0 +fi + +LABELS="" +AREAS_SECTION_START=$( (echo "${BODY}" | grep -n '### Area(s)' | awk '{ print $1 }' | grep -oE '[0-9]+') || echo '-1' ) +BODY_AREAS="" + +if [[ "${AREAS_SECTION_START}" != '-1' ]]; then + BODY_AREAS=$(echo "${BODY}" | sed -n $((AREAS_SECTION_START+2))p) +fi + +for AREA in ${BODY_AREAS}; do + # Areas are delimited by ', ' and the for loop separates on spaces, so remove the extra comma. + AREA=${AREA//,/} + + if (( "${#AREA}" > 50 )); then + echo "'${AREA}' exceeds GitHub's 50-character limit on labels, skipping adding a label" + continue + fi + + if [[ -n "${LABELS}" ]]; then + LABELS+="," + fi + LABELS+="${AREA}" +done + +if [[ -v PINGED_AREAS[@] ]]; then + echo "The issue was associated with areas:" "${!PINGED_AREAS[@]}" +else + echo "No related areas were given" +fi + +if [[ -n "${LABELS}" ]]; then + # Notes on this call: + # 1. Labels will be deduplicated by the GitHub CLI. + # 2. The call to edit the issue will fail if any of the + # labels doesn't exist. We can be reasonably sure that + # all labels will exist since they come from a known set. + echo "Adding the following labels: ${LABELS//,/ /}" + gh issue edit "${ISSUE}" --add-label "${LABELS}" || true +else + echo "No labels were found to add" +fi diff --git a/.yamllint b/.yamllint index 70b17e868b..0e43f20a2a 100644 --- a/.yamllint +++ b/.yamllint @@ -3,6 +3,9 @@ extends: default ignore-from-file: - .gitignore +ignore: | + node_modules/* + rules: document-start: disable octal-values: enable @@ -10,6 +13,8 @@ rules: allowed-values: ['true', 'false', 'on'] # 'on' for GH action trigger line-length: max: 200 + ignore: | + .github/* indentation: check-multi-line-strings: false indent-sequences: consistent diff --git a/Makefile b/Makefile index 3ef76b3827..283402f5c0 100644 --- a/Makefile +++ b/Makefile @@ -150,3 +150,9 @@ chlog-preview: $(CHLOGGEN) .PHONY: chlog-update chlog-update: $(CHLOGGEN) $(CHLOGGEN) update --config $(CHLOGGEN_CONFIG) --version $(VERSION) + +# Updates the areas (registry yaml file names) on all ISSUE_TEMPLATE +# files that have the "area" dropdown field +.PHONY: generate-gh-issue-templates +generate-gh-issue-templates: + $(TOOLS_DIR)/scripts/update-issue-template-areas.sh diff --git a/internal/tools/scripts/update-issue-template-areas.sh b/internal/tools/scripts/update-issue-template-areas.sh new file mode 100755 index 0000000000..1e7c7cb276 --- /dev/null +++ b/internal/tools/scripts/update-issue-template-areas.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +# Create labels for all semantic convention areas that are in model/registry. +# Existing labels are not affected. +# +# Note that there is a 50-character limit on labels, so some areas may +# not have a corresponding label. + +set -euo pipefail + +CUR_DIRECTORY=$(dirname "$0") +REPO_DIR="$( cd "$CUR_DIRECTORY/../../../" && pwd )" +GITHUB_DIR="$( cd "$REPO_DIR/.github/" && pwd )" +TEMPLATES_DIR="$( cd "$GITHUB_DIR/ISSUE_TEMPLATE" && pwd )" + +AREAS=$(sh "${GITHUB_DIR}/workflows/scripts/get-registry-areas.sh") + +START_AREA_LIST="# Start semconv area list" +END_AREA_LIST="# End semconv area list" + +replacement=" ${START_AREA_LIST}" + +for AREA in ${AREAS}; do + LABEL_NAME=$(basename "${AREA}" .yaml) + replacement="${replacement}\n - area:${LABEL_NAME}" +done + +echo -e "\nStarting to replace areas in ISSUE_TEMPLATES:" +echo -e "---------------------------------------------\n" + +replacement="${replacement}\n ${END_AREA_LIST}" + +echo -e "The replacement text will be:" +echo -e "---------------------------------------------\n" +echo -e $replacement + +find ${TEMPLATES_DIR} -type f -name '*.yaml' -exec sed -i "/$START_AREA_LIST/,/$END_AREA_LIST/c\\$replacement" {} \; + +echo -e "\nISSUE_TEMPLATES updated successfully" +echo -e "---------------------------------------------" From 80a2d1a8f70c96c51e541827c7548ba42bb77876 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:09:49 +0100 Subject: [PATCH 388/482] [chore] Enable creating area labels on push to `main` (#824) --- .github/workflows/scripts/generate-registry-area-labels.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/scripts/generate-registry-area-labels.sh b/.github/workflows/scripts/generate-registry-area-labels.sh index bd45812bc5..e06082e982 100755 --- a/.github/workflows/scripts/generate-registry-area-labels.sh +++ b/.github/workflows/scripts/generate-registry-area-labels.sh @@ -25,8 +25,7 @@ for AREA in ${AREAS}; do continue fi echo "area:${LABEL_NAME}" - - # gh label create "area:${LABEL_NAME}" -c "#425cc7" + gh label create "area:${LABEL_NAME}" -c "#425cc7" done echo -e "\nLabels created successfully" From f94edec229a665ff99014f579d33f15b8cda10d7 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 22 Mar 2024 02:37:47 +0100 Subject: [PATCH 389/482] [chore] Move metric requirement levels doc from spec (#831) Co-authored-by: Trask Stalnaker --- docs/database/database-metrics.md | 4 +-- docs/faas/faas-metrics.md | 2 +- docs/general/metric-requirement-level.md | 43 ++++++++++++++++++++++++ docs/messaging/messaging-metrics.md | 6 ++-- docs/rpc/rpc-metrics.md | 2 +- docs/runtime/jvm-metrics.md | 4 +-- docs/system/process-metrics.md | 2 +- docs/system/system-metrics.md | 4 +-- model/README.md | 2 +- 9 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 docs/general/metric-requirement-level.md diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index cd476652e0..f7bedea83d 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -191,5 +191,5 @@ This metric is [recommended][MetricRecommended]. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#required -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricRequired]: /docs/general/metric-requirement-level.md#required +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index 22dbc92556..9ecf509df3 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -301,4 +301,4 @@ FaaS providers. This list is not exhaustive. * [OpenFaas Metrics](https://docs.openfaas.com/architecture/metrics/) [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/general/metric-requirement-level.md b/docs/general/metric-requirement-level.md new file mode 100644 index 0000000000..e9de297124 --- /dev/null +++ b/docs/general/metric-requirement-level.md @@ -0,0 +1,43 @@ +# Metric Requirement Levels + +**Status**: [Stable][DocumentStatus] + +
+Table of Contents + + + +- [Required](#required) +- [Recommended](#recommended) +- [Opt-In](#opt-in) + + + +
+ +The following metric requirement levels are specified: + +- [Required](#required) +- [Recommended](#recommended) +- [Opt-In](#opt-in) + +## Required + +All instrumentations MUST emit the metric. +A semantic convention defining a Required metric expects that an absolute majority of instrumentation libraries and applications are able to efficiently emit it. + +## Recommended + +Instrumentations SHOULD emit the metric by default if it's readily available and can be efficiently emitted. Instrumentations MAY offer a configuration option to disable Recommended metrics. + +Instrumentations that decide not to emit `Recommended` metrics due to performance, security, privacy, or other consideration by default, SHOULD allow for opting in to emitting them as defined for the `Opt-In` requirement level if the metrics are logically applicable. + +## Opt-In + +Instrumentations SHOULD emit the metric if and only if the user configures the instrumentation to do so. +Instrumentation that doesn't support configuration MUST NOT emit `Opt-In` metrics. + +This attribute requirement level is recommended for metrics that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled deliberately by a user making an informed decision. + +[DocumentStatus]: + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index f650cfd9bf..7f4cf40ddd 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -187,6 +187,6 @@ _Note: The need to report `messaging.process.messages` depends on the messaging [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/document-status.md -[MetricRequired]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#required -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#recommended -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/metrics/metric-requirement-level.md#opt-in +[MetricRequired]: /docs/general/metric-requirement-level.md#required +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended +[MetricOptIn]: /docs/general/metric-requirement-level.md#opt-in diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 693653d92e..ff162640e3 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -289,4 +289,4 @@ More specific Semantic Conventions are defined for the following RPC technologie * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 3d27e0a24a..7d2d27d148 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -455,5 +455,5 @@ This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricOptIn]: /docs/general/metric-requirement-level.md#opt-in +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 31b1367200..3feb662a15 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -238,4 +238,4 @@ This metric is [recommended][MetricRecommended]. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index ebb3bf3c3a..7bc0a81a2c 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -795,8 +795,8 @@ An instrument for load average over 1 minute on Linux could be named an `{os}` prefix to split this metric across OSes. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[MetricRecommended]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md#recommended -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended +[MetricOptIn]: /docs/general/metric-requirement-level.md#opt-in ### Metric: `system.linux.memory.available` diff --git a/model/README.md b/model/README.md index 2fc6f39b35..f5968affd5 100644 --- a/model/README.md +++ b/model/README.md @@ -12,7 +12,7 @@ the generated markdown output in the [docs](../docs/README.md) folder. Semantic conventions for the spec MUST adhere to the [attribute naming](../docs/general/attribute-naming.md), [attribute requirement level](../docs/general/attribute-requirement-level.md), -and [metric requirement level](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/metric-requirement-level.md) conventions. +and [metric requirement level](../docs/general/metric-requirement-level.md) conventions. Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. From 25b4932b923dadd618121f24bee8f87509fc3ad5 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 22 Mar 2024 08:23:04 -0700 Subject: [PATCH 390/482] [chore] Mark dotnet-specific metrics and attributes stable in yaml to match markdown (#819) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- docs/dotnet/dotnet-aspnetcore-metrics.md | 26 ++++++++++----------- docs/dotnet/dotnet-kestrel-metrics.md | 12 +++++----- docs/dotnet/dotnet-signalr-metrics.md | 8 +++---- model/metrics/dotnet/dotnet-aspnetcore.yaml | 14 +++++++++++ model/metrics/dotnet/dotnet-kestrel.yaml | 10 ++++++++ model/metrics/dotnet/dotnet-signalr.yaml | 4 ++++ 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index b09a34d8b8..54b8fc04a0 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -43,9 +43,9 @@ All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | Conditionally Required: if and only if a route was successfully matched. | -| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | Required | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: if and only if a route was successfully matched. | +| `aspnetcore.routing.is_fallback` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
A value that indicates whether the matched route is a fallback route. | `True` | Conditionally Required: if and only if a route was successfully matched. | +| `aspnetcore.routing.match_status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Match result - success or failure | `success`; `failure` | Required | +| [`http.route`](../attributes-registry/http.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: if and only if a route was successfully matched. | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. @@ -75,9 +75,9 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | Required | -| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | Conditionally Required: [1] | -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [2] | `System.OperationCanceledException`; `Contoso.MyException` | Required | +| `aspnetcore.diagnostics.exception.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
ASP.NET Core exception middleware handling result | `handled`; `unhandled` | Required | +| `aspnetcore.diagnostics.handler.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | Conditionally Required: [1] | +| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [2] | `System.OperationCanceledException`; `Contoso.MyException` | Required | **[1]:** if and only if the exception was handled by this handler. @@ -130,7 +130,7 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -152,7 +152,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -170,7 +170,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -192,8 +192,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | +| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -225,8 +225,8 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | +| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| `aspnetcore.rate_limiting.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | **[1]:** if the matched endpoint for the request had a rate-limiting policy. diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md index 96f400ab19..81ea6e79a4 100644 --- a/docs/dotnet/dotnet-kestrel-metrics.md +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -94,9 +94,9 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [3] | `1.1`; `2` | Recommended | +| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | +| [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [3] | `1.1`; `2` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -252,8 +252,8 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [2] | `1.1`; `2` | Recommended | +| [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [2] | `1.1`; `2` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -358,7 +358,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | +| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index dc2b04ed06..931d5f4bf3 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -32,8 +32,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | +| `signalr.connection.status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | +| `signalr.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | `signalr.connection.status` MUST be one of the following: @@ -65,8 +65,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | +| `signalr.connection.status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | +| `signalr.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | `signalr.connection.status` MUST be one of the following: diff --git a/model/metrics/dotnet/dotnet-aspnetcore.yaml b/model/metrics/dotnet/dotnet-aspnetcore.yaml index 8369e068d5..89ce151d2d 100644 --- a/model/metrics/dotnet/dotnet-aspnetcore.yaml +++ b/model/metrics/dotnet/dotnet-aspnetcore.yaml @@ -7,6 +7,7 @@ groups: - id: rate_limiting.policy type: string brief: Rate limiting policy name. + stability: stable examples: ["fixed", "sliding", "token"] requirement_level: conditionally_required: if the matched endpoint for the request had a rate-limiting policy. @@ -26,17 +27,20 @@ groups: - id: request_canceled value: 'request_canceled' brief: "Lease request was canceled" + stability: stable brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason examples: ["acquired", "request_canceled"] requirement_level: required - id: routing.is_fallback type: boolean + stability: stable brief: A value that indicates whether the matched route is a fallback route. examples: [true] requirement_level: conditionally_required: If and only if a route was successfully matched. - id: diagnostics.handler.type type: string + stability: stable brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. examples: ["Contoso.MyHandler"] @@ -44,6 +48,7 @@ groups: conditionally_required: if and only if the exception was handled by this handler. - id: request.is_unhandled type: boolean + stability: stable brief: Flag indicating if request was handled by the application pipeline. examples: [true] requirement_level: @@ -53,6 +58,7 @@ groups: - id: metric.aspnetcore.routing.match_attempts type: metric metric_name: aspnetcore.routing.match_attempts + stability: stable brief: Number of requests that were attempted to be matched to an endpoint. instrument: counter unit: "{match_attempt}" @@ -75,6 +81,7 @@ groups: - id: failure value: 'failure' brief: 'Match failed' + stability: stable requirement_level: required brief: Match result - success or failure examples: ["success", "failure"] @@ -83,6 +90,7 @@ groups: - id: metric.aspnetcore.diagnostics.exceptions type: metric metric_name: aspnetcore.diagnostics.exceptions + stability: stable brief: Number of exceptions caught by exception handling middleware. instrument: counter unit: "{exception}" @@ -109,6 +117,7 @@ groups: - id: aborted value: 'aborted' brief: "Exception handling didn't run because the request was aborted." + stability: stable requirement_level: required brief: ASP.NET Core exception middleware handling result examples: ["handled", "unhandled"] @@ -117,6 +126,7 @@ groups: - id: metric.aspnetcore.rate_limiting.active_request_leases type: metric metric_name: aspnetcore.rate_limiting.active_request_leases + stability: stable brief: Number of requests that are currently active on the server that hold a rate limiting lease. instrument: updowncounter unit: "{request}" @@ -128,6 +138,7 @@ groups: - id: metric.aspnetcore.rate_limiting.request_lease.duration type: metric metric_name: aspnetcore.rate_limiting.request_lease.duration + stability: stable brief: The duration of rate limiting lease held by requests on the server. instrument: histogram unit: "s" @@ -139,6 +150,7 @@ groups: - id: metric.aspnetcore.rate_limiting.request.time_in_queue type: metric metric_name: aspnetcore.rate_limiting.request.time_in_queue + stability: stable brief: The time the request spent in a queue waiting to acquire a rate limiting lease. instrument: histogram unit: "s" @@ -151,6 +163,7 @@ groups: - id: metric.aspnetcore.rate_limiting.queued_requests type: metric metric_name: aspnetcore.rate_limiting.queued_requests + stability: stable brief: Number of requests that are currently queued, waiting to acquire a rate limiting lease. instrument: updowncounter unit: "{request}" @@ -162,6 +175,7 @@ groups: - id: metric.aspnetcore.rate_limiting.requests type: metric metric_name: aspnetcore.rate_limiting.requests + stability: stable brief: Number of requests that tried to acquire a rate limiting lease. instrument: counter unit: "{request}" diff --git a/model/metrics/dotnet/dotnet-kestrel.yaml b/model/metrics/dotnet/dotnet-kestrel.yaml index e04714a9b5..9a4a231f51 100644 --- a/model/metrics/dotnet/dotnet-kestrel.yaml +++ b/model/metrics/dotnet/dotnet-kestrel.yaml @@ -14,6 +14,7 @@ groups: - id: metric.kestrel.active_connections type: metric metric_name: kestrel.active_connections + stability: stable brief: Number of connections that are currently active on the server. instrument: updowncounter unit: "{connection}" @@ -24,6 +25,7 @@ groups: - id: metric.kestrel.connection.duration type: metric metric_name: kestrel.connection.duration + stability: stable brief: The duration of connections on the server. instrument: histogram unit: "s" @@ -36,6 +38,7 @@ groups: - ref: network.protocol.version examples: ["1.1", "2"] - ref: tls.protocol.version + stability: experimental - ref: error.type brief: The full name of exception type. requirement_level: @@ -46,6 +49,7 @@ groups: - id: metric.kestrel.rejected_connections type: metric metric_name: kestrel.rejected_connections + stability: stable brief: Number of connections rejected by the server. instrument: counter unit: "{connection}" @@ -57,6 +61,7 @@ groups: - id: metric.kestrel.queued_connections type: metric metric_name: kestrel.queued_connections + stability: stable brief: Number of connections that are currently queued and are waiting to start. instrument: updowncounter unit: "{connection}" @@ -67,6 +72,7 @@ groups: - id: metric.kestrel.queued_requests type: metric metric_name: kestrel.queued_requests + stability: stable brief: Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start. instrument: updowncounter unit: "{request}" @@ -82,6 +88,7 @@ groups: - id: metric.kestrel.upgraded_connections type: metric metric_name: kestrel.upgraded_connections + stability: stable brief: Number of connections that are currently upgraded (WebSockets). . instrument: updowncounter unit: "{connection}" @@ -94,6 +101,7 @@ groups: - id: metric.kestrel.tls_handshake.duration type: metric metric_name: kestrel.tls_handshake.duration + stability: stable brief: The duration of TLS handshakes on the server. instrument: histogram unit: "s" @@ -102,6 +110,7 @@ groups: extends: common.kestrel.attributes attributes: - ref: tls.protocol.version + stability: experimental - ref: error.type brief: The full name of exception type. note: "Captures the exception type when a TLS handshake fails." @@ -112,6 +121,7 @@ groups: - id: metric.kestrel.active_tls_handshakes type: metric metric_name: kestrel.active_tls_handshakes + stability: stable brief: Number of TLS handshakes that are currently in progress on the server. instrument: updowncounter unit: "{handshake}" diff --git a/model/metrics/dotnet/dotnet-signalr.yaml b/model/metrics/dotnet/dotnet-signalr.yaml index 3333669c57..b47ebf6908 100644 --- a/model/metrics/dotnet/dotnet-signalr.yaml +++ b/model/metrics/dotnet/dotnet-signalr.yaml @@ -16,6 +16,7 @@ groups: - id: app_shutdown value: 'app_shutdown' brief: "The connection was closed because the app is shutting down." + stability: stable brief: SignalR HTTP connection closure status. examples: ["app_shutdown", "timeout"] - id: transport @@ -32,11 +33,13 @@ groups: - id: web_sockets value: 'web_sockets' brief: "WebSockets protocol" + stability: stable examples: ["web_sockets", "long_polling"] - id: metric.signalr.server.connection.duration type: metric metric_name: signalr.server.connection.duration + stability: stable brief: The duration of connections on the server. instrument: histogram unit: "s" @@ -49,6 +52,7 @@ groups: - id: metric.signalr.server.active_connections type: metric metric_name: signalr.server.active_connections + stability: stable brief: Number of connections that are currently active on the server. instrument: updowncounter unit: "{connection}" From e01cafdcbe4828407945dde718af94c664b69fec Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 25 Mar 2024 08:39:18 -0700 Subject: [PATCH 391/482] Messaging: clarify network attributes usage on common semconv (#698) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/698.yaml | 7 +++ docs/messaging/gcp-pubsub.md | 4 +- docs/messaging/kafka.md | 2 +- docs/messaging/messaging-metrics.md | 16 ++----- docs/messaging/messaging-spans.md | 58 ++++--------------------- docs/messaging/rabbitmq.md | 6 ++- docs/messaging/rocketmq.md | 2 +- model/messaging-common.yaml | 7 +-- model/trace/messaging.yaml | 67 +++++++++++++++++++---------- 9 files changed, 75 insertions(+), 94 deletions(-) create mode 100644 .chloggen/698.yaml diff --git a/.chloggen/698.yaml b/.chloggen/698.yaml new file mode 100644 index 0000000000..c12d9d9f2d --- /dev/null +++ b/.chloggen/698.yaml @@ -0,0 +1,7 @@ +change_type: breaking + +component: messaging + +note: Remove `network.transport` and `network.type` attributes from messaging semantic conventions, clarify when `network.peer.address|port` should be populated. + +issues: [690, 698] diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 95acf97d64..17b74081a9 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -13,7 +13,7 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub ## Span attributes For Google Cloud Pub/Sub, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | Conditionally Required: If the message type has an ordering key set. | @@ -31,7 +31,7 @@ flowchart LR; direction LR CA[Span Create A] CB[Span Create B] - P[Span Publish A B] + P[Span Publish A B] end CA-. link .-P; CB-. link .-P; diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 4f6866ed83..522c4c2a16 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -24,7 +24,7 @@ described on this page. For Apache Kafka, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id the message (or batch) is sent to or received from."" | `1` | Recommended | diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 7f4cf40ddd..4f2678243c 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -36,10 +36,8 @@ All messaging metrics share the same set of attributes: | [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | Conditionally Required: [4] | | [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | Conditionally Required: if available. | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [6] | `amqp`; `mqtt` | Conditionally Required: [7] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [8] | `3.1.1` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [10] | `80`; `8080`; `443` | Recommended | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Recommended | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -66,15 +64,9 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi **[5]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[6]:** The value SHOULD be normalized to lowercase. +**[6]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[7]:** Only for messaging systems and frameworks that support more than one protocol. - -**[8]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - -**[9]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. - -**[10]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 7cff828c2c..f78ad5993c 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -275,8 +275,6 @@ Messaging attributes are organized into the following namespaces: - `messaging.batch`: Contains attributes that describe batch operations. - `messaging.consumer`: Contains [consumer attributes](#consumer-attributes) that describe the application instance that consumes a message. See [consumer](#consumer) for more details. -The communication with the intermediary is described with general [network attributes]. - Messaging system-specific attributes MUST be defined in the corresponding `messaging.{system}` namespace as described in [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems). @@ -296,14 +294,10 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended | | [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [13] | `publish` | Required | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [14] | `amqp`; `mqtt` | Conditionally Required: [15] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [16] | `3.1.1` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [18] | `ipv4`; `ipv6` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [19] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [20] | `80`; `8080`; `443` | Recommended | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [14] | `10.1.2.80`; `/tmp/my.sock` | Recommended: If applicable for this messaging system. | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | Recommended: if and only if `network.peer.address` is set. | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [15] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | Recommended | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -348,23 +342,13 @@ size should be used. **[13]:** If a custom value is used, it MUST be of low cardinality. -**[14]:** The value SHOULD be normalized to lowercase. - -**[15]:** Only for messaging systems and frameworks that support more than one protocol. - -**[16]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - -**[17]:** The value SHOULD be normalized to lowercase. +**[14]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +Network peer address and port are important when the application interacts with individual intermediary nodes directly, +If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. +**[15]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[18]:** The value SHOULD be normalized to lowercase. - -**[19]:** This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. - -**[20]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[16]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `error.type` 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. @@ -396,32 +380,8 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `kafka` | Apache Kafka | | `rabbitmq` | RabbitMQ | | `rocketmq` | Apache RocketMQ | - -`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | - -`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | -Additionally `server.port` from the [network attributes][] is recommended. -Furthermore, it is strongly recommended to add the [`network.transport`][] attribute and follow its guidelines, especially for in-process queueing systems (like [Hangfire][], for example). -These attributes should be set to the broker to which the message is sent/from which it is received. - -[network attributes]: /docs/general/attributes.md#server-and-client-attributes -[`network.transport`]: /docs/general/attributes.md#network-attributes -[Hangfire]: https://www.hangfire.io/ - ### Consumer attributes The following additional attributes describe message consumer operations. diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 1c8f2ec8cc..7852546f4d 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -17,11 +17,15 @@ described on this page. In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. `messaging.destination.name` MUST be set to the name of the exchange. This will be an empty string if the default exchange is used. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | | [`messaging.rabbitmq.message.delivery_tag`](../attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | Conditionally Required: When available. | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `10.1.2.80`; `/tmp/my.sock` | Recommended | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | Recommended | + +**[1]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index 8f4bbca5fb..eb0d8b3d5d 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -16,7 +16,7 @@ described on this page. Specific attributes for Apache RocketMQ are defined below. - + | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`messaging.rocketmq.client_group`](../attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | Required | diff --git a/model/messaging-common.yaml b/model/messaging-common.yaml index f5505a0baf..35d6a8eefb 100644 --- a/model/messaging-common.yaml +++ b/model/messaging-common.yaml @@ -12,12 +12,7 @@ groups: conditionally_required: If and only if the messaging operation has failed. - ref: server.address note: > - This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from. + Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. requirement_level: conditionally_required: If available. - ref: server.port - - ref: network.protocol.name - examples: ['amqp', 'mqtt'] - requirement_level: - conditionally_required: Only for messaging systems and frameworks that support more than one protocol. - - ref: network.protocol.version diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 362eaab9f4..75410d34de 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -80,28 +80,51 @@ groups: - ref: messaging.message.conversation_id - ref: messaging.message.envelope.size - ref: messaging.message.body.size - - ref: server.address - ref: network.peer.address + brief: Peer address of the messaging intermediary node where the operation was performed. + requirement_level: + recommended: If applicable for this messaging system. + note: > + Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. + + Network peer address and port are important when the application interacts with individual intermediary nodes directly, + + If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - ref: network.peer.port + brief: Peer port of the messaging intermediary node where the operation was performed. requirement_level: - recommended: If `network.peer.address` is set. - - ref: network.transport - - ref: network.type + recommended: if and only if `network.peer.address` is set. - - id: messaging.rabbitmq + - id: messaging.tech_specific.network.attributes type: attribute_group + brief: Attributes that describe messaging operation along with network information. extends: messaging + attributes: + - ref: network.peer.address + requirement_level: recommended + note: > + If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + - ref: network.peer.port + requirement_level: recommended + + - id: messaging.rabbitmq + type: attribute_group + extends: messaging.tech_specific.network.attributes brief: > Attributes for RabbitMQ attributes: - ref: messaging.rabbitmq.destination.routing_key requirement_level: conditionally_required: If not empty. - tag: tech-specific-rabbitmq + tag: tech-specific - ref: messaging.rabbitmq.message.delivery_tag requirement_level: conditionally_required: When available. - tag: tech-specific-rabbitmq + tag: tech-specific + - ref: network.peer.address + tag: tech-specific + - ref: network.peer.port + tag: tech-specific - id: messaging.kafka type: attribute_group @@ -112,17 +135,17 @@ groups: - ref: messaging.destination.partition.id brief: > "String representation of the partition id the message (or batch) is sent to or received from."" - tag: tech-specific-kafka + tag: tech-specific - ref: messaging.kafka.message.key - tag: tech-specific-kafka + tag: tech-specific - ref: messaging.kafka.consumer.group - tag: tech-specific-kafka + tag: tech-specific - ref: messaging.kafka.message.offset - tag: tech-specific-kafka + tag: tech-specific - ref: messaging.kafka.message.tombstone requirement_level: conditionally_required: If value is `true`. When missing, the value is assumed to be `false`. - tag: tech-specific-kafka + tag: tech-specific - id: messaging.rocketmq type: attribute_group @@ -132,30 +155,30 @@ groups: attributes: - ref: messaging.rocketmq.namespace requirement_level: required - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.client_group requirement_level: required - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.delivery_timestamp requirement_level: conditionally_required: If the message type is delay and delay time level is not specified. - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.delay_time_level requirement_level: conditionally_required: If the message type is delay and delivery timestamp is not specified. - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.group requirement_level: conditionally_required: If the message type is FIFO. - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.type - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.tag - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.message.keys - tag: tech-specific-rocketmq + tag: tech-specific - ref: messaging.rocketmq.consumption_model - tag: tech-specific-rocketmq + tag: tech-specific - id: messaging.gcp_pubsub type: attribute_group extends: messaging @@ -163,7 +186,7 @@ groups: Attributes for Google Cloud Pub/Sub attributes: - ref: messaging.gcp_pubsub.message.ordering_key - tag: tech-specific-gcp-pubsub + tag: tech-specific requirement_level: conditionally_required: If the message type has an ordering key set. - id: messaging.servicebus From 83119ef0d0050a55353ff48bd3cb6c36dc86bb37 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 25 Mar 2024 09:44:25 -0700 Subject: [PATCH 392/482] Clarify that `network.protocol.version` represents negotiated version (#817) --- .chloggen/817.yaml | 4 ++++ docs/attributes-registry/network.md | 4 ++-- docs/dotnet/dotnet-http-metrics.md | 6 ++--- docs/dotnet/dotnet-kestrel-metrics.md | 8 +++---- docs/general/attributes.md | 4 ++-- docs/http/http-metrics.md | 32 +++++++++++++-------------- docs/http/http-spans.md | 4 ++-- model/registry/network.yaml | 10 ++++----- 8 files changed, 38 insertions(+), 34 deletions(-) create mode 100644 .chloggen/817.yaml diff --git a/.chloggen/817.yaml b/.chloggen/817.yaml new file mode 100644 index 0000000000..bf56ad5daa --- /dev/null +++ b/.chloggen/817.yaml @@ -0,0 +1,4 @@ +change_type: bug_fix +component: network +note: Clarifies that network.protocol.version represents negotiated version +issues: [ 686 ] diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index a06417c9dc..b534c86f54 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -22,13 +22,13 @@ These attributes may be used for any network related operation. | `network.peer.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | `network.peer.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer port number of the network connection. | `65123` | | `network.protocol.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | -| `network.protocol.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | +| `network.protocol.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [2] | `1.1`; `2` | | `network.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | | `network.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | **[1]:** The value SHOULD be normalized to lowercase. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[2]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[3]:** The value SHOULD be normalized to lowercase. diff --git a/docs/dotnet/dotnet-http-metrics.md b/docs/dotnet/dotnet-http-metrics.md index e4e4f7c28c..e59166dd01 100644 --- a/docs/dotnet/dotnet-http-metrics.md +++ b/docs/dotnet/dotnet-http-metrics.md @@ -54,7 +54,7 @@ Notes: |---|---|---|---|---| | `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Remote IP address of the socket connection. | `10.1.2.80` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The negotiated version of the protocol associated with connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.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] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | @@ -90,7 +90,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The negotiated version of the protocol associated with connection in the connection pool. [1] | `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.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] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | @@ -119,7 +119,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | HTTP protocol version of the connection in the connection pool. [2] | `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The negotiated version of the protocol associated with connection in the connection pool. [2] | `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Conditionally Required: [5] | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Recommended | diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md index 81ea6e79a4..a6971f77ef 100644 --- a/docs/dotnet/dotnet-kestrel-metrics.md +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -96,7 +96,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. |---|---|---|---|---| | [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | | [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [3] | `1.1`; `2` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [3] | `1.1`; `2` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -107,7 +107,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. **[2]:** The value SHOULD be normalized to lowercase. -**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[3]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[4]:** The value SHOULD be normalized to lowercase. @@ -253,7 +253,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Version of the protocol specified in `network.protocol.name`. [2] | `1.1`; `2` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [2] | `1.1`; `2` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | @@ -261,7 +261,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[1]:** The value SHOULD be normalized to lowercase. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[2]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[3]:** The value SHOULD be normalized to lowercase. diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 3ae6cbfdfd..d809f56add 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -164,13 +164,13 @@ if they do not cause breaking changes to HTTP semantic conventions. | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [2] | `3.1.1` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | **[1]:** The value SHOULD be normalized to lowercase. -**[2]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[2]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[3]:** The value SHOULD be normalized to lowercase. diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index dd429a32fb..f6e5d7ec3c 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -83,7 +83,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | @@ -127,7 +127,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** If not `http` and `network.protocol.version` is set. -**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** @@ -246,7 +246,7 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | @@ -290,7 +290,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** If not `http` and `network.protocol.version` is set. -**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** @@ -348,7 +348,7 @@ This metric is optional. | [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | | [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | @@ -392,7 +392,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin **[5]:** If not `http` and `network.protocol.version` is set. -**[6]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** @@ -455,7 +455,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | @@ -496,7 +496,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** If not `http` and `network.protocol.version` is set. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. @@ -545,7 +545,7 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | @@ -586,7 +586,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** If not `http` and `network.protocol.version` is set. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. @@ -635,7 +635,7 @@ This metric is optional. | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | @@ -676,7 +676,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[4]:** If not `http` and `network.protocol.version` is set. -**[5]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. @@ -721,12 +721,12 @@ This metric is optional. |---|---|---|---|---| | [`http.connection.state`](../attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [1] | `3.1.1` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [1] | `1.1`; `2` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.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` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | -**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[1]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -760,12 +760,12 @@ This metric is optional. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [1] | `3.1.1` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [1] | `1.1`; `2` | Recommended | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | | [`server.port`](../attributes-registry/server.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` | Required | | [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | -**[1]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[1]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 1668199fa2..fcbadbf9b3 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -125,7 +125,7 @@ sections below. | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | | [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | Conditionally Required: [6] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | Version of the protocol specified in `network.protocol.name`. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | **[1]:** If the request fails with an error before response status code was sent or received, @@ -170,7 +170,7 @@ The attribute value MUST consist of either multiple header values as an array of **[6]:** If not `http` and `network.protocol.version` is set. -**[7]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. diff --git a/model/registry/network.yaml b/model/registry/network.yaml index e7520bae9c..0c1da314c4 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -141,12 +141,12 @@ groups: - id: protocol.version stability: stable type: string - brief: Version of the protocol specified in `network.protocol.name`. - examples: '3.1.1' + brief: The actual version of the protocol used for network communication. + examples: ['1.1', '2'] note: > - `network.protocol.version` refers to the version of the protocol used and might be - different from the protocol client's version. If the HTTP client has a version - of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), + this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, + this attribute SHOULD NOT be set. - id: transport stability: stable type: From 8ac8d450f30c076b40f49f51ff01f0db5f59d51d Mon Sep 17 00:00:00 2001 From: Emily S Date: Tue, 26 Mar 2024 12:36:32 +0100 Subject: [PATCH 393/482] Use db.instance.id instead of specific elasticsearch node name attribute (#738) Co-authored-by: Trask Stalnaker --- .chloggen/738.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/db.md | 15 +++++++++++++-- docs/database/elasticsearch.md | 10 +++++----- model/registry/db.yaml | 7 ------- model/registry/deprecated/db.yaml | 5 +++++ model/trace/database.yaml | 2 +- 6 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 .chloggen/738.yaml diff --git a/.chloggen/738.yaml b/.chloggen/738.yaml new file mode 100644 index 0000000000..1d09182d8a --- /dev/null +++ b/.chloggen/738.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Update Elasticsearch attributes to use db.instance.id instead of db.elasticsearch.node.name + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [725] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index be7f5753d0..0c39de22e2 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -14,6 +14,7 @@ - [Redis Attributes](#redis-attributes) - [SQL Attributes](#sql-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) + - [Deprecated Elasticsearch Attributes](#deprecated-elasticsearch-attributes) @@ -171,7 +172,6 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | -| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | | `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. @@ -219,5 +219,16 @@ | Attribute | Type | Description | Examples | |---|---|---|---| | `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | +| `db.elasticsearch.node.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `db.instance.id` instead. | `instance-0000000001` | | `db.jdbc.driver_classname` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | - \ No newline at end of file + + +### Deprecated Elasticsearch Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | +| `db.elasticsearch.node.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `db.instance.id` instead. | `instance-0000000001` | +| `db.jdbc.driver_classname` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | + diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 4603978dda..5c8d9f5a9d 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -27,8 +27,8 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| | [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | -| [`db.elasticsearch.node.name`](../attributes-registry/db.md) | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | Recommended: [2] | -| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [3] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | +| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [2] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: [3] | | [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | | [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | @@ -40,9 +40,9 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m **[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. -**[2]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. +**[2]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -**[3]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. +**[3]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. **[4]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. @@ -105,6 +105,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `url.full` | `"https://elasticsearch.mydomain.com:9200/my-index-000001/_search?from=40&size=20"` | | `db.elasticsearch.path_parts.index` | `"my-index-000001"` | | `db.elasticsearch.cluster.name` | `"e9106fc68e3044f0b1475b04bf4ffd5f"` | -| `db.elasticsearch.node.name` | `"instance-0000000001"` | +| `db.instance.id` | `"instance-0000000001"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 4185c279ab..781cc68f9f 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -173,13 +173,6 @@ groups: Represents the identifier of an Elasticsearch cluster. examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] tag: tech-specific-elasticsearch - - id: elasticsearch.node.name - type: string - stability: experimental - brief: > - Represents the human-readable identifier of the node/instance to which a request was routed. - examples: ["instance-0000000001"] - tag: tech-specific-elasticsearch - id: elasticsearch.path_parts type: template[string] stability: experimental diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 1dd6996704..76430d1b1b 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -16,3 +16,8 @@ groups: brief: 'Removed, no replacement at this time.' deprecated: 'Removed as not used.' examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] + - id: elasticsearch.node.name + type: string + brief: 'Deprecated, use `db.instance.id` instead.' + deprecated: "Replaced by `db.instance.id`." + examples: ["instance-0000000001"] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index e824438bf9..7435d4e485 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -189,7 +189,7 @@ groups: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. tag: tech-specific - - ref: db.elasticsearch.node.name + - ref: db.instance.id requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. From 4368358cdcdd78f37291317a31cbc413080738ec Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 26 Mar 2024 05:48:05 -0700 Subject: [PATCH 394/482] Link to proposal for gRPC metrics (#627) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/627.yaml | 22 ++++++++++++++++++++++ docs/rpc/README.md | 4 ++++ docs/rpc/rpc-metrics.md | 4 ++++ 3 files changed, 30 insertions(+) create mode 100755 .chloggen/627.yaml diff --git a/.chloggen/627.yaml b/.chloggen/627.yaml new file mode 100755 index 0000000000..1e96d83745 --- /dev/null +++ b/.chloggen/627.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: rpc + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add link to specification for metrics defined by gRPC community. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [627] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/rpc/README.md b/docs/rpc/README.md index 353f6bce85..f028fd910a 100644 --- a/docs/rpc/README.md +++ b/docs/rpc/README.md @@ -23,4 +23,8 @@ Technology specific semantic conventions are defined for the following RPC syste * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. +Specifications defined by maintainers of RPC systems: + +* [gRPC](https://github.com/grpc/proposal/blob/master/A66-otel-stats.md): Semantic Conventions for *gRPC*. + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index ff162640e3..6369eb4461 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -288,5 +288,9 @@ More specific Semantic Conventions are defined for the following RPC technologie * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. +Specifications defined by maintainers of RPC systems: + +* [gRPC](https://github.com/grpc/proposal/blob/master/A66-otel-stats.md): Semantic Conventions for *gRPC*. + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended From 0941ebb01638da01086baeaafe39c6de8a6b3d91 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 27 Mar 2024 11:47:38 +0200 Subject: [PATCH 395/482] Add container metric fields (from ECS) (#282) Signed-off-by: ChrsMark Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/add_new_container_metrics.yaml | 21 +++++ docs/attributes-registry/container.md | 9 ++ docs/system/container-metrics.md | 105 +++++++++++++++++++++++ model/metrics/container.yaml | 53 ++++++++++++ model/registry/container.yaml | 15 ++++ 5 files changed, 203 insertions(+) create mode 100644 .chloggen/add_new_container_metrics.yaml create mode 100644 docs/system/container-metrics.md create mode 100644 model/metrics/container.yaml diff --git a/.chloggen/add_new_container_metrics.yaml b/.chloggen/add_new_container_metrics.yaml new file mode 100644 index 0000000000..4e6c71bb49 --- /dev/null +++ b/.chloggen/add_new_container_metrics.yaml @@ -0,0 +1,21 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: "enhancement" + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: "container" + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add new container metrics for `cpu`, `memory`, `disk` and `network`" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [282, 72] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index d9f66e67f9..4e6ec20847 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -11,6 +11,7 @@ | `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | | `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | | `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | +| `container.cpu.state` | string | The CPU state for this data point. | `user`; `kernel` | | `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | | `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | | `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | @@ -27,4 +28,12 @@ K8s defines a link to the container registry repository with digest `"imageID": The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. **[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. + +`container.cpu.state` 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 | +|---|---| +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | +| `system` | When CPU is used by the system (host OS) | +| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md new file mode 100644 index 0000000000..d5df4933b2 --- /dev/null +++ b/docs/system/container-metrics.md @@ -0,0 +1,105 @@ + + +# Semantic Conventions for Container Metrics + +**Status**: [Experimental][DocumentStatus] + +## Container Metrics + +### Metric: `container.cpu.time` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `container.cpu.time` | Counter | `s` | Total CPU time consumed [1] | + +**[1]:** Total CPU time consumed by the specific container on all available CPU cores + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`container.cpu.state`](../attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | Opt-In | + +`container.cpu.state` 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 | +|---|---| +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | +| `system` | When CPU is used by the system (host OS) | +| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | + + +### Metric: `container.memory.usage` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `container.memory.usage` | Counter | `By` | Memory usage of the container. [1] | + +**[1]:** Memory usage of the container. + + + + + +### Metric: `container.disk.io` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `container.disk.io` | Counter | `By` | Disk bytes for the container. [1] | + +**[1]:** The total number of bytes read/written successfully (aggregated from all disks). + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | +| `system.device` | string | The device identifier | `(identifier)` | Recommended | + +`disk.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `read` | read | +| `write` | write | + + +### Metric: `container.network.io` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | +| -------- | --------------- | ----------- | -------------- | +| `container.network.io` | Counter | `By` | Network bytes for the container. [1] | + +**[1]:** The number of bytes sent/received on all network interfaces by the container. + + + +| Attribute | Type | Description | Examples | Requirement Level | +|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | +| `system.device` | string | The device identifier | `(identifier)` | Recommended | + +`network.io.direction` MUST be one of the following: + +| Value | Description | +|---|---| +| `transmit` | transmit | +| `receive` | receive | + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in diff --git a/model/metrics/container.yaml b/model/metrics/container.yaml new file mode 100644 index 0000000000..3904f168be --- /dev/null +++ b/model/metrics/container.yaml @@ -0,0 +1,53 @@ +groups: + # container.cpu.* metrics and attribute group + - id: metric.container.cpu.time + type: metric + metric_name: container.cpu.time + brief: "Total CPU time consumed" + note: > + Total CPU time consumed by the specific container on all available CPU cores + instrument: counter + unit: "s" + attributes: + - ref: container.cpu.state + brief: "The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels." + requirement_level: opt_in + + # container.memory.* metrics and attribute group + - id: metric.container.memory.usage + type: metric + metric_name: container.memory.usage + brief: "Memory usage of the container." + note: > + Memory usage of the container. + instrument: counter + unit: "By" + + # container.disk.io.* metrics and attribute group + - id: metric.container.disk.io + type: metric + metric_name: container.disk.io + brief: "Disk bytes for the container." + note: > + The total number of bytes read/written + successfully (aggregated from all disks). + instrument: counter + unit: "By" + attributes: + - ref: disk.io.direction + - ref: system.device + + # container.network.io.* metrics and attribute group + - id: metric.container.network.io + type: metric + metric_name: container.network.io + brief: "Network bytes for the container." + note: > + The number of bytes sent/received + on all network interfaces + by the container. + instrument: counter + unit: "By" + attributes: + - ref: network.io.direction + - ref: system.device diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 343c63b927..2878766b66 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -95,3 +95,18 @@ groups: brief: > Container labels, `` being the label name, the value being the label value. examples: [ 'container.label.app=nginx' ] + - id: cpu.state + brief: "The CPU state for this data point." + type: + allow_custom_values: true + members: + - id: user + value: 'user' + brief: "When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows)." + - id: system + value: 'system' + brief: "When CPU is used by the system (host OS)" + - id: kernel + value: 'kernel' + brief: "When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows)." + examples: ["user", "kernel"] From f8f1e16fecf6035f055240fceec0c6c1d741b492 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:23:16 +0100 Subject: [PATCH 396/482] [chore] Move CloudEvents attributes to the registry (#837) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/cloudevents.md | 16 +++++++++ docs/cloudevents/cloudevents-spans.md | 10 +++--- model/registry/cloudevents.yaml | 37 +++++++++++++++++++ model/trace/cloudevents.yaml | 39 +++++---------------- 8 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 docs/attributes-registry/cloudevents.md create mode 100644 model/registry/cloudevents.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 08dca47531..c363fa1bfd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -23,6 +23,7 @@ body: - area:browser - area:client - area:cloud + - area:cloudevents - area:code - area:container - area:db diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index edaa3a4a75..a14603adf1 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -16,6 +16,7 @@ body: - area:browser - area:client - area:cloud + - area:cloudevents - area:code - area:container - area:db diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 8a72b6bff2..161b9c7eeb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -25,6 +25,7 @@ body: - area:browser - area:client - area:cloud + - area:cloudevents - area:code - area:container - area:db diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 00ff6ad8e6..8b22577d09 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -31,6 +31,7 @@ Currently, the following namespaces exist: * [Browser](browser.md) * [Client](client.md) * [Cloud](cloud.md) +* [CloudEvents](cloudevents.md) * [Code](code.md) * [Container](container.md) * [DB](db.md) (database) diff --git a/docs/attributes-registry/cloudevents.md b/docs/attributes-registry/cloudevents.md new file mode 100644 index 0000000000..aba5249b29 --- /dev/null +++ b/docs/attributes-registry/cloudevents.md @@ -0,0 +1,16 @@ + + +# CloudEvents + +## CloudEvents Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | +| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | +| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | +| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | +| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | + diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 44f112fe7a..472f8aea16 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -202,11 +202,11 @@ The following attributes are applicable to creation and processing Spans. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | Required | -| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | Required | -| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | Recommended | -| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | Recommended | -| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | Recommended | +| [`cloudevents.event_id`](../attributes-registry/cloudevents.md) | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | Required | +| [`cloudevents.event_source`](../attributes-registry/cloudevents.md) | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | Required | +| [`cloudevents.event_spec_version`](../attributes-registry/cloudevents.md) | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | Recommended | +| [`cloudevents.event_subject`](../attributes-registry/cloudevents.md) | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | Recommended | +| [`cloudevents.event_type`](../attributes-registry/cloudevents.md) | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | Recommended | diff --git a/model/registry/cloudevents.yaml b/model/registry/cloudevents.yaml new file mode 100644 index 0000000000..4da702f8a8 --- /dev/null +++ b/model/registry/cloudevents.yaml @@ -0,0 +1,37 @@ +groups: + - id: registry.cloudevents + prefix: cloudevents + type: attribute_group + brief: > + This document defines attributes for CloudEvents. + attributes: + - id: event_id + type: string + stability: experimental + brief: > + The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. + examples: ['123e4567-e89b-12d3-a456-426614174000', '0001'] + - id: event_source + type: string + stability: experimental + brief: > + The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. + examples: ['https://github.com/cloudevents', '/cloudevents/spec/pull/123', 'my-service' ] + - id: event_spec_version + type: string + stability: experimental + brief: > + The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. + examples: '1.0' + - id: event_type + type: string + stability: experimental + brief: > + The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. + examples: ['com.github.pull_request.opened', 'com.example.object.deleted.v2'] + - id: event_subject + type: string + stability: experimental + brief: > + The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). + examples: 'mynewfile.jpg' diff --git a/model/trace/cloudevents.yaml b/model/trace/cloudevents.yaml index 931b082f94..604d101c17 100644 --- a/model/trace/cloudevents.yaml +++ b/model/trace/cloudevents.yaml @@ -1,41 +1,18 @@ groups: - id: cloudevents - prefix: cloudevents type: span brief: > This document defines attributes for CloudEvents. CloudEvents is a specification on how to define event data in a standard way. These attributes can be attached to spans when performing operations with CloudEvents, regardless of the protocol being used. attributes: - - id: event_id - type: string - stability: experimental + - ref: cloudevents.event_id requirement_level: required - brief: > - The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. - examples: ['123e4567-e89b-12d3-a456-426614174000', '0001'] - - id: event_source - type: string - stability: experimental + - ref: cloudevents.event_source requirement_level: required - brief: > - The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. - examples: ['https://github.com/cloudevents', '/cloudevents/spec/pull/123', 'my-service' ] - - id: event_spec_version - type: string - stability: experimental - brief: > - The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. - examples: '1.0' - - id: event_type - type: string - stability: experimental - brief: > - The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. - examples: ['com.github.pull_request.opened', 'com.example.object.deleted.v2'] - - id: event_subject - type: string - stability: experimental - brief: > - The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). - examples: 'mynewfile.jpg' + - ref: cloudevents.event_spec_version + requirement_level: recommended + - ref: cloudevents.event_type + requirement_level: recommended + - ref: cloudevents.event_subject + requirement_level: recommended From ae4005e8a13bb05eae238a325dc40e65852f6cea Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:43:32 +0100 Subject: [PATCH 397/482] Fix path of yaml files for VSCode schema auto completion (#846) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- .vscode/settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6b792056bd..ec636cc19b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,8 +10,8 @@ "MD040": false, }, "yaml.schemas": { - "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.21.0/semantic-conventions/semconv.schema.json": [ - "semantic_conventions/**/*.yaml" + "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.24.0/semantic-conventions/semconv.schema.json": [ + "model/**/*.yaml", ] }, "json.schemaDownload.enable": true From 6bbc74de661ee98ce1c9aec05c8382ea59b84198 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:40:44 +0100 Subject: [PATCH 398/482] [chore] Move Feature Flag attributes to the registry (#842) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/feature-flag.md | 19 ++++++++++++ docs/feature-flags/feature-flags-logs.md | 6 ++-- docs/feature-flags/feature-flags-spans.md | 6 ++-- model/logs/log-feature_flag.yaml | 2 +- model/registry/feature-flag.yaml | 33 +++++++++++++++++++++ model/trace/feature-flag.yaml | 31 +++---------------- 10 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 docs/attributes-registry/feature-flag.md create mode 100644 model/registry/feature-flag.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index c363fa1bfd..16b2187e26 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -34,6 +34,7 @@ body: - area:error - area:exception - area:faas + - area:feature-flag - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index a14603adf1..269d42edac 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -27,6 +27,7 @@ body: - area:error - area:exception - area:faas + - area:feature-flag - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 161b9c7eeb..8c4df4f09e 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -36,6 +36,7 @@ body: - area:error - area:exception - area:faas + - area:feature-flag - area:host - area:http - area:k8s diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 8b22577d09..187f3847ee 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -41,6 +41,7 @@ Currently, the following namespaces exist: * [Error](error.md) * [Exception](exception.md) * [FaaS](faas.md) +* [Feature Flag](feature-flag.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/feature-flag.md b/docs/attributes-registry/feature-flag.md new file mode 100644 index 0000000000..b1fcf8f872 --- /dev/null +++ b/docs/attributes-registry/feature-flag.md @@ -0,0 +1,19 @@ +# Feature Flag + +## Feature Flag Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | +| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | +| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | + +**[1]:** A semantic identifier, commonly referred to as a variant, provides a means +for referring to a value without including the value itself. This can +provide additional context for understanding the meaning behind a value. +For example, the variant `red` maybe be used for the value `#c05543`. + +A stringified version of the value can be used in situations where a +semantic identifier is unavailable. String representation of the value +should be determined by the implementer. + diff --git a/docs/feature-flags/feature-flags-logs.md b/docs/feature-flags/feature-flags-logs.md index 200229fab7..e86df3b2f3 100644 --- a/docs/feature-flags/feature-flags-logs.md +++ b/docs/feature-flags/feature-flags-logs.md @@ -42,9 +42,9 @@ The event name MUST be `feature_flag`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| [`feature_flag.key`](feature-flags-spans.md) | string | The unique identifier of the feature flag. | `logo-color` | Required | -| [`feature_flag.provider_name`](feature-flags-spans.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | -| [`feature_flag.variant`](feature-flags-spans.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | +| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | Recommended | +| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | +| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/feature-flags/feature-flags-spans.md b/docs/feature-flags/feature-flags-spans.md index bdd94a0106..da0fa1cc1f 100644 --- a/docs/feature-flags/feature-flags-spans.md +++ b/docs/feature-flags/feature-flags-spans.md @@ -46,9 +46,9 @@ The event name MUST be `feature_flag`. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | Required | -| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | -| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | +| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | Required | +| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | +| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/model/logs/log-feature_flag.yaml b/model/logs/log-feature_flag.yaml index 6d902423f5..4530096de7 100644 --- a/model/logs/log-feature_flag.yaml +++ b/model/logs/log-feature_flag.yaml @@ -1,7 +1,7 @@ groups: - id: log-feature_flag type: event - prefix: feature_flag + name: feature_flag brief: > This document defines attributes for feature flag evaluations represented using Log Records. diff --git a/model/registry/feature-flag.yaml b/model/registry/feature-flag.yaml new file mode 100644 index 0000000000..9de106ffc8 --- /dev/null +++ b/model/registry/feature-flag.yaml @@ -0,0 +1,33 @@ +groups: + - id: registry.feature_flag + prefix: feature_flag + type: attribute_group + brief: > + This document defines attributes for Feature Flags. + attributes: + - id: key + type: string + stability: experimental + brief: The unique identifier of the feature flag. + examples: ["logo-color"] + - id: provider_name + type: string + stability: experimental + brief: The name of the service provider that performs the flag evaluation. + examples: ["Flag Manager"] + - id: variant + type: string + stability: experimental + examples: ["red", "true", "on"] + brief: > + SHOULD be a semantic identifier for a value. If one is unavailable, a + stringified version of the value can be used. + note: |- + A semantic identifier, commonly referred to as a variant, provides a means + for referring to a value without including the value itself. This can + provide additional context for understanding the meaning behind a value. + For example, the variant `red` maybe be used for the value `#c05543`. + + A stringified version of the value can be used in situations where a + semantic identifier is unavailable. String representation of the value + should be determined by the implementer. diff --git a/model/trace/feature-flag.yaml b/model/trace/feature-flag.yaml index b6bc1ba1dc..8aae493385 100644 --- a/model/trace/feature-flag.yaml +++ b/model/trace/feature-flag.yaml @@ -1,37 +1,14 @@ groups: - id: feature_flag - prefix: feature_flag type: event + name: feature_flag brief: > This semantic convention defines the attributes used to represent a feature flag evaluation as an event. attributes: - - id: key - type: string - stability: experimental + - ref: feature_flag.key requirement_level: required - brief: The unique identifier of the feature flag. - examples: ["logo-color"] - - id: provider_name - type: string - stability: experimental + - ref: feature_flag.provider_name requirement_level: recommended - brief: The name of the service provider that performs the flag evaluation. - examples: ["Flag Manager"] - - id: variant - type: string - stability: experimental + - ref: feature_flag.variant requirement_level: recommended - examples: ["red", "true", "on"] - brief: > - SHOULD be a semantic identifier for a value. If one is unavailable, a - stringified version of the value can be used. - note: |- - A semantic identifier, commonly referred to as a variant, provides a means - for referring to a value without including the value itself. This can - provide additional context for understanding the meaning behind a value. - For example, the variant `red` maybe be used for the value `#c05543`. - - A stringified version of the value can be used in situations where a - semantic identifier is unavailable. String representation of the value - should be determined by the implementer. From 3adaac281c21480c53dfa00db4eb7bbbbe835599 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:48:13 +0100 Subject: [PATCH 399/482] [chore] Move end user attributes to the registry (#844) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/enduser.md | 10 +++++++ docs/general/attributes.md | 6 ++--- model/general.yaml | 29 +++++---------------- model/registry/enduser.yaml | 29 +++++++++++++++++++++ 8 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 docs/attributes-registry/enduser.md create mode 100644 model/registry/enduser.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 16b2187e26..4c7e81a5d0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -31,6 +31,7 @@ body: - area:device - area:disk - area:dns + - area:enduser - area:error - area:exception - area:faas diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 269d42edac..c2c40ec74a 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -24,6 +24,7 @@ body: - area:device - area:disk - area:dns + - area:enduser - area:error - area:exception - area:faas diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 8c4df4f09e..311ee512cb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -33,6 +33,7 @@ body: - area:device - area:disk - area:dns + - area:enduser - area:error - area:exception - area:faas diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 187f3847ee..a1fb7a30fe 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -38,6 +38,7 @@ Currently, the following namespaces exist: * [Destination](destination.md) * [Device](device.md) * [Disk](disk.md) +* [End user](enduser.md) * [Error](error.md) * [Exception](exception.md) * [FaaS](faas.md) diff --git a/docs/attributes-registry/enduser.md b/docs/attributes-registry/enduser.md new file mode 100644 index 0000000000..f8be2f3699 --- /dev/null +++ b/docs/attributes-registry/enduser.md @@ -0,0 +1,10 @@ +# End User + +## End User Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | +| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | +| `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | + diff --git a/docs/general/attributes.md b/docs/general/attributes.md index d809f56add..9a74f6807f 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -311,9 +311,9 @@ These attributes may be used for any operation with an authenticated and/or auth | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | Recommended | -| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | Recommended | -| `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | Recommended | +| [`enduser.id`](../attributes-registry/enduser.md) | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | Recommended | +| [`enduser.role`](../attributes-registry/enduser.md) | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | Recommended | +| [`enduser.scope`](../attributes-registry/enduser.md) | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | Recommended | These attributes describe the authenticated user driving the user agent making requests to the instrumented diff --git a/model/general.yaml b/model/general.yaml index ec38d6e8dd..23ec6cd32e 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -41,33 +41,16 @@ groups: resource attribute of the remote service if any. examples: "AuthTokenCache" - id: identity - prefix: enduser type: span brief: > These attributes may be used for any operation with an authenticated and/or authorized enduser. attributes: - - id: id - type: string - stability: experimental - brief: > - Username or client_id extracted from the access token or - [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) - header in the inbound request from outside the system. - examples: 'username' - - id: role - type: string - stability: experimental - brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' - examples: 'admin' - - id: scope - type: string - stability: experimental - brief: > - Scopes or granted authorities the client currently possesses extracted from token - or application security context. The value would come from the scope associated - with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) - or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). - examples: 'read:message, write:files' + - ref: enduser.id + requirement_level: recommended + - ref: enduser.role + requirement_level: recommended + - ref: enduser.scope + requirement_level: recommended - id: thread type: span brief: > diff --git a/model/registry/enduser.yaml b/model/registry/enduser.yaml new file mode 100644 index 0000000000..656f36d682 --- /dev/null +++ b/model/registry/enduser.yaml @@ -0,0 +1,29 @@ +groups: + - id: registry.enduser + prefix: enduser + type: attribute_group + brief: > + This document defines attributes for operations with an authenticated and/or authorized enduser. + attributes: + - id: id + type: string + stability: experimental + brief: > + Username or client_id extracted from the access token or + [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) + header in the inbound request from outside the system. + examples: 'username' + - id: role + type: string + stability: experimental + brief: 'Actual/assumed role the client is making the request under extracted from token or application security context.' + examples: 'admin' + - id: scope + type: string + stability: experimental + brief: > + Scopes or granted authorities the client currently possesses extracted from token + or application security context. The value would come from the scope associated + with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) + or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + examples: 'read:message, write:files' From a187625b51dd8f4b0f8ecff2461f65cba0f27e5a Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:55:19 +0100 Subject: [PATCH 400/482] [chore] Move deployment attributes to the registry (#845) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/deployment.md | 16 +++++++++++++++ docs/resource/deployment-environment.md | 2 +- model/registry/deployment.yaml | 22 +++++++++++++++++++++ model/resource/deployment_environment.yaml | 18 ++--------------- 8 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 docs/attributes-registry/deployment.md create mode 100644 model/registry/deployment.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4c7e81a5d0..30d6a421f7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -27,6 +27,7 @@ body: - area:code - area:container - area:db + - area:deployment - area:destination - area:device - area:disk diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index c2c40ec74a..d47978fd71 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -20,6 +20,7 @@ body: - area:code - area:container - area:db + - area:deployment - area:destination - area:device - area:disk diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 311ee512cb..deef5d5aa1 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -29,6 +29,7 @@ body: - area:code - area:container - area:db + - area:deployment - area:destination - area:device - area:disk diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index a1fb7a30fe..eddd116a5c 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -35,6 +35,7 @@ Currently, the following namespaces exist: * [Code](code.md) * [Container](container.md) * [DB](db.md) (database) +* [Deployment](deployment.md) * [Destination](destination.md) * [Device](device.md) * [Disk](disk.md) diff --git a/docs/attributes-registry/deployment.md b/docs/attributes-registry/deployment.md new file mode 100644 index 0000000000..7e4ad484ed --- /dev/null +++ b/docs/attributes-registry/deployment.md @@ -0,0 +1,16 @@ +# Deployment + +## Deployment Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | + +**[1]:** `deployment.environment` does not affect the uniqueness constraints defined through +the `service.namespace`, `service.name` and `service.instance.id` resource attributes. +This implies that resources carrying the following attribute combinations MUST be +considered to be identifying the same service: + +* `service.name=frontend`, `deployment.environment=production` +* `service.name=frontend`, `deployment.environment=staging`. + diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index faba4a47d9..12301f3ae5 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | Recommended | +| [`deployment.environment`](../attributes-registry/deployment.md) | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | Recommended | **[1]:** `deployment.environment` does not affect the uniqueness constraints defined through the `service.namespace`, `service.name` and `service.instance.id` resource attributes. diff --git a/model/registry/deployment.yaml b/model/registry/deployment.yaml new file mode 100644 index 0000000000..ffc0050eab --- /dev/null +++ b/model/registry/deployment.yaml @@ -0,0 +1,22 @@ +groups: + - id: registry.deployment + prefix: deployment + type: attribute_group + brief: > + This document defines attributes for software deployments. + attributes: + - id: environment + type: string + stability: experimental + brief: > + Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) + (aka deployment tier). + note: | + `deployment.environment` does not affect the uniqueness constraints defined through + the `service.namespace`, `service.name` and `service.instance.id` resource attributes. + This implies that resources carrying the following attribute combinations MUST be + considered to be identifying the same service: + + * `service.name=frontend`, `deployment.environment=production` + * `service.name=frontend`, `deployment.environment=staging`. + examples: ['staging', 'production'] diff --git a/model/resource/deployment_environment.yaml b/model/resource/deployment_environment.yaml index bc2574386a..c9a54bc7fa 100644 --- a/model/resource/deployment_environment.yaml +++ b/model/resource/deployment_environment.yaml @@ -1,22 +1,8 @@ groups: - id: deployment - prefix: deployment type: resource brief: > The software deployment. attributes: - - id: environment - type: string - stability: experimental - brief: > - Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) - (aka deployment tier). - note: | - `deployment.environment` does not affect the uniqueness constraints defined through - the `service.namespace`, `service.name` and `service.instance.id` resource attributes. - This implies that resources carrying the following attribute combinations MUST be - considered to be identifying the same service: - - * `service.name=frontend`, `deployment.environment=production` - * `service.name=frontend`, `deployment.environment=staging`. - examples: ['staging', 'production'] + - ref: deployment.environment + requirement_level: recommended From 2541b872367cd4ca3119fd71ee2c468e09e4a3d5 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:14:09 +0100 Subject: [PATCH 401/482] [chore] Move GCP attributes to the registry (#849) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 ++ .github/ISSUE_TEMPLATE/change_proposal.yaml | 2 ++ .github/ISSUE_TEMPLATE/new-conventions.yaml | 2 ++ docs/attributes-registry/README.md | 2 ++ docs/attributes-registry/gcp-cloud-run.md | 9 +++++++ docs/attributes-registry/gcp-gce.md | 9 +++++++ docs/resource/cloud-provider/gcp/cloud-run.md | 4 +-- docs/resource/cloud-provider/gcp/gce.md | 4 +-- model/registry/gcp-cloud-run.yaml | 25 +++++++++++++++++++ model/registry/gcp-gce.yaml | 24 ++++++++++++++++++ .../cloud_provider/gcp/cloud_run.yaml | 23 +++-------------- model/resource/cloud_provider/gcp/gce.yaml | 22 +++------------- 12 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 docs/attributes-registry/gcp-cloud-run.md create mode 100644 docs/attributes-registry/gcp-gce.md create mode 100644 model/registry/gcp-cloud-run.yaml create mode 100644 model/registry/gcp-gce.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 30d6a421f7..42e2d38a75 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -37,6 +37,8 @@ body: - area:exception - area:faas - area:feature-flag + - area:gcp-cloud-run + - area:gcp-gce - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index d47978fd71..b4ba2ee211 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -30,6 +30,8 @@ body: - area:exception - area:faas - area:feature-flag + - area:gcp-cloud-run + - area:gcp-gce - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index deef5d5aa1..a289b3b6bd 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -39,6 +39,8 @@ body: - area:exception - area:faas - area:feature-flag + - area:gcp-cloud-run + - area:gcp-gce - area:host - area:http - area:k8s diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index eddd116a5c..8d8cd7e466 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -44,6 +44,8 @@ Currently, the following namespaces exist: * [Exception](exception.md) * [FaaS](faas.md) * [Feature Flag](feature-flag.md) +* [Google Cloud Run](gcp-cloud-run.md) +* [Google Compute Engine](gcp-gce.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/gcp-cloud-run.md b/docs/attributes-registry/gcp-cloud-run.md new file mode 100644 index 0000000000..219b854ebb --- /dev/null +++ b/docs/attributes-registry/gcp-cloud-run.md @@ -0,0 +1,9 @@ +# Google Cloud Run + +## Google Cloud Run Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | +| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | + diff --git a/docs/attributes-registry/gcp-gce.md b/docs/attributes-registry/gcp-gce.md new file mode 100644 index 0000000000..da3b46486d --- /dev/null +++ b/docs/attributes-registry/gcp-gce.md @@ -0,0 +1,9 @@ +# Google Compute Engine + +## Google Compute Engine Attributes + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | +| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | + diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index d929928a9a..1f79773078 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -11,8 +11,8 @@ These conventions are recommended for resources running on Cloud Run. | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | Recommended | -| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | Recommended | +| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp-cloud-run.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | Recommended | +| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp-cloud-run.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | Recommended | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/gce.md b/docs/resource/cloud-provider/gcp/gce.md index 986ce0fbe5..4e2855ed76 100644 --- a/docs/resource/cloud-provider/gcp/gce.md +++ b/docs/resource/cloud-provider/gcp/gce.md @@ -7,6 +7,6 @@ | Attribute | Type | Description | Examples | Requirement Level | |---|---|---|---|---| -| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | Recommended | -| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | Recommended | +| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp-gce.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | Recommended | +| [`gcp.gce.instance.name`](../../../attributes-registry/gcp-gce.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | Recommended | diff --git a/model/registry/gcp-cloud-run.yaml b/model/registry/gcp-cloud-run.yaml new file mode 100644 index 0000000000..11b9481feb --- /dev/null +++ b/model/registry/gcp-cloud-run.yaml @@ -0,0 +1,25 @@ +groups: + - id: registry.gcp.cloud_run + prefix: gcp.cloud_run + type: attribute_group + brief: > + This document defines attributes for Google Cloud Run. + attributes: + - id: job.execution + type: string + stability: experimental + brief: > + The name of the Cloud Run + [execution](https://cloud.google.com/run/docs/managing/job-executions) + being run for the Job, as set by the + [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + environment variable. + examples: ['job-name-xxxx', 'sample-job-mdw84'] + - id: job.task_index + type: int + stability: experimental + brief: > + The index for a task within an execution as provided by the + [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + environment variable. + examples: [0, 1] diff --git a/model/registry/gcp-gce.yaml b/model/registry/gcp-gce.yaml new file mode 100644 index 0000000000..1ca30ee72d --- /dev/null +++ b/model/registry/gcp-gce.yaml @@ -0,0 +1,24 @@ +groups: + - id: registry.gcp.gce + prefix: gcp.gce + type: attribute_group + brief: > + This document defines attributes for Google Compute Engine (GCE). + attributes: + - id: instance.name + type: string + stability: experimental + brief: > + The instance name of a GCE instance. This is the value + provided by `host.name`, the visible name of the instance in + the Cloud Console UI, and the prefix for the default + hostname of the instance as defined by the [default internal + DNS + name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). + examples: ['instance-1', 'my-vm-name'] + - id: instance.hostname + type: string + stability: experimental + brief: > + The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). + examples: ['my-host1234.example.com', 'sample-vm.us-west1-b.c.my-project.internal'] diff --git a/model/resource/cloud_provider/gcp/cloud_run.yaml b/model/resource/cloud_provider/gcp/cloud_run.yaml index 269f4a6f84..3f05837747 100644 --- a/model/resource/cloud_provider/gcp/cloud_run.yaml +++ b/model/resource/cloud_provider/gcp/cloud_run.yaml @@ -1,25 +1,10 @@ groups: - id: gcp.cloud_run - prefix: gcp.cloud_run type: resource brief: > Resource used by Google Cloud Run. attributes: - - id: job.execution - type: string - stability: experimental - brief: > - The name of the Cloud Run - [execution](https://cloud.google.com/run/docs/managing/job-executions) - being run for the Job, as set by the - [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) - environment variable. - examples: ['job-name-xxxx', 'sample-job-mdw84'] - - id: job.task_index - type: int - stability: experimental - brief: > - The index for a task within an execution as provided by the - [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) - environment variable. - examples: [0, 1] + - ref: gcp.cloud_run.job.execution + requirement_level: recommended + - ref: gcp.cloud_run.job.task_index + requirement_level: recommended diff --git a/model/resource/cloud_provider/gcp/gce.yaml b/model/resource/cloud_provider/gcp/gce.yaml index 22b96628dc..d29684b2a3 100644 --- a/model/resource/cloud_provider/gcp/gce.yaml +++ b/model/resource/cloud_provider/gcp/gce.yaml @@ -1,24 +1,10 @@ groups: - id: gcp.gce - prefix: gcp.gce type: resource brief: > Resources used by Google Compute Engine (GCE). attributes: - - id: instance.name - type: string - stability: experimental - brief: > - The instance name of a GCE instance. This is the value - provided by `host.name`, the visible name of the instance in - the Cloud Console UI, and the prefix for the default - hostname of the instance as defined by the [default internal - DNS - name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). - examples: ['instance-1', 'my-vm-name'] - - id: instance.hostname - type: string - stability: experimental - brief: > - The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). - examples: ['my-host1234.example.com', 'sample-vm.us-west1-b.c.my-project.internal'] + - ref: gcp.gce.instance.name + requirement_level: recommended + - ref: gcp.gce.instance.hostname + requirement_level: recommended From 0e2eca51cdda5bc87c7e54fc9735cbdd2c0e2be2 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:34:17 +0100 Subject: [PATCH 402/482] [chore] propagate error up (#841) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- internal/tools/scripts/update-issue-template-areas.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tools/scripts/update-issue-template-areas.sh b/internal/tools/scripts/update-issue-template-areas.sh index 1e7c7cb276..da2f81ebcf 100755 --- a/internal/tools/scripts/update-issue-template-areas.sh +++ b/internal/tools/scripts/update-issue-template-areas.sh @@ -37,7 +37,7 @@ echo -e "The replacement text will be:" echo -e "---------------------------------------------\n" echo -e $replacement -find ${TEMPLATES_DIR} -type f -name '*.yaml' -exec sed -i "/$START_AREA_LIST/,/$END_AREA_LIST/c\\$replacement" {} \; +find ${TEMPLATES_DIR} -type f -name '*.yaml' -print0 | xargs -0 sed -i "/$START_AREA_LIST/,/$END_AREA_LIST/c\\$replacement" echo -e "\nISSUE_TEMPLATES updated successfully" echo -e "---------------------------------------------" From 5a94098c2a80417f4d5bde58ed470314290ed7da Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:59:43 +0100 Subject: [PATCH 403/482] add new ECS file namespace (#732) Co-authored-by: Alexander Wert --- .chloggen/file.yaml | 22 ++++++++++++++ .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/file.md | 18 +++++++++++ model/registry/file.yaml | 33 +++++++++++++++++++++ 7 files changed, 77 insertions(+) create mode 100755 .chloggen/file.yaml create mode 100644 docs/attributes-registry/file.md create mode 100644 model/registry/file.yaml diff --git a/.chloggen/file.yaml b/.chloggen/file.yaml new file mode 100755 index 0000000000..20bcdca15b --- /dev/null +++ b/.chloggen/file.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: new_component + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: file + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add new file namespace + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [732] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 42e2d38a75..de2be6b191 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -37,6 +37,7 @@ body: - area:exception - area:faas - area:feature-flag + - area:file - area:gcp-cloud-run - area:gcp-gce - area:host diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index b4ba2ee211..5b1f182e55 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -30,6 +30,7 @@ body: - area:exception - area:faas - area:feature-flag + - area:file - area:gcp-cloud-run - area:gcp-gce - area:host diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index a289b3b6bd..da5ba98845 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -39,6 +39,7 @@ body: - area:exception - area:faas - area:feature-flag + - area:file - area:gcp-cloud-run - area:gcp-gce - area:host diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 8d8cd7e466..07c0d1754a 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -44,6 +44,7 @@ Currently, the following namespaces exist: * [Exception](exception.md) * [FaaS](faas.md) * [Feature Flag](feature-flag.md) +* [File](file.md) * [Google Cloud Run](gcp-cloud-run.md) * [Google Compute Engine](gcp-gce.md) * [Host](host.md) diff --git a/docs/attributes-registry/file.md b/docs/attributes-registry/file.md new file mode 100644 index 0000000000..1848908a45 --- /dev/null +++ b/docs/attributes-registry/file.md @@ -0,0 +1,18 @@ + + +# File + +## File Attributes + + +| Attribute | Type | Description | Examples | +|---|---|---|---| +| `file.directory` | string | Directory where the file is located. It should include the drive letter, when appropriate. | `/home/user`; `C:\Program Files\MyApp` | +| `file.extension` | string | File extension, excluding the leading dot. [1] | `png`; `gz` | +| `file.name` | string | Name of the file including the extension, without the directory. | `example.png` | +| `file.path` | string | Full path to the file, including the file name. It should include the drive letter, when appropriate. | `/home/alice/example.png`; `C:\Program Files\MyApp\myapp.exe` | +| `file.size` | int | File size in bytes. | | + +**[1]:** When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). + diff --git a/model/registry/file.yaml b/model/registry/file.yaml new file mode 100644 index 0000000000..6a86aa9f9b --- /dev/null +++ b/model/registry/file.yaml @@ -0,0 +1,33 @@ +groups: + - id: registry.file + prefix: file + type: attribute_group + brief: "Describes file attributes." + attributes: + - id: directory + type: string + brief: > + Directory where the file is located. It should include the drive letter, when appropriate. + examples: ['/home/user', 'C:\Program Files\MyApp'] + - id: extension + type: string + brief: > + File extension, excluding the leading dot. + examples: ['png', 'gz'] + note: > + When the file name has multiple extensions (example.tar.gz), only the last one should + be captured ("gz", not "tar.gz"). + - id: name + type: string + brief: > + Name of the file including the extension, without the directory. + examples: ['example.png'] + - id: path + type: string + brief: > + Full path to the file, including the file name. It should include the drive letter, when appropriate. + examples: ['/home/alice/example.png', 'C:\Program Files\MyApp\myapp.exe'] + - id: size + type: int + brief: > + File size in bytes. From e44693245eef815071402b88c3a44a8f7f8f24c8 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:30:54 +0100 Subject: [PATCH 404/482] [chore] Force create labels in workflow (#852) --- .github/workflows/scripts/generate-registry-area-labels.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scripts/generate-registry-area-labels.sh b/.github/workflows/scripts/generate-registry-area-labels.sh index e06082e982..3a2af777e6 100755 --- a/.github/workflows/scripts/generate-registry-area-labels.sh +++ b/.github/workflows/scripts/generate-registry-area-labels.sh @@ -25,7 +25,7 @@ for AREA in ${AREAS}; do continue fi echo "area:${LABEL_NAME}" - gh label create "area:${LABEL_NAME}" -c "#425cc7" + gh label create "area:${LABEL_NAME}" -c "#425cc7" --force done echo -e "\nLabels created successfully" From a04a1f4ba413d0a1f137c223fc243ea14fdcd89b Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 28 Mar 2024 13:05:32 -0700 Subject: [PATCH 405/482] Update build-tools to 0.24.0 (#820) --- .chloggen/820.yaml | 4 + CONTRIBUTING.md | 2 +- Makefile | 6 +- docs/attributes-registry/android.md | 6 +- docs/attributes-registry/browser.md | 12 +- docs/attributes-registry/client.md | 8 +- docs/attributes-registry/cloud.md | 98 +- docs/attributes-registry/cloudevents.md | 14 +- docs/attributes-registry/code.md | 16 +- docs/attributes-registry/container.md | 40 +- docs/attributes-registry/db.md | 292 +++--- docs/attributes-registry/deployment.md | 6 +- docs/attributes-registry/destination.md | 8 +- docs/attributes-registry/device.md | 12 +- docs/attributes-registry/disk.md | 14 +- docs/attributes-registry/dns.md | 6 +- docs/attributes-registry/enduser.md | 10 +- docs/attributes-registry/error.md | 14 +- docs/attributes-registry/exception.md | 12 +- docs/attributes-registry/faas.md | 78 +- docs/attributes-registry/feature-flag.md | 10 +- docs/attributes-registry/file.md | 14 +- docs/attributes-registry/gcp-cloud-run.md | 8 +- docs/attributes-registry/gcp-gce.md | 8 +- docs/attributes-registry/host.md | 58 +- docs/attributes-registry/http.md | 114 +-- docs/attributes-registry/k8s.md | 50 +- docs/attributes-registry/messaging.md | 194 ++-- docs/attributes-registry/network.md | 202 ++--- docs/attributes-registry/oci.md | 6 +- docs/attributes-registry/os.md | 42 +- docs/attributes-registry/process.md | 26 +- docs/attributes-registry/rpc.md | 124 +-- docs/attributes-registry/server.md | 8 +- docs/attributes-registry/source.md | 8 +- docs/attributes-registry/thread.md | 8 +- docs/attributes-registry/tls.md | 72 +- docs/attributes-registry/url.md | 28 +- docs/attributes-registry/user-agent.md | 10 +- docs/cloud-providers/aws-sdk.md | 12 +- docs/cloudevents/cloudevents-spans.md | 14 +- docs/database/cassandra.md | 58 +- docs/database/cosmosdb.md | 70 +- docs/database/couchdb.md | 6 +- docs/database/database-metrics.md | 118 +-- docs/database/database-spans.md | 152 ++-- docs/database/dynamodb.md | 172 ++-- docs/database/elasticsearch.md | 92 +- docs/database/hbase.md | 6 +- docs/database/mongodb.md | 6 +- docs/database/mssql.md | 8 +- docs/database/redis.md | 12 +- docs/database/sql.md | 6 +- docs/dns/dns-metrics.md | 24 +- docs/dotnet/dotnet-aspnetcore-metrics.md | 160 ++-- docs/dotnet/dotnet-kestrel-metrics.md | 368 ++++---- docs/dotnet/dotnet-signalr-metrics.md | 72 +- docs/exceptions/exceptions-logs.md | 10 +- docs/exceptions/exceptions-spans.md | 12 +- docs/faas/aws-lambda.md | 6 +- docs/faas/faas-metrics.md | 234 ++--- docs/faas/faas-spans.md | 94 +- docs/feature-flags/feature-flags-logs.md | 10 +- docs/feature-flags/feature-flags-spans.md | 10 +- docs/general/attributes.md | 204 ++--- docs/general/events.md | 6 +- docs/general/logs.md | 32 +- docs/general/session.md | 8 +- docs/general/trace-compatibility.md | 14 +- docs/graphql/graphql-spans.md | 20 +- docs/http/http-metrics.md | 856 +++++++++--------- docs/http/http-spans.md | 230 ++--- docs/messaging/azure-messaging.md | 22 +- docs/messaging/gcp-pubsub.md | 7 +- docs/messaging/kafka.md | 19 +- docs/messaging/messaging-metrics.md | 92 +- docs/messaging/messaging-spans.md | 142 +-- docs/messaging/rabbitmq.md | 13 +- docs/messaging/rocketmq.md | 43 +- docs/mobile/events.md | 36 +- docs/object-stores/s3.md | 16 +- docs/resource/README.md | 66 +- docs/resource/android.md | 6 +- docs/resource/browser.md | 14 +- docs/resource/cloud-provider/aws/ecs.md | 26 +- docs/resource/cloud-provider/aws/eks.md | 6 +- docs/resource/cloud-provider/aws/logs.md | 12 +- docs/resource/cloud-provider/gcp/cloud-run.md | 8 +- docs/resource/cloud-provider/gcp/gce.md | 8 +- docs/resource/cloud-provider/heroku.md | 10 +- docs/resource/cloud.md | 98 +- docs/resource/container.md | 40 +- docs/resource/deployment-environment.md | 6 +- docs/resource/device.md | 12 +- docs/resource/faas.md | 56 +- docs/resource/host.md | 62 +- docs/resource/k8s.md | 90 +- docs/resource/os.md | 46 +- docs/resource/process.md | 30 +- docs/resource/webengine.md | 10 +- docs/rpc/connect-rpc.md | 46 +- docs/rpc/grpc.md | 48 +- docs/rpc/json-rpc.md | 14 +- docs/rpc/rpc-metrics.md | 118 +-- docs/rpc/rpc-spans.md | 124 +-- docs/runtime/jvm-metrics.md | 238 ++--- docs/system/container-metrics.md | 74 +- docs/system/process-metrics.md | 156 ++-- docs/system/system-metrics.md | 624 ++++++------- docs/url/url.md | 14 +- internal/tools/schema_check.sh | 2 +- model/README.md | 6 +- model/logs/media.yaml | 2 + model/logs/mobile-events.yaml | 8 + model/metrics/container.yaml | 4 + model/metrics/database-metrics.yaml | 2 + model/metrics/dotnet/dotnet-aspnetcore.yaml | 10 + model/metrics/dotnet/dotnet-kestrel.yaml | 2 - model/metrics/dotnet/dotnet-signalr.yaml | 6 + model/metrics/jvm-metrics.yaml | 8 + model/metrics/process-metrics.yaml | 7 + model/metrics/system-metrics.yaml | 43 + model/registry/cloud.yaml | 35 + model/registry/container.yaml | 4 + model/registry/db.yaml | 80 ++ model/registry/deprecated/container.yaml | 1 + model/registry/deprecated/db.yaml | 3 + model/registry/deprecated/http.yaml | 15 + model/registry/deprecated/k8s.yaml | 1 + model/registry/deprecated/messaging.yaml | 1 + model/registry/deprecated/network.yaml | 21 + model/registry/deprecated/system.yaml | 5 + model/registry/disk.yaml | 2 + model/registry/error.yaml | 1 + model/registry/faas.yaml | 13 + model/registry/file.yaml | 5 + model/registry/host.yaml | 8 + model/registry/http.yaml | 12 + model/registry/messaging.yaml | 25 + model/registry/network.yaml | 34 + model/registry/os.yaml | 11 + model/registry/rpc.yaml | 38 + model/registry/tls.yaml | 2 + model/resource/cloud_provider/aws/ecs.yaml | 2 + model/resource/telemetry.yaml | 12 + model/scope/exporter/exporter.yaml | 2 + model/trace/compatibility.yaml | 2 + model/trace/exporter/exporter.yaml | 2 + model/trace/instrumentation/graphql.yml | 3 + model/trace/rpc.yaml | 2 + 150 files changed, 4031 insertions(+), 3613 deletions(-) create mode 100644 .chloggen/820.yaml diff --git a/.chloggen/820.yaml b/.chloggen/820.yaml new file mode 100644 index 0000000000..85ac249f44 --- /dev/null +++ b/.chloggen/820.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: other +note: Update build-tools version to 0.24.0 and make semantic conventions compatible with this version (add stability on enum members and deprecated attributes). +issues: [ 807 ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8e5b78e834..bc9b273e9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,7 +82,7 @@ environment configured: ### 1. Modify the YAML model Refer to the -[Semantic Convention YAML Language](https://github.com/open-telemetry/build-tools/blob/v0.23.0/semantic-conventions/syntax.md) +[Semantic Convention YAML Language](https://github.com/open-telemetry/build-tools/blob/v0.24.0/semantic-conventions/syntax.md) to learn how to make changes to the YAML files. #### Schema files diff --git a/Makefile b/Makefile index 283402f5c0..dedc29b494 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ CHLOGGEN_CONFIG := .chloggen/config.yaml # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! -SEMCONVGEN_VERSION=0.23.0 +SEMCONVGEN_VERSION=0.24.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all @@ -95,13 +95,13 @@ yamllint: .PHONY: table-generation table-generation: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-use-badges --md-stable + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown # Check if current markdown tables differ from the ones that would be generated from YAML definitions .PHONY: table-check table-check: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check --md-use-badges --md-stable + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec .PHONY: schema-check schema-check: diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index e8539f2b73..65072ef1aa 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -2,7 +2,7 @@ ## Android Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/browser.md b/docs/attributes-registry/browser.md index 84366ea986..fd51f5bf79 100644 --- a/docs/attributes-registry/browser.md +++ b/docs/attributes-registry/browser.md @@ -6,12 +6,12 @@ ## Browser Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | -| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | -| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | -| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). diff --git a/docs/attributes-registry/client.md b/docs/attributes-registry/client.md index 9ed3875a83..e5ad30b661 100644 --- a/docs/attributes-registry/client.md +++ b/docs/attributes-registry/client.md @@ -12,10 +12,10 @@ protocol / API does not expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `client.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| `client.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Client port number. [2] | `65123` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `client.address` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `client.port` | int | Client port number. [2] | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/attributes-registry/cloud.md b/docs/attributes-registry/cloud.md index 1931f5a878..76176b3c93 100644 --- a/docs/attributes-registry/cloud.md +++ b/docs/attributes-registry/cloud.md @@ -6,14 +6,14 @@ ## Cloud Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | -| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | -| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | -| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | -| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | -| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. @@ -39,48 +39,48 @@ The following well-known definitions MUST be used if you set this attribute and This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. -`cloud.platform` 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. +`cloud.platform` 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 | -|---|---| -| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | -| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | -| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | -| `aws_ec2` | AWS Elastic Compute Cloud | -| `aws_ecs` | AWS Elastic Container Service | -| `aws_eks` | AWS Elastic Kubernetes Service | -| `aws_lambda` | AWS Lambda | -| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | -| `aws_app_runner` | AWS App Runner | -| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | -| `azure_vm` | Azure Virtual Machines | -| `azure_container_apps` | Azure Container Apps | -| `azure_container_instances` | Azure Container Instances | -| `azure_aks` | Azure Kubernetes Service | -| `azure_functions` | Azure Functions | -| `azure_app_service` | Azure App Service | -| `azure_openshift` | Azure Red Hat OpenShift | -| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | -| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | -| `gcp_cloud_run` | Google Cloud Run | -| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | -| `gcp_cloud_functions` | Google Cloud Functions (GCF) | -| `gcp_app_engine` | Google Cloud App Engine (GAE) | -| `gcp_openshift` | Red Hat OpenShift on Google Cloud | -| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | -| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | -| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | -| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ec2` | AWS Elastic Compute Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ecs` | AWS Elastic Container Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_eks` | AWS Elastic Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_lambda` | AWS Lambda | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_app_runner` | AWS App Runner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_vm` | Azure Virtual Machines | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_apps` | Azure Container Apps | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_instances` | Azure Container Instances | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_aks` | Azure Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_functions` | Azure Functions | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_app_service` | Azure App Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_openshift` | Azure Red Hat OpenShift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_run` | Google Cloud Run | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_functions` | Google Cloud Functions (GCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_app_engine` | Google Cloud App Engine (GAE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_openshift` | Red Hat OpenShift on Google Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`cloud.provider` 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. +`cloud.provider` 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 | -|---|---| -| `alibaba_cloud` | Alibaba Cloud | -| `aws` | Amazon Web Services | -| `azure` | Microsoft Azure | -| `gcp` | Google Cloud Platform | -| `heroku` | Heroku Platform as a Service | -| `ibm_cloud` | IBM Cloud | -| `tencent_cloud` | Tencent Cloud | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku` | Heroku Platform as a Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud` | IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/cloudevents.md b/docs/attributes-registry/cloudevents.md index aba5249b29..f7a7204310 100644 --- a/docs/attributes-registry/cloudevents.md +++ b/docs/attributes-registry/cloudevents.md @@ -6,11 +6,11 @@ ## CloudEvents Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | -| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | -| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | -| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | -| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/code.md b/docs/attributes-registry/code.md index 651caa99f5..de298c4526 100644 --- a/docs/attributes-registry/code.md +++ b/docs/attributes-registry/code.md @@ -8,12 +8,12 @@ These attributes allow to report this unit of code and therefore to provide more ## Code Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | -| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | -| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | -| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | -| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | -| `code.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index 4e6ec20847..b8b37373c6 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -6,20 +6,20 @@ ## Container Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | -| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | -| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | -| `container.cpu.state` | string | The CPU state for this data point. | `user`; `kernel` | -| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | -| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | -| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | -| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | -| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | -| `container.label.` | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | -| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | -| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.cpu.state` | string | The CPU state for this data point. | `user`; `kernel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.label.` | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. @@ -29,11 +29,11 @@ The ID is assinged by the container runtime and can vary in different environmen **[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. -`container.cpu.state` 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. +`container.cpu.state` 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 | -|---|---| -| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | -| `system` | When CPU is used by the system (host OS) | -| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | +| Value | Description | Stability | +|---|---|---| +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 0c39de22e2..63824a6024 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -21,158 +21,158 @@ ## Generic Database Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | -| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | -| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | -| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). **[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. -`db.system` 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 | -|---|---| -| `other_sql` | Some other SQL database. Fallback only. See notes. | -| `mssql` | Microsoft SQL Server | -| `mssqlcompact` | Microsoft SQL Server Compact | -| `mysql` | MySQL | -| `oracle` | Oracle Database | -| `db2` | IBM Db2 | -| `postgresql` | PostgreSQL | -| `redshift` | Amazon Redshift | -| `hive` | Apache Hive | -| `cloudscape` | Cloudscape | -| `hsqldb` | HyperSQL DataBase | -| `progress` | Progress Database | -| `maxdb` | SAP MaxDB | -| `hanadb` | SAP HANA | -| `ingres` | Ingres | -| `firstsql` | FirstSQL | -| `edb` | EnterpriseDB | -| `cache` | InterSystems Caché | -| `adabas` | Adabas (Adaptable Database System) | -| `firebird` | Firebird | -| `derby` | Apache Derby | -| `filemaker` | FileMaker | -| `informix` | Informix | -| `instantdb` | InstantDB | -| `interbase` | InterBase | -| `mariadb` | MariaDB | -| `netezza` | Netezza | -| `pervasive` | Pervasive PSQL | -| `pointbase` | PointBase | -| `sqlite` | SQLite | -| `sybase` | Sybase | -| `teradata` | Teradata | -| `vertica` | Vertica | -| `h2` | H2 | -| `coldfusion` | ColdFusion IMQ | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | -| `cosmosdb` | Microsoft Azure Cosmos DB | -| `dynamodb` | Amazon DynamoDB | -| `neo4j` | Neo4j | -| `geode` | Apache Geode | -| `elasticsearch` | Elasticsearch | -| `memcached` | Memcached | -| `cockroachdb` | CockroachDB | -| `opensearch` | OpenSearch | -| `clickhouse` | ClickHouse | -| `spanner` | Cloud Spanner | -| `trino` | Trino | +`db.system` 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 | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Cassandra Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | -| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | -| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | -| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | -| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | -| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | -| `db.cassandra.table` | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.table` | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. `db.cassandra.consistency_level` MUST be one of the following: -| Value | Description | -|---|---| -| `all` | all | -| `each_quorum` | each_quorum | -| `quorum` | quorum | -| `local_quorum` | local_quorum | -| `one` | one | -| `two` | two | -| `three` | three | -| `local_one` | local_one | -| `any` | any | -| `serial` | serial | -| `local_serial` | local_serial | +| Value | Description | Stability | +|---|---|---| +| `all` | all | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `each_quorum` | each_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `quorum` | quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_quorum` | local_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `one` | one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `two` | two | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `three` | three | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_one` | local_one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `any` | any | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `serial` | serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_serial` | local_serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## CosmosDB Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | -| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | -| `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | -| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | -| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | -| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | -| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | -| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `db.cosmosdb.connection_mode` MUST be one of the following: -| Value | Description | -|---|---| -| `gateway` | Gateway (HTTP) connections mode | -| `direct` | Direct connection. | - -`db.cosmosdb.operation_type` 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 | -|---|---| -| `Invalid` | invalid | -| `Create` | create | -| `Patch` | patch | -| `Read` | read | -| `ReadFeed` | read_feed | -| `Delete` | delete | -| `Replace` | replace | -| `Execute` | execute | -| `Query` | query | -| `Head` | head | -| `HeadFeed` | head_feed | -| `Upsert` | upsert | -| `Batch` | batch | -| `QueryPlan` | query_plan | -| `ExecuteJavaScript` | execute_javascript | +| Value | Description | Stability | +|---|---|---| +| `gateway` | Gateway (HTTP) connections mode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `direct` | Direct connection. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`db.cosmosdb.operation_type` 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 | Stability | +|---|---|---| +| `Invalid` | invalid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Create` | create | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Patch` | patch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ReadFeed` | read_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Replace` | replace | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Execute` | execute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Query` | query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Head` | head | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `HeadFeed` | head_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Upsert` | upsert | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Batch` | batch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `QueryPlan` | query_plan | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ExecuteJavaScript` | execute_javascript | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Elasticsearch Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | -| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. @@ -180,17 +180,17 @@ ## MongoDB Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.mongodb.collection` | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.mongodb.collection` | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## MSSQL Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). @@ -198,17 +198,17 @@ ## Redis Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## SQL Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. @@ -216,19 +216,19 @@ ## Deprecated DB Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | -| `db.elasticsearch.node.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `db.instance.id` instead. | `instance-0000000001` | -| `db.jdbc.driver_classname` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | +| `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | +| `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | ### Deprecated Elasticsearch Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `db.connection_string` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | -| `db.elasticsearch.node.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `db.instance.id` instead. | `instance-0000000001` | -| `db.jdbc.driver_classname` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | +| `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | +| `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | diff --git a/docs/attributes-registry/deployment.md b/docs/attributes-registry/deployment.md index 7e4ad484ed..a29d864de4 100644 --- a/docs/attributes-registry/deployment.md +++ b/docs/attributes-registry/deployment.md @@ -2,9 +2,9 @@ ## Deployment Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** `deployment.environment` does not affect the uniqueness constraints defined through the `service.namespace`, `service.name` and `service.instance.id` resource attributes. diff --git a/docs/attributes-registry/destination.md b/docs/attributes-registry/destination.md index db83cb53b0..1e5d7339d5 100644 --- a/docs/attributes-registry/destination.md +++ b/docs/attributes-registry/destination.md @@ -12,10 +12,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t "user-facing" surface of the protocol / API does not expose a clear notion of client and server. -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| `destination.port` | int | Destination port number | `3389`; `2888` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `destination.port` | int | Destination port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/attributes-registry/device.md b/docs/attributes-registry/device.md index 3c1f06c4ea..c52d23f5fa 100644 --- a/docs/attributes-registry/device.md +++ b/docs/attributes-registry/device.md @@ -6,12 +6,12 @@ ## Device Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | -| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | -| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | -| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. diff --git a/docs/attributes-registry/disk.md b/docs/attributes-registry/disk.md index a983873365..b52b79af0f 100644 --- a/docs/attributes-registry/disk.md +++ b/docs/attributes-registry/disk.md @@ -6,14 +6,14 @@ ## Disk Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `disk.io.direction` | string | The disk IO operation direction. | `read` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/dns.md b/docs/attributes-registry/dns.md index eeb6e10d5e..59079ab01e 100644 --- a/docs/attributes-registry/dns.md +++ b/docs/attributes-registry/dns.md @@ -6,9 +6,9 @@ ## DNS Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. \ No newline at end of file diff --git a/docs/attributes-registry/enduser.md b/docs/attributes-registry/enduser.md index f8be2f3699..616c7f89ad 100644 --- a/docs/attributes-registry/enduser.md +++ b/docs/attributes-registry/enduser.md @@ -2,9 +2,9 @@ ## End User Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | -| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | -| `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/error.md b/docs/attributes-registry/error.md index 21e0d2c67d..1b43a77600 100644 --- a/docs/attributes-registry/error.md +++ b/docs/attributes-registry/error.md @@ -6,9 +6,9 @@ ## Error Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `error.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -26,9 +26,9 @@ it's RECOMMENDED to: * Use a domain-specific attribute * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -`error.type` 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. +`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | \ No newline at end of file diff --git a/docs/attributes-registry/exception.md b/docs/attributes-registry/exception.md index e5d541c930..22f4bfc5c6 100644 --- a/docs/attributes-registry/exception.md +++ b/docs/attributes-registry/exception.md @@ -6,12 +6,12 @@ ## Exception Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `exception.escaped` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | -| `exception.message` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | -| `exception.stacktrace` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | -| `exception.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". diff --git a/docs/attributes-registry/faas.md b/docs/attributes-registry/faas.md index 4f8f5e4ea8..ec0a9a61c2 100644 --- a/docs/attributes-registry/faas.md +++ b/docs/attributes-registry/faas.md @@ -7,24 +7,24 @@ linkTitle: FaaS ## FaaS Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | -| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | -| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | -| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | -| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | -| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | -| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [1] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | -| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | -| `faas.invoked_name` | string | The name of the invoked function. [2] | `my-function` | -| `faas.invoked_provider` | string | The cloud provider of the invoked function. [3] | `alibaba_cloud` | -| `faas.invoked_region` | string | The cloud region of the invoked function. [4] | `eu-central-1` | -| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [5] | `134217728` | -| `faas.name` | string | The name of the single function that this runtime instance executes. [6] | `my-function`; `myazurefunctionapp/some-function-name` | -| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | -| `faas.version` | string | The immutable version of the function being executed. [7] | `26`; `pinkfroid-00002` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [1] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_name` | string | The name of the invoked function. [2] | `my-function` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_provider` | string | The cloud provider of the invoked function. [3] | `alibaba_cloud` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_region` | string | The cloud region of the invoked function. [4] | `eu-central-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [5] | `134217728` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.name` | string | The name of the single function that this runtime instance executes. [6] | `my-function`; `myazurefunctionapp/some-function-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.version` | string | The immutable version of the function being executed. [7] | `26`; `pinkfroid-00002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** * **AWS Lambda:** Use the (full) log stream name. @@ -63,31 +63,31 @@ definition of function name MUST be used for this attribute [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). * **Azure Functions:** Not applicable. Do not set this attribute. -`faas.document.operation` 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. +`faas.document.operation` 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 | -|---|---| -| `insert` | When a new object is created. | -| `edit` | When an object is modified. | -| `delete` | When an object is deleted. | +| Value | Description | Stability | +|---|---|---| +| `insert` | When a new object is created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edit` | When an object is modified. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | When an object is deleted. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.invoked_provider` 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. +`faas.invoked_provider` 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 | -|---|---| -| `alibaba_cloud` | Alibaba Cloud | -| `aws` | Amazon Web Services | -| `azure` | Microsoft Azure | -| `gcp` | Google Cloud Platform | -| `tencent_cloud` | Tencent Cloud | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/feature-flag.md b/docs/attributes-registry/feature-flag.md index b1fcf8f872..cad407b363 100644 --- a/docs/attributes-registry/feature-flag.md +++ b/docs/attributes-registry/feature-flag.md @@ -2,11 +2,11 @@ ## Feature Flag Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | -| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | -| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/attributes-registry/file.md b/docs/attributes-registry/file.md index 1848908a45..d2d83591ca 100644 --- a/docs/attributes-registry/file.md +++ b/docs/attributes-registry/file.md @@ -6,13 +6,13 @@ ## File Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `file.directory` | string | Directory where the file is located. It should include the drive letter, when appropriate. | `/home/user`; `C:\Program Files\MyApp` | -| `file.extension` | string | File extension, excluding the leading dot. [1] | `png`; `gz` | -| `file.name` | string | Name of the file including the extension, without the directory. | `example.png` | -| `file.path` | string | Full path to the file, including the file name. It should include the drive letter, when appropriate. | `/home/alice/example.png`; `C:\Program Files\MyApp\myapp.exe` | -| `file.size` | int | File size in bytes. | | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `file.directory` | string | Directory where the file is located. It should include the drive letter, when appropriate. | `/home/user`; `C:\Program Files\MyApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.extension` | string | File extension, excluding the leading dot. [1] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.name` | string | Name of the file including the extension, without the directory. | `example.png` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.path` | string | Full path to the file, including the file name. It should include the drive letter, when appropriate. | `/home/alice/example.png`; `C:\Program Files\MyApp\myapp.exe` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.size` | int | File size in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). diff --git a/docs/attributes-registry/gcp-cloud-run.md b/docs/attributes-registry/gcp-cloud-run.md index 219b854ebb..fc754e943a 100644 --- a/docs/attributes-registry/gcp-cloud-run.md +++ b/docs/attributes-registry/gcp-cloud-run.md @@ -2,8 +2,8 @@ ## Google Cloud Run Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | -| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/gcp-gce.md b/docs/attributes-registry/gcp-gce.md index da3b46486d..d6735be23e 100644 --- a/docs/attributes-registry/gcp-gce.md +++ b/docs/attributes-registry/gcp-gce.md @@ -2,8 +2,8 @@ ## Google Compute Engine Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | -| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/host.md b/docs/attributes-registry/host.md index a8c1de6e3f..dc571c70cd 100644 --- a/docs/attributes-registry/host.md +++ b/docs/attributes-registry/host.md @@ -6,23 +6,23 @@ ## Host Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | -| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | -| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | -| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | -| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | -| `host.cpu.stepping` | string | Stepping or core revisions. | `1`; `r1p1` | -| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | -| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | -| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | -| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | -| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | -| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [2] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | -| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [3] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | -| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | -| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.stepping` | string | Stepping or core revisions. | `1`; `r1p1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [2] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [3] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. @@ -30,16 +30,16 @@ **[3]:** MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. -`host.arch` 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 | -|---|---| -| `amd64` | AMD64 | -| `arm32` | ARM32 | -| `arm64` | ARM64 | -| `ia64` | Itanium | -| `ppc32` | 32-bit PowerPC | -| `ppc64` | 64-bit PowerPC | -| `s390x` | IBM z/Architecture | -| `x86` | 32-bit x86 | +`host.arch` 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 | Stability | +|---|---|---| +| `amd64` | AMD64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm32` | ARM32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm64` | ARM64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ia64` | Itanium | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc32` | 32-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc64` | 64-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `s390x` | IBM z/Architecture | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `x86` | 32-bit x86 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index 31fb5b6355..e25443590d 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -6,20 +6,20 @@ ## HTTP Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | -| `http.request.body.size` | 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` | -| `http.request.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | -| `http.request.method` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP request method. [2] | `GET`; `POST`; `HEAD` | -| `http.request.method_original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | -| `http.request.resend_count` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | -| `http.request.size` | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | -| `http.response.body.size` | 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` | -| `http.response.header.` | string[] | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | -| `http.response.size` | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | -| `http.response.status_code` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | -| `http.route` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.request.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.size` | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.response.size` | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. @@ -49,52 +49,52 @@ The attribute value MUST consist of either multiple header values as an array of **[5]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -`http.connection.state` 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 | -|---|---| -| `active` | active state. | -| `idle` | idle state. | - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.connection.state` 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 | Stability | +|---|---|---| +| `active` | active state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Deprecated HTTP Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `http.flavor` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.name` instead. | `1.0` | -| `http.method` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | -| `http.request_content_length` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.request.header.content-length` instead. | `3495` | -| `http.response_content_length` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.response.header.content-length` instead. | `3495` | -| `http.scheme` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.scheme` instead. | `http`; `https` | -| `http.status_code` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `http.response.status_code` instead. | `200` | -| `http.target` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | -| `http.url` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | -| `http.user_agent` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | - -`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. | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | +| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.method`. | +| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.header.content-length`. | +| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.header.content-length`. | +| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.scheme` instead. | +| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.status_code`. | +| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `url.path` and `url.query. | +| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.full`. | +| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `user_agent.original`. | + +`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 | Stability | +|---|---|---| +| `1.0` | HTTP/1.0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `1.1` | HTTP/1.1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `2.0` | HTTP/2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `3.0` | HTTP/3 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `SPDY` | SPDY protocol. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `QUIC` | QUIC protocol. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index 7c85db4516..ea7c55d6fc 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -3,31 +3,31 @@ ## Kubernetes Resource Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | -| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | -| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | -| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | -| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | -| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | -| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | -| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | -| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | -| `k8s.node.name` | string | The name of the Node. | `node-1` | -| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | -| `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | -| `k8s.pod.label.` | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | -| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | -| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | -| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | -| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | -| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.node.name` | string | The name of the Node. | `node-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.label.` | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 7e3491b8d3..3e713cdd5a 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -19,23 +19,23 @@ ## Generic Messaging Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | -| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | -| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | -| `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | -| `messaging.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | -| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | -| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | -| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | -| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | -| `messaging.message.body.size` | int | The size of the message body in bytes. [5] | `1439` | -| `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | -| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | -| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | -| `messaging.operation` | string | A string identifying the kind of messaging operation. [7] | `publish` | -| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.body.size` | int | The size of the message body in bytes. [5] | `1439` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.operation` | string | A string identifying the kind of messaging operation. [7] | `publish` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -55,49 +55,49 @@ size should be used. **[7]:** If a custom value is used, it MUST be of low cardinality. -`messaging.operation` 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 | -|---|---| -| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | -| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | -| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | -| `process` | One or more messages are delivered to or processed by a consumer. | -| `settle` | One or more messages are settled. | - -`messaging.system` 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 | -|---|---| -| `activemq` | Apache ActiveMQ | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `eventgrid` | Azure Event Grid | -| `eventhubs` | Azure Event Hubs | -| `servicebus` | Azure Service Bus | -| `gcp_pubsub` | Google Cloud Pub/Sub | -| `jms` | Java Message Service | -| `kafka` | Apache Kafka | -| `rabbitmq` | RabbitMQ | -| `rocketmq` | Apache RocketMQ | +`messaging.operation` 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 | Stability | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.system` 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 | Stability | +|---|---|---| +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## GCP Pub/Sub Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Kafka Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | -| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | -| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. @@ -105,77 +105,77 @@ size should be used. ## RabbitMQ Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | -| `messaging.rabbitmq.message.delivery_tag` | int | RabbitMQ message delivery tag | `123` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rabbitmq.message.delivery_tag` | int | RabbitMQ message delivery tag | `123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## RocketMQ Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | -| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | -| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | -| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | -| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | -| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | -| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | -| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | -| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.rocketmq.consumption_model` MUST be one of the following: -| Value | Description | -|---|---| -| `clustering` | Clustering consumption model | -| `broadcasting` | Broadcasting consumption model | +| Value | Description | Stability | +|---|---|---| +| `clustering` | Clustering consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `broadcasting` | Broadcasting consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.rocketmq.message.type` MUST be one of the following: -| Value | Description | -|---|---| -| `normal` | Normal message | -| `fifo` | FIFO message | -| `delay` | Delay message | -| `transaction` | Transaction message | +| Value | Description | Stability | +|---|---|---| +| `normal` | Normal message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fifo` | FIFO message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delay` | Delay message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `transaction` | Transaction message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Azure Event Hubs Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | -| `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Azure Service Bus Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | -| `messaging.servicebus.disposition_status` | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | -| `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | -| `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | - -`messaging.servicebus.disposition_status` 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 | -|---|---| -| `complete` | Message is completed | -| `abandon` | Message is abandoned | -| `dead_letter` | Message is sent to dead letter queue | -| `defer` | Message is deferred | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.disposition_status` | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.servicebus.disposition_status` 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 | Stability | +|---|---|---| +| `complete` | Message is completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `abandon` | Message is abandoned | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dead_letter` | Message is sent to dead letter queue | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defer` | Message is deferred | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Deprecated Messaging Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `messaging.kafka.destination.partition` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Deprecated, use `messaging.destination.partition.id` instead." | `2` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `messaging.kafka.destination.partition` | int | "Deprecated, use `messaging.destination.partition.id` instead." | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | \ No newline at end of file diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index b534c86f54..497a575c31 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -8,23 +8,23 @@ These attributes may be used for any network related operation. ## Network Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | -| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | -| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | -| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | -| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | -| `network.connection.type` | string | The internet connection type. | `wifi` | -| `network.io.direction` | string | The network IO operation direction. | `transmit` | -| `network.local.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | -| `network.local.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Local port number of the network connection. | `65123` | -| `network.peer.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | -| `network.peer.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Peer port number of the network connection. | `65123` | -| `network.protocol.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | -| `network.protocol.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [2] | `1.1`; `2` | -| `network.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | -| `network.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.connection.type` | string | The internet connection type. | `wifi` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.io.direction` | string | The network IO operation direction. | `transmit` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.local.port` | int | Local port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.peer.port` | int | Peer port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.protocol.version` | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -38,102 +38,102 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** The value SHOULD be normalized to lowercase. -`network.connection.subtype` 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 | -|---|---| -| `gprs` | GPRS | -| `edge` | EDGE | -| `umts` | UMTS | -| `cdma` | CDMA | -| `evdo_0` | EVDO Rel. 0 | -| `evdo_a` | EVDO Rev. A | -| `cdma2000_1xrtt` | CDMA2000 1XRTT | -| `hsdpa` | HSDPA | -| `hsupa` | HSUPA | -| `hspa` | HSPA | -| `iden` | IDEN | -| `evdo_b` | EVDO Rev. B | -| `lte` | LTE | -| `ehrpd` | EHRPD | -| `hspap` | HSPAP | -| `gsm` | GSM | -| `td_scdma` | TD-SCDMA | -| `iwlan` | IWLAN | -| `nr` | 5G NR (New Radio) | -| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | -| `lte_ca` | LTE CA | - -`network.connection.type` 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 | -|---|---| -| `wifi` | wifi | -| `wired` | wired | -| `cell` | cell | -| `unavailable` | unavailable | -| `unknown` | unknown | +`network.connection.subtype` 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 | Stability | +|---|---|---| +| `gprs` | GPRS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edge` | EDGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `umts` | UMTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma` | CDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_0` | EVDO Rel. 0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_a` | EVDO Rev. A | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma2000_1xrtt` | CDMA2000 1XRTT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsdpa` | HSDPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsupa` | HSUPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspa` | HSPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iden` | IDEN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_b` | EVDO Rev. B | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte` | LTE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ehrpd` | EHRPD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspap` | HSPAP | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gsm` | GSM | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `td_scdma` | TD-SCDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iwlan` | IWLAN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nr` | 5G NR (New Radio) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte_ca` | LTE CA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`network.connection.type` 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 | Stability | +|---|---|---| +| `wifi` | wifi | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `wired` | wired | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cell` | cell | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Deprecated Network Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `net.host.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address`. | `example.com` | -| `net.host.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.port`. | `8080` | -| `net.peer.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | -| `net.peer.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | -| `net.protocol.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | -| `net.protocol.version` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.protocol.version`. | `3.1.1` | -| `net.sock.family` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.transport` and `network.type`. | `inet` | -| `net.sock.host.addr` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.local.address`. | `/var/my.sock` | -| `net.sock.host.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.local.port`. | `8080` | -| `net.sock.peer.addr` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.peer.address`. | `192.168.0.1` | -| `net.sock.peer.name` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | `/var/my.sock` | -| `net.sock.peer.port` | int | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.peer.port`. | `65531` | -| `net.transport` | string | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, use `network.transport`. | `ip_tcp` | - -`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 | - -`net.transport` 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 | -|---|---| -| `ip_tcp` | ip_tcp | -| `ip_udp` | ip_udp | -| `pipe` | Named or anonymous pipe. | -| `inproc` | In-process communication. [1] | -| `other` | Something else (non IP-based). | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | +| `net.host.port` | int | Deprecated, use `server.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port`. | +| `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address` on client spans and `client.address` on server spans. | +| `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port` on client spans and `client.port` on server spans. | +| `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | +| `net.protocol.version` | string | Deprecated, use `network.protocol.version`. | `3.1.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.version`. | +| `net.sock.family` | string | Deprecated, use `network.transport` and `network.type`. | `inet` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `network.transport` and `network.type`. | +| `net.sock.host.addr` | string | Deprecated, use `network.local.address`. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.address`. | +| `net.sock.host.port` | int | Deprecated, use `network.local.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.port`. | +| `net.sock.peer.addr` | string | Deprecated, use `network.peer.address`. | `192.168.0.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.address`. | +| `net.sock.peer.name` | string | Deprecated, no replacement at this time. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| `net.sock.peer.port` | int | Deprecated, use `network.peer.port`. | `65531` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.port`. | +| `net.transport` | string | Deprecated, use `network.transport`. | `ip_tcp` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.transport`. | + +`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 | Stability | +|---|---|---| +| `inet` | IPv4 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inet6` | IPv6 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unix` | Unix domain socket path | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`net.transport` 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 | Stability | +|---|---|---| +| `ip_tcp` | ip_tcp | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ip_udp` | ip_udp | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pipe` | Named or anonymous pipe. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inproc` | In-process communication. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | Something else (non IP-based). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. diff --git a/docs/attributes-registry/oci.md b/docs/attributes-registry/oci.md index abfc4f7479..839aa4da9e 100644 --- a/docs/attributes-registry/oci.md +++ b/docs/attributes-registry/oci.md @@ -5,9 +5,9 @@ The [Open Container Initiative](https://opencontainers.org/) defines open indust ## OCI Image Manifest -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). diff --git a/docs/attributes-registry/os.md b/docs/attributes-registry/os.md index 1a9df99771..aff35e76e8 100644 --- a/docs/attributes-registry/os.md +++ b/docs/attributes-registry/os.md @@ -7,27 +7,27 @@ linkTitle: OS ## Operating System Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | -| `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | -| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | -| `os.type` | string | The operating system type. | `windows` | -| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.type` | string | The operating system type. | `windows` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`os.type` 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. +`os.type` 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 | -|---|---| -| `windows` | Microsoft Windows | -| `linux` | Linux | -| `darwin` | Apple Darwin | -| `freebsd` | FreeBSD | -| `netbsd` | NetBSD | -| `openbsd` | OpenBSD | -| `dragonflybsd` | DragonFly BSD | -| `hpux` | HP-UX (Hewlett Packard Unix) | -| `aix` | AIX (Advanced Interactive eXecutive) | -| `solaris` | SunOS, Oracle Solaris | -| `z_os` | IBM z/OS | +| Value | Description | Stability | +|---|---|---| +| `windows` | Microsoft Windows | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `linux` | Linux | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `darwin` | Apple Darwin | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `freebsd` | FreeBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netbsd` | NetBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openbsd` | OpenBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dragonflybsd` | DragonFly BSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hpux` | HP-UX (Hewlett Packard Unix) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aix` | AIX (Advanced Interactive eXecutive) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `solaris` | SunOS, Oracle Solaris | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `z_os` | IBM z/OS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 3405cb03c1..280cb7e851 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -6,17 +6,17 @@ ## Process Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | -| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | -| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | -| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | -| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | -| `process.owner` | string | The username of the user that owns the process. | `root` | -| `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | -| `process.pid` | int | Process identifier (PID). | `1234` | -| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | -| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | -| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.owner` | string | The username of the user that owns the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.pid` | int | Process identifier (PID). | `1234` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/rpc.md b/docs/attributes-registry/rpc.md index fd112b1d2b..0c904e3f48 100644 --- a/docs/attributes-registry/rpc.md +++ b/docs/attributes-registry/rpc.md @@ -8,21 +8,21 @@ RPC attributes are intended to be used in the context of events related to remote procedure calls (RPC). -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | -| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | -| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | -| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | -| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | -| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | -| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | -| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | -| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [5] | `exampleMethod` | -| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [6] | `myservice.EchoService` | -| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [5] | `exampleMethod` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [6] | `myservice.EchoService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -38,54 +38,54 @@ RPC attributes are intended to be used in the context of events related to remot `rpc.connect_rpc.error_code` MUST be one of the following: -| Value | Description | -|---|---| -| `cancelled` | cancelled | -| `unknown` | unknown | -| `invalid_argument` | invalid_argument | -| `deadline_exceeded` | deadline_exceeded | -| `not_found` | not_found | -| `already_exists` | already_exists | -| `permission_denied` | permission_denied | -| `resource_exhausted` | resource_exhausted | -| `failed_precondition` | failed_precondition | -| `aborted` | aborted | -| `out_of_range` | out_of_range | -| `unimplemented` | unimplemented | -| `internal` | internal | -| `unavailable` | unavailable | -| `data_loss` | data_loss | -| `unauthenticated` | unauthenticated | +| Value | Description | Stability | +|---|---|---| +| `cancelled` | cancelled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `invalid_argument` | invalid_argument | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `deadline_exceeded` | deadline_exceeded | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `not_found` | not_found | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `already_exists` | already_exists | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `permission_denied` | permission_denied | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `resource_exhausted` | resource_exhausted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `failed_precondition` | failed_precondition | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aborted` | aborted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out_of_range` | out_of_range | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unimplemented` | unimplemented | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `internal` | internal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `data_loss` | data_loss | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unauthenticated` | unauthenticated | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `rpc.grpc.status_code` MUST be one of the following: -| Value | Description | -|---|---| -| `0` | OK | -| `1` | CANCELLED | -| `2` | UNKNOWN | -| `3` | INVALID_ARGUMENT | -| `4` | DEADLINE_EXCEEDED | -| `5` | NOT_FOUND | -| `6` | ALREADY_EXISTS | -| `7` | PERMISSION_DENIED | -| `8` | RESOURCE_EXHAUSTED | -| `9` | FAILED_PRECONDITION | -| `10` | ABORTED | -| `11` | OUT_OF_RANGE | -| `12` | UNIMPLEMENTED | -| `13` | INTERNAL | -| `14` | UNAVAILABLE | -| `15` | DATA_LOSS | -| `16` | UNAUTHENTICATED | - -`rpc.system` 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 | -|---|---| -| `grpc` | gRPC | -| `java_rmi` | Java RMI | -| `dotnet_wcf` | .NET WCF | -| `apache_dubbo` | Apache Dubbo | -| `connect_rpc` | Connect RPC | +| Value | Description | Stability | +|---|---|---| +| `0` | OK | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `1` | CANCELLED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `2` | UNKNOWN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `3` | INVALID_ARGUMENT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `4` | DEADLINE_EXCEEDED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `5` | NOT_FOUND | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `6` | ALREADY_EXISTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `7` | PERMISSION_DENIED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `8` | RESOURCE_EXHAUSTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `9` | FAILED_PRECONDITION | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `10` | ABORTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `11` | OUT_OF_RANGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `12` | UNIMPLEMENTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `13` | INTERNAL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `14` | UNAVAILABLE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `15` | DATA_LOSS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `16` | UNAUTHENTICATED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/server.md b/docs/attributes-registry/server.md index a1189591a1..a55453f54a 100644 --- a/docs/attributes-registry/server.md +++ b/docs/attributes-registry/server.md @@ -12,10 +12,10 @@ protocol / API does not expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `server.address` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| `server.port` | int | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Server port number. [2] | `80`; `8080`; `443` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `server.address` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/attributes-registry/source.md b/docs/attributes-registry/source.md index c239896bf1..b4d4af5da1 100644 --- a/docs/attributes-registry/source.md +++ b/docs/attributes-registry/source.md @@ -12,10 +12,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t "user-facing" surface of the protocol / API does not expose a clear notion of client and server. -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| `source.port` | int | Source port number | `3389`; `2888` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `source.port` | int | Source port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. \ No newline at end of file diff --git a/docs/attributes-registry/thread.md b/docs/attributes-registry/thread.md index 5a71c29cc8..4e503b99c2 100644 --- a/docs/attributes-registry/thread.md +++ b/docs/attributes-registry/thread.md @@ -8,8 +8,8 @@ These attributes may be used for any operation to store information about a thre ## Thread Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | -| `thread.name` | string | Current thread name. | `main` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `thread.name` | string | Current thread name. | `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/tls.md b/docs/attributes-registry/tls.md index f774c31a26..081192af6b 100644 --- a/docs/attributes-registry/tls.md +++ b/docs/attributes-registry/tls.md @@ -6,44 +6,44 @@ ## TLS Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `tls.cipher` | string | String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. [1] | `TLS_RSA_WITH_3DES_EDE_CBC_SHA`; `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | -| `tls.client.certificate` | string | PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. | `MII...` | -| `tls.client.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | -| `tls.client.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | -| `tls.client.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | -| `tls.client.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | -| `tls.client.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | -| `tls.client.ja3` | string | A hash that identifies clients based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | -| `tls.client.not_after` | string | Date/Time indicating when client certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | -| `tls.client.not_before` | string | Date/Time indicating when client certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | -| `tls.client.server_name` | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | -| `tls.client.subject` | string | Distinguished name of subject of the x.509 certificate presented by the client. | `CN=myclient, OU=Documentation Team, DC=example, DC=com` | -| `tls.client.supported_ciphers` | string[] | Array of ciphers offered by the client during the client hello. | `["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."]` | -| `tls.curve` | string | String indicating the curve used for the given cipher, when applicable | `secp256r1` | -| `tls.established` | boolean | Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. | `True` | -| `tls.next_protocol` | string | String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. | `http/1.1` | -| `tls.protocol.name` | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl` | -| `tls.protocol.version` | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | -| `tls.resumed` | boolean | Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. | `True` | -| `tls.server.certificate` | string | PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. | `MII...` | -| `tls.server.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | -| `tls.server.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | -| `tls.server.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | -| `tls.server.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | -| `tls.server.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | -| `tls.server.ja3s` | string | A hash that identifies servers based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | -| `tls.server.not_after` | string | Date/Time indicating when server certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | -| `tls.server.not_before` | string | Date/Time indicating when server certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | -| `tls.server.subject` | string | Distinguished name of subject of the x.509 certificate presented by the server. | `CN=myserver, OU=Documentation Team, DC=example, DC=com` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `tls.cipher` | string | String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. [1] | `TLS_RSA_WITH_3DES_EDE_CBC_SHA`; `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.certificate` | string | PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.ja3` | string | A hash that identifies clients based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.not_after` | string | Date/Time indicating when client certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.not_before` | string | Date/Time indicating when client certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.server_name` | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.subject` | string | Distinguished name of subject of the x.509 certificate presented by the client. | `CN=myclient, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.supported_ciphers` | string[] | Array of ciphers offered by the client during the client hello. | `["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.curve` | string | String indicating the curve used for the given cipher, when applicable | `secp256r1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.established` | boolean | Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. | `True` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.next_protocol` | string | String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. | `http/1.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.protocol.name` | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.protocol.version` | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.resumed` | boolean | Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. | `True` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.certificate` | string | PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.ja3s` | string | A hash that identifies servers based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.not_after` | string | Date/Time indicating when server certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.not_before` | string | Date/Time indicating when server certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.subject` | string | Distinguished name of subject of the x.509 certificate presented by the server. | `CN=myserver, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). -`tls.protocol.name` 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. +`tls.protocol.name` 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 | -|---|---| -| `ssl` | ssl | -| `tls` | tls | +| Value | Description | Stability | +|---|---|---| +| `ssl` | ssl | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls` | tls | ![Experimental](https://img.shields.io/badge/-experimental-blue) | \ No newline at end of file diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index 630c8fc639..69ca3fb8f3 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -7,20 +7,20 @@ linkTitle: URL ## URL Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `url.domain` | string | Domain extracted from the `url.full`, such as "opentelemetry.io". [1] | `www.foo.bar`; `opentelemetry.io`; `3.12.167.2`; `[1080:0:0:0:8:800:200C:417A]` | -| `url.extension` | string | The file extension extracted from the `url.full`, excluding the leading dot. [2] | `png`; `gz` | -| `url.fragment` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | -| `url.full` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | -| `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | -| `url.path` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [5] | `/search` | -| `url.port` | int | Port extracted from the `url.full` | `443` | -| `url.query` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | -| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | -| `url.scheme` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | -| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | -| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `url.domain` | string | Domain extracted from the `url.full`, such as "opentelemetry.io". [1] | `www.foo.bar`; `opentelemetry.io`; `3.12.167.2`; `[1080:0:0:0:8:800:200C:417A]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.extension` | string | The file extension extracted from the `url.full`, excluding the leading dot. [2] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [5] | `/search` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.port` | int | Port extracted from the `url.full` | `443` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md index 3baeaaf931..cc0cd35a0c 100644 --- a/docs/attributes-registry/user-agent.md +++ b/docs/attributes-registry/user-agent.md @@ -6,11 +6,11 @@ ## User agent Attributes -| Attribute | Type | Description | Examples | -|---|---|---|---| -| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name. [1] | `Safari`; `YourApp` | -| `user_agent.original` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | -| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2`; `1.0.0` | +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name. [1] | `Safari`; `YourApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user_agent.original` | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2`; `1.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [Example](https://www.whatsmyua.info) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version` diff --git a/docs/cloud-providers/aws-sdk.md b/docs/cloud-providers/aws-sdk.md index 9eb2077746..a23c543d33 100644 --- a/docs/cloud-providers/aws-sdk.md +++ b/docs/cloud-providers/aws-sdk.md @@ -25,12 +25,12 @@ with the naming guidelines for RPC client spans. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | Recommended | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | Recommended | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | Recommended | -| [`rpc.system`](../attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.system`](../attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 472f8aea16..7587bad336 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -200,13 +200,13 @@ The following attributes are applicable to creation and processing Spans. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`cloudevents.event_id`](../attributes-registry/cloudevents.md) | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | Required | -| [`cloudevents.event_source`](../attributes-registry/cloudevents.md) | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | Required | -| [`cloudevents.event_spec_version`](../attributes-registry/cloudevents.md) | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | Recommended | -| [`cloudevents.event_subject`](../attributes-registry/cloudevents.md) | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | Recommended | -| [`cloudevents.event_type`](../attributes-registry/cloudevents.md) | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudevents.event_id`](../attributes-registry/cloudevents.md) | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_source`](../attributes-registry/cloudevents.md) | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_spec_version`](../attributes-registry/cloudevents.md) | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_subject`](../attributes-registry/cloudevents.md) | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_type`](../attributes-registry/cloudevents.md) | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 6e83dd1a69..96ff729430 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -15,40 +15,40 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | Recommended | -| [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | Recommended | -| [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | Recommended | -| [`db.cassandra.idempotence`](../attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | Recommended | -| [`db.cassandra.page_size`](../attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | Recommended | -| [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | Recommended | -| [`db.cassandra.table`](../attributes-registry/db.md) | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | Recommended | -| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [2] | `mykeyspace` | Conditionally Required: If applicable. | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | - -**[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. - -**[2]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [1] | `mykeyspace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.idempotence`](../attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.page_size`](../attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.table`](../attributes-registry/db.md) | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [2] | `mytable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +**[2]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. **[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. `db.cassandra.consistency_level` MUST be one of the following: -| Value | Description | -|---|---| -| `all` | all | -| `each_quorum` | each_quorum | -| `quorum` | quorum | -| `local_quorum` | local_quorum | -| `one` | one | -| `two` | two | -| `three` | three | -| `local_one` | local_one | -| `any` | any | -| `serial` | serial | -| `local_serial` | local_serial | +| Value | Description | Stability | +|---|---|---| +| `all` | all | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `each_quorum` | each_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `quorum` | quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_quorum` | local_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `one` | one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `two` | two | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `three` | three | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_one` | local_one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `any` | any | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `serial` | serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_serial` | local_serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 51fc4ba2f9..822ddeccc7 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -18,17 +18,17 @@ described on this page. Cosmos DB instrumentation includes call-level (public API) surface spans and network spans. Depending on the connection mode (Gateway or Direct), network-level spans may also be created. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | Recommended | -| [`db.cosmosdb.connection_mode`](../attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway` | Conditionally Required: if not `direct` (or pick gw as default) | -| [`db.cosmosdb.container`](../attributes-registry/db.md) | string | Cosmos DB container name. | `anystring` | Conditionally Required: if available | -| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | Conditionally Required: [1] | -| [`db.cosmosdb.request_charge`](../attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1.0` | Conditionally Required: when available | -| [`db.cosmosdb.request_content_length`](../attributes-registry/db.md) | int | Request payload size in bytes | | Recommended | -| [`db.cosmosdb.status_code`](../attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | Conditionally Required: if response was received | -| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | Conditionally Required: [2] | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.cosmosdb.connection_mode`](../attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway` | `Conditionally Required` if not `direct` (or pick gw as default) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.container`](../attributes-registry/db.md) | string | Cosmos DB container name. | `anystring` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.request_charge`](../attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1.0` | `Conditionally Required` when available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.status_code`](../attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | `Conditionally Required` if response was received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.request_content_length`](../attributes-registry/db.md) | int | Request payload size in bytes | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** when performing one of the operations in this list @@ -40,30 +40,30 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net `db.cosmosdb.connection_mode` MUST be one of the following: -| Value | Description | -|---|---| -| `gateway` | Gateway (HTTP) connections mode | -| `direct` | Direct connection. | - -`db.cosmosdb.operation_type` 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 | -|---|---| -| `Invalid` | invalid | -| `Create` | create | -| `Patch` | patch | -| `Read` | read | -| `ReadFeed` | read_feed | -| `Delete` | delete | -| `Replace` | replace | -| `Execute` | execute | -| `Query` | query | -| `Head` | head | -| `HeadFeed` | head_feed | -| `Upsert` | upsert | -| `Batch` | batch | -| `QueryPlan` | query_plan | -| `ExecuteJavaScript` | execute_javascript | +| Value | Description | Stability | +|---|---|---| +| `gateway` | Gateway (HTTP) connections mode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `direct` | Direct connection. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`db.cosmosdb.operation_type` 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 | Stability | +|---|---|---| +| `Invalid` | invalid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Create` | create | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Patch` | patch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ReadFeed` | read_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Replace` | replace | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Execute` | execute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Query` | query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Head` | head | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `HeadFeed` | head_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Upsert` | upsert | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Batch` | batch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `QueryPlan` | query_plan | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ExecuteJavaScript` | execute_javascript | ![Experimental](https://img.shields.io/badge/-experimental-blue) | In addition to Cosmos DB attributes, all spans include diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 5ad2aae166..a7ba93e347 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -15,9 +15,9 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | Conditionally Required: If `db.statement` is not applicable. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` If `db.statement` is not applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index f7bedea83d..03c69cb6e2 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -44,38 +44,38 @@ The following metric instruments describe database client connection pool operat This metric is [required][MetricRequired]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.usage` | UpDownCounter | `{connection}` | The number of connections that are currently in state described by the `state` attribute | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.usage` | UpDownCounter | `{connection}` | The number of connections that are currently in state described by the `state` attribute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | -| `state` | string | The state of a connection in the pool | `idle` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `state` | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `state` MUST be one of the following: -| Value | Description | -|---|---| -| `idle` | idle | -| `used` | used | +| Value | Description | Stability | +|---|---|---| +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.idle.max` This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.idle.min` @@ -83,15 +83,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.max` @@ -99,15 +99,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.pending_requests` @@ -115,15 +115,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.pending_requests` | UpDownCounter | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.pending_requests` | UpDownCounter | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.timeouts` @@ -131,15 +131,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.timeouts` | Counter | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.timeouts` | Counter | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.create_time` @@ -147,15 +147,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.create_time` | Histogram | `ms` | The time it took to create a new connection | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.create_time` | Histogram | `ms` | The time it took to create a new connection | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.wait_time` @@ -163,15 +163,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.wait_time` | Histogram | `ms` | The time it took to obtain an open connection from the pool | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.wait_time` | Histogram | `ms` | The time it took to obtain an open connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.use_time` @@ -179,15 +179,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `db.client.connections.use_time` | Histogram | `ms` | The time between borrowing a connection and returning it to the pool | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.connections.use_time` | Histogram | `ms` | The time between borrowing a connection and returning it to the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index a37429f009..7f9d792e34 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -71,90 +71,90 @@ These attributes will usually be the same for all operations performed over the Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: If different from the `server.address` | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | Conditionally Required: If applicable. | -| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | Conditionally Required: If `db.statement` is not applicable. | -| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | Recommended: [3] | -| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | Required | -| [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | Recommended: If applicable for this database system. | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` If `db.statement` is not applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` [4] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [6] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). **[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. -**[3]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[4]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +**[4]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[5]:** Should be collected by default only if there is sanitization that excludes sensitive information. + +**[6]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. - -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. - -**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. - -`db.system` 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 | -|---|---| -| `other_sql` | Some other SQL database. Fallback only. See notes. | -| `mssql` | Microsoft SQL Server | -| `mssqlcompact` | Microsoft SQL Server Compact | -| `mysql` | MySQL | -| `oracle` | Oracle Database | -| `db2` | IBM Db2 | -| `postgresql` | PostgreSQL | -| `redshift` | Amazon Redshift | -| `hive` | Apache Hive | -| `cloudscape` | Cloudscape | -| `hsqldb` | HyperSQL DataBase | -| `progress` | Progress Database | -| `maxdb` | SAP MaxDB | -| `hanadb` | SAP HANA | -| `ingres` | Ingres | -| `firstsql` | FirstSQL | -| `edb` | EnterpriseDB | -| `cache` | InterSystems Caché | -| `adabas` | Adabas (Adaptable Database System) | -| `firebird` | Firebird | -| `derby` | Apache Derby | -| `filemaker` | FileMaker | -| `informix` | Informix | -| `instantdb` | InstantDB | -| `interbase` | InterBase | -| `mariadb` | MariaDB | -| `netezza` | Netezza | -| `pervasive` | Pervasive PSQL | -| `pointbase` | PointBase | -| `sqlite` | SQLite | -| `sybase` | Sybase | -| `teradata` | Teradata | -| `vertica` | Vertica | -| `h2` | H2 | -| `coldfusion` | ColdFusion IMQ | -| `cassandra` | Apache Cassandra | -| `hbase` | Apache HBase | -| `mongodb` | MongoDB | -| `redis` | Redis | -| `couchbase` | Couchbase | -| `couchdb` | CouchDB | -| `cosmosdb` | Microsoft Azure Cosmos DB | -| `dynamodb` | Amazon DynamoDB | -| `neo4j` | Neo4j | -| `geode` | Apache Geode | -| `elasticsearch` | Elasticsearch | -| `memcached` | Memcached | -| `cockroachdb` | CockroachDB | -| `opensearch` | OpenSearch | -| `clickhouse` | ClickHouse | -| `spanner` | Cloud Spanner | -| `trino` | Trino | +**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +`db.system` 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 | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Notes and well-known identifiers for `db.system` diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 932f5e5fc0..b81e58fdda 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -17,157 +17,157 @@ described on this page. These attributes are filled in for all DynamoDB request types. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.system`](../attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.system`](../attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.BatchGetItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.BatchWriteItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.CreateTable -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | -| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | Recommended | -| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | -| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteTable -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DescribeTable -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.GetItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | Recommended | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.ListTables -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | Recommended | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | -| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.PutItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Query -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | Recommended | -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | Recommended | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | Recommended | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | Recommended | -| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | Recommended | -| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Scan -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | Recommended | -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | Recommended | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | Recommended | -| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | Recommended | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | Recommended | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | Recommended | -| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | Recommended | -| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | Recommended | -| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | -| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateItem -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateTable -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | Recommended | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | Recommended | -| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | Recommended | -| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | -| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | Recommended | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 5c8d9f5a9d..2b85f275b8 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -24,31 +24,23 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | Recommended: [1] | -| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [2] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | Conditionally Required: when the url has dynamic values | -| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | Recommended: [3] | -| [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [4] | `search`; `ml.close_job`; `cat.aliases` | Required | -| [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | Recommended: [5] | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [6] | `GET`; `POST`; `HEAD` | Required | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [7] | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [9] | `80`; `8080`; `443` | Conditionally Required: [10] | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [11] | `https://localhost:9200/index/_search?q=user.id:kimchy` | Required | - -**[1]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. - -**[2]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. - -**[3]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. - -**[4]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. - -**[5]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. - -**[6]:** HTTP request method value SHOULD be "known" to the instrumentation. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [1] | `search`; `ml.close_job`; `cat.aliases` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://localhost:9200/index/_search?q=user.id:kimchy` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | `Conditionally Required` when the url has dynamic values | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + +**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -63,32 +55,40 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[7]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. -**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[4]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -**[9]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[10]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[11]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. +**[7]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. + +**[8]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. + +**[9]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. + +**[10]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[11]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +`http.request.method` 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.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +| Value | Description | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Example diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 50675d6b91..45a665eef1 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -15,9 +15,9 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | Conditionally Required: If applicable. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** For HBase the `db.name` should be set to the HBase namespace. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 71558732c8..2bd73c8df3 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -15,9 +15,9 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Example diff --git a/docs/database/mssql.md b/docs/database/mssql.md index e0ad3c6727..90c80af32d 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -15,10 +15,10 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | Recommended | -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [2] | `public.users`; `customers` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [2] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). diff --git a/docs/database/redis.md b/docs/database/redis.md index 895a293895..be0897ba42 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -15,12 +15,12 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | Conditionally Required: If other than the default database (`0`). | -| [`db.statement`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | Recommended: [2] | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: if and only if `network.peer.address` is set. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | `Conditionally Required` If other than the default database (`0`). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.statement`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. diff --git a/docs/database/sql.md b/docs/database/sql.md index 17b8dcc892..32aeaa31cb 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -13,9 +13,9 @@ described on this page. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. diff --git a/docs/dns/dns-metrics.md b/docs/dns/dns-metrics.md index 46262286cc..7c67b1f9e6 100644 --- a/docs/dns/dns-metrics.md +++ b/docs/dns/dns-metrics.md @@ -21,8 +21,6 @@ This document defines semantic conventions to apply when instrumenting DNS queri ### Metric: `dns.lookup.duration` -**Status**: [Experimental][DocumentStatus] - This metric is optional. This metric SHOULD be specified with @@ -30,26 +28,26 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`dns.question.name`](../attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `dot.net` | Required | -| [`error.type`](../attributes-registry/error.md) | string | Describes the error the DNS lookup failed with. [2] | `host_not_found`; `no_recovery`; `java.net.UnknownHostException` | Conditionally Required: if and only if an error has occurred. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`dns.question.name`](../attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `dot.net` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](../attributes-registry/error.md) | string | Describes the error the DNS lookup failed with. [2] | `host_not_found`; `no_recovery`; `java.net.UnknownHostException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. **[2]:** Instrumentations SHOULD use error code such as one of errors reported by `getaddrinfo`([Linux or other POSIX systems](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) / [Windows](https://learn.microsoft.com/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo)) or one reported by the runtime or client library. If error code is not available, the full name of exception type SHOULD be used. -`error.type` 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. +`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index 54b8fc04a0..95617251d4 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -33,29 +33,29 @@ All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. ### Metric: `aspnetcore.routing.match_attempts` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.routing.match_attempts` | Counter | `{match_attempt}` | Number of requests that were attempted to be matched to an endpoint. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.routing.match_attempts` | Counter | `{match_attempt}` | Number of requests that were attempted to be matched to an endpoint. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Routing`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.routing.is_fallback` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
A value that indicates whether the matched route is a fallback route. | `True` | Conditionally Required: if and only if a route was successfully matched. | -| `aspnetcore.routing.match_status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Match result - success or failure | `success`; `failure` | Required | -| [`http.route`](../attributes-registry/http.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: if and only if a route was successfully matched. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. -`aspnetcore.routing.match_status` 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. +`aspnetcore.routing.match_status` 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 | -|---|---| -| `success` | Match succeeded | -| `failure` | Match failed | +| Value | Description | Stability | +|---|---|---| +| `success` | Match succeeded | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Exceptions @@ -65,23 +65,21 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. ### Metric: `aspnetcore.diagnostics.exceptions` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.diagnostics.exceptions` | Counter | `{exception}` | Number of exceptions caught by exception handling middleware. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.diagnostics.exceptions` | Counter | `{exception}` | Number of exceptions caught by exception handling middleware. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Diagnostics`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.diagnostics.exception.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
ASP.NET Core exception middleware handling result | `handled`; `unhandled` | Required | -| `aspnetcore.diagnostics.handler.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | Conditionally Required: [1] | -| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [2] | `System.OperationCanceledException`; `Contoso.MyException` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** if and only if the exception was handled by this handler. - -**[2]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. @@ -97,20 +95,22 @@ it's RECOMMENDED to: * Use a domain-specific attribute * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. +**[2]:** if and only if the exception was handled by this handler. + `aspnetcore.diagnostics.exception.result` MUST be one of the following: -| Value | Description | -|---|---| -| `handled` | Exception was handled by the exception handling middleware. | -| `unhandled` | Exception was not handled by the exception handling middleware. | -| `skipped` | Exception handling was skipped because the response had started. | -| `aborted` | Exception handling didn't run because the request was aborted. | +| Value | Description | Stability | +|---|---|---| +| `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`error.type` 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. +`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Rate-limiting @@ -120,17 +120,17 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting ### Metric: `aspnetcore.rate_limiting.active_request_leases` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.rate_limiting.active_request_leases` | UpDownCounter | `{request}` | Number of requests that are currently active on the server that hold a rate limiting lease. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.rate_limiting.active_request_leases` | UpDownCounter | `{request}` | Number of requests that are currently active on the server that hold a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -142,17 +142,17 @@ this metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.rate_limiting.request_lease.duration` | Histogram | `s` | The duration of rate limiting lease held by requests on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.rate_limiting.request_lease.duration` | Histogram | `s` | The duration of rate limiting lease held by requests on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -160,17 +160,17 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ### Metric: `aspnetcore.rate_limiting.queued_requests` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.rate_limiting.queued_requests` | UpDownCounter | `{request}` | Number of requests that are currently queued, waiting to acquire a rate limiting lease. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.rate_limiting.queued_requests` | UpDownCounter | `{request}` | Number of requests that are currently queued, waiting to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -182,37 +182,37 @@ this metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.rate_limiting.request.time_in_queue` | Histogram | `s` | The time the request spent in a queue waiting to acquire a rate limiting lease. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.rate_limiting.request.time_in_queue` | Histogram | `s` | The time the request spent in a queue waiting to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | -| `aspnetcore.rate_limiting.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. -`aspnetcore.rate_limiting.result` 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. +`aspnetcore.rate_limiting.result` 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 | -|---|---| -| `acquired` | Lease was acquired | -| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | -| `global_limiter` | Lease request was rejected by the global limiter | -| `request_canceled` | Lease request was canceled | +| Value | Description | Stability | +|---|---|---| +| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `aspnetcore.rate_limiting.requests` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `aspnetcore.rate_limiting.requests` | Counter | `{request}` | Number of requests that tried to acquire a rate limiting lease. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `aspnetcore.rate_limiting.requests` | Counter | `{request}` | Number of requests that tried to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Requests could be: @@ -223,21 +223,21 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate limiting policy name. | `fixed`; `sliding`; `token` | Conditionally Required: [1] | -| `aspnetcore.rate_limiting.result` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. -`aspnetcore.rate_limiting.result` 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. +`aspnetcore.rate_limiting.result` 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 | -|---|---| -| `acquired` | Lease was acquired | -| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | -| `global_limiter` | Lease request was rejected by the global limiter | -| `request_canceled` | Lease request was canceled | +| Value | Description | Stability | +|---|---|---| +| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md index a6971f77ef..34727f84e2 100644 --- a/docs/dotnet/dotnet-kestrel-metrics.md +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -33,20 +33,20 @@ In case instrumentation does not recognize `EndPoint` implementation, it sets th ## Metric: `kestrel.active_connections` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -60,21 +60,21 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.connection.duration` @@ -84,24 +84,24 @@ this metric SHOULD be specified with of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [3] | `1.1`; `2` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Recommended | -| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Captures the exception type when a connection fails. @@ -121,47 +121,47 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`error.type` 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. +`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.rejected_connections` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.rejected_connections` | Counter | `{connection}` | Number of connections rejected by the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.rejected_connections` | Counter | `{connection}` | Number of connections rejected by the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Connections are rejected when the currently active count exceeds the value configured with `MaxConcurrentConnections`. Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -175,40 +175,40 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.queued_connections` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.queued_connections` | UpDownCounter | `{connection}` | Number of connections that are currently queued and are waiting to start. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.queued_connections` | UpDownCounter | `{connection}` | Number of connections that are currently queued and are waiting to start. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -222,42 +222,42 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.queued_requests` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.queued_requests` | UpDownCounter | `{request}` | Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.queued_requests` | UpDownCounter | `{request}` | Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.protocol.name`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The actual version of the protocol used for network communication. [2] | `1.1`; `2` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -275,29 +275,29 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.upgraded_connections` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.upgraded_connections` | UpDownCounter | `{connection}` | Number of connections that are currently upgraded (WebSockets). . [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.upgraded_connections` | UpDownCounter | `{connection}` | Number of connections that are currently upgraded (WebSockets). . [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The counter only tracks HTTP/1.1 connections. @@ -305,12 +305,12 @@ Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -324,21 +324,21 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.tls_handshake.duration` @@ -348,22 +348,22 @@ this metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.tls_handshake.duration` | Histogram | `s` | The duration of TLS handshakes on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.tls_handshake.duration` | Histogram | `s` | The duration of TLS handshakes on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | Conditionally Required: if and only if an error has occurred. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | Recommended | -| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Captures the exception type when a TLS handshake fails. @@ -379,46 +379,46 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`error.type` 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. +`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `kestrel.active_tls_handshakes` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `kestrel.active_tls_handshakes` | UpDownCounter | `{handshake}` | Number of TLS handshakes that are currently in progress on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `kestrel.active_tls_handshakes` | UpDownCounter | `{handshake}` | Number of TLS handshakes that are currently in progress on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended: if the transport is `tcp` or `udp` | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -432,21 +432,21 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index 931d5f4bf3..73471c645b 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -22,67 +22,67 @@ this metric SHOULD be specified with of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `signalr.server.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `signalr.server.connection.duration` | Histogram | `s` | The duration of connections on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `signalr.connection.status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | -| `signalr.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: -| Value | Description | -|---|---| -| `normal_closure` | The connection was closed normally. | -| `timeout` | The connection was closed due to a timeout. | -| `app_shutdown` | The connection was closed because the app is shutting down. | +| Value | Description | Stability | +|---|---|---| +| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`signalr.transport` 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. +`signalr.transport` 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 | -|---|---| -| `server_sent_events` | ServerSentEvents protocol | -| `long_polling` | LongPolling protocol | -| `web_sockets` | WebSockets protocol | +| Value | Description | Stability | +|---|---|---| +| `server_sent_events` | ServerSentEvents protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Metric: `signalr.server.active_connections` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `signalr.server.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `signalr.server.active_connections` | UpDownCounter | `{connection}` | Number of connections that are currently active on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Meter name: `Microsoft.AspNetCore.Http.Connections`; Added in: ASP.NET Core 8.0 -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `signalr.connection.status` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Recommended | -| `signalr.transport` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: -| Value | Description | -|---|---| -| `normal_closure` | The connection was closed normally. | -| `timeout` | The connection was closed due to a timeout. | -| `app_shutdown` | The connection was closed because the app is shutting down. | +| Value | Description | Stability | +|---|---|---| +| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`signalr.transport` 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. +`signalr.transport` 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 | -|---|---| -| `server_sent_events` | ServerSentEvents protocol | -| `long_polling` | LongPolling protocol | -| `web_sockets` | WebSockets protocol | +| Value | Description | Stability | +|---|---|---| +| `server_sent_events` | ServerSentEvents protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 0746762191..1365a02753 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -36,11 +36,11 @@ The table below indicates which attributes should be added to the [LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **Additional attribute requirements:** At least one of the following sets of attributes is required: diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index ef9d3849e1..66ff658c1a 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -46,12 +46,12 @@ their types. The event name MUST be `exception`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | Recommended | -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | -| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Recommended | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index c2219b9e4e..f980a2b2f1 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -45,9 +45,9 @@ Also consider setting other attributes of the [`faas` resource][faasres] and [tr and the [cloud resource conventions][cloud]. The following AWS Lambda-specific attribute MAY also be set: -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.lambda.invoked_arn` | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.lambda.invoked_arn` | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This may be different from `cloud.resource_id` if an alias is involved. diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index 9ecf509df3..e7211edf2c 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -50,25 +50,25 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.invoke_duration` | Histogram | `s` | Measures the duration of the function's logic execution | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.invoke_duration` | Histogram | `s` | Measures the duration of the function's logic execution | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.init_duration` @@ -80,25 +80,25 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.init_duration` | Histogram | `s` | Measures the duration of the function's initialization, such as a cold start | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.init_duration` | Histogram | `s` | Measures the duration of the function's initialization, such as a cold start | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.coldstarts` @@ -106,25 +106,25 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.coldstarts` | Counter | `{coldstart}` | Number of invocation cold starts | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.coldstarts` | Counter | `{coldstart}` | Number of invocation cold starts | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.errors` @@ -132,25 +132,25 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.errors` | Counter | `{error}` | Number of invocation errors | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.errors` | Counter | `{error}` | Number of invocation errors | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.invocations` @@ -158,25 +158,25 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.invocations` | Counter | `{invocation}` | Number of successful invocations | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.invocations` | Counter | `{invocation}` | Number of successful invocations | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.timeouts` @@ -184,25 +184,25 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.timeouts` | Counter | `{timeout}` | Number of invocation timeouts | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.timeouts` | Counter | `{timeout}` | Number of invocation timeouts | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.mem_usage` @@ -210,25 +210,25 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.mem_usage` | Histogram | `By` | Distribution of max memory usage per invocation | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.mem_usage` | Histogram | `By` | Distribution of max memory usage per invocation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.cpu_usage` @@ -240,25 +240,25 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.cpu_usage` | Histogram | `s` | Distribution of CPU usage per invocation | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.cpu_usage` | Histogram | `s` | Distribution of CPU usage per invocation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | #### Metric: `faas.net_io` @@ -266,25 +266,25 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `faas.net_io` | Histogram | `By` | Distribution of net I/O usage per invocation | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `faas.net_io` | Histogram | `By` | Distribution of net I/O usage per invocation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## References diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index ee38715df3..3b49cc5bca 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -39,11 +39,11 @@ Span `name` should be set to the function name being executed. Depending on the If Spans following this convention are produced, a Resource of type `faas` MUST exist following the [Resource semantic convention](../resource/faas.md). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | -| [`faas.invocation_id`](../attributes-registry/faas.md) | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | Recommended | -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [2] | `datasource` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invocation_id`](../attributes-registry/faas.md) | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [2] | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. @@ -75,13 +75,13 @@ call to invoke the lambda, which is often HTTP). `faas.trigger` MUST be one of the following: -| Value | Description | -|---|---| -| `datasource` | A response to some data source operation such as a database or filesystem read/write | -| `http` | To provide an answer to an inbound HTTP request | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | -| `timer` | A function is scheduled to be executed regularly | -| `other` | If none of the others apply | +| Value | Description | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Function Name @@ -120,10 +120,10 @@ For incoming FaaS spans, the span kind MUST be `Server`. ### Incoming FaaS Span attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.coldstart`](../attributes-registry/faas.md) | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | Recommended | -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [1] | `datasource` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [1] | `datasource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.coldstart`](../attributes-registry/faas.md) | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** For the server/consumer span on the incoming side, `faas.trigger` MUST be set. @@ -159,11 +159,11 @@ the corresponding [FaaS resource attributes][] and [Cloud resource attributes][] which the invoked FaaS instance reports about itself, if it's instrumented. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.invoked_name`](../attributes-registry/faas.md) | string | The name of the invoked function. [1] | `my-function` | Required | -| [`faas.invoked_provider`](../attributes-registry/faas.md) | string | The cloud provider of the invoked function. [2] | `alibaba_cloud` | Required | -| [`faas.invoked_region`](../attributes-registry/faas.md) | string | The cloud region of the invoked function. [3] | `eu-central-1` | Conditionally Required: [4] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.invoked_name`](../attributes-registry/faas.md) | string | The name of the invoked function. [1] | `my-function` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invoked_provider`](../attributes-registry/faas.md) | string | The cloud provider of the invoked function. [2] | `alibaba_cloud` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invoked_region`](../attributes-registry/faas.md) | string | The cloud region of the invoked function. [3] | `eu-central-1` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** SHOULD be equal to the `faas.name` resource attribute of the invoked function. @@ -173,15 +173,15 @@ which the invoked FaaS instance reports about itself, if it's instrumented. **[4]:** For some cloud providers, like AWS or GCP, the region in which a function is hosted is essential to uniquely identify the function and also part of its endpoint. Since it's part of the endpoint being called, the region is always known to clients. In these cases, `faas.invoked_region` MUST be set accordingly. If the region is unknown to the client or not required for identifying the invoked function, setting `faas.invoked_region` is optional. -`faas.invoked_provider` 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. +`faas.invoked_provider` 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 | -|---|---| -| `alibaba_cloud` | Alibaba Cloud | -| `aws` | Amazon Web Services | -| `azure` | Microsoft Azure | -| `gcp` | Google Cloud Platform | -| `tencent_cloud` | Tencent Cloud | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [FaaS resource attributes]: ../resource/faas.md @@ -197,20 +197,20 @@ A datasource function is triggered as a response to some data source operation s FaaS instrumentations that produce `faas` spans with trigger `datasource`, SHOULD use the following set of attributes. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.document.collection`](../attributes-registry/faas.md) | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | Required | -| [`faas.document.name`](../attributes-registry/faas.md) | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | Recommended | -| [`faas.document.operation`](../attributes-registry/faas.md) | string | Describes the type of the operation that was performed on the data. | `insert` | Required | -| [`faas.document.time`](../attributes-registry/faas.md) | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | - -`faas.document.operation` 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 | -|---|---| -| `insert` | When a new object is created. | -| `edit` | When an object is modified. | -| `delete` | When an object is deleted. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.document.collection`](../attributes-registry/faas.md) | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.operation`](../attributes-registry/faas.md) | string | Describes the type of the operation that was performed on the data. | `insert` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.name`](../attributes-registry/faas.md) | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.time`](../attributes-registry/faas.md) | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`faas.document.operation` 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 | Stability | +|---|---|---| +| `insert` | When a new object is created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edit` | When an object is modified. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | When an object is deleted. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### HTTP @@ -230,10 +230,10 @@ This way, it is possible to correlate each individual message with its invocatio A function is scheduled to be executed regularly. The following additional attributes are recommended. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`faas.cron`](../attributes-registry/faas.md) | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | Recommended | -| [`faas.time`](../attributes-registry/faas.md) | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.cron`](../attributes-registry/faas.md) | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.time`](../attributes-registry/faas.md) | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Other diff --git a/docs/feature-flags/feature-flags-logs.md b/docs/feature-flags/feature-flags-logs.md index e86df3b2f3..e9db9d3a2d 100644 --- a/docs/feature-flags/feature-flags-logs.md +++ b/docs/feature-flags/feature-flags-logs.md @@ -40,11 +40,11 @@ The table below indicates which attributes should be added to the The event name MUST be `feature_flag`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | Recommended | -| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | -| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/feature-flags/feature-flags-spans.md b/docs/feature-flags/feature-flags-spans.md index da0fa1cc1f..8a6548338e 100644 --- a/docs/feature-flags/feature-flags-spans.md +++ b/docs/feature-flags/feature-flags-spans.md @@ -44,11 +44,11 @@ A flag evaluation SHOULD be recorded as an Event on the span during which it occ The event name MUST be `feature_flag`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | Required | -| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | Recommended | -| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 9a74f6807f..2c6f13649d 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -67,10 +67,10 @@ Once the HTTP semantic conventions are declared stable, changes to the attribute if they do not cause breaking changes to HTTP semantic conventions. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -104,10 +104,10 @@ Once the HTTP semantic conventions are declared stable, changes to the attribute if they do not cause breaking changes to HTTP semantic conventions. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. @@ -126,10 +126,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t #### Source -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`source.address`](../attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`source.port`](../attributes-registry/source.md) | int | Source port number | `3389`; `2888` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`source.address`](../attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`source.port`](../attributes-registry/source.md) | int | Source port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. @@ -139,10 +139,10 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t Destination fields capture details about the receiver of a network exchange/packet. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`destination.address`](../attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`destination.port`](../attributes-registry/destination.md) | int | Destination port number | `3389`; `2888` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`destination.address`](../attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`destination.port`](../attributes-registry/destination.md) | int | Destination port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. @@ -157,16 +157,16 @@ Once the HTTP semantic conventions are declared stable, changes to the attribute if they do not cause breaking changes to HTTP semantic conventions. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.local.address`](../attributes-registry/network.md) | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.local.port`](../attributes-registry/network.md) | int | Local port number of the network connection. | `65123` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.local.address`](../attributes-registry/network.md) | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.port`](../attributes-registry/network.md) | int | Local port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -180,21 +180,21 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[4]:** The value SHOULD be normalized to lowercase. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`network.type` 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. +`network.type` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | #### `network.peer.*` and `network.local.*` attributes @@ -239,50 +239,50 @@ Note that `network.local.*` attributes are not included in these examples since #### Network connection and carrier attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.carrier.icc`](../attributes-registry/network.md) | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | Recommended | -| [`network.carrier.mcc`](../attributes-registry/network.md) | string | The mobile carrier country code. | `310` | Recommended | -| [`network.carrier.mnc`](../attributes-registry/network.md) | string | The mobile carrier network code. | `001` | Recommended | -| [`network.carrier.name`](../attributes-registry/network.md) | string | The name of the mobile carrier. | `sprint` | Recommended | -| [`network.connection.subtype`](../attributes-registry/network.md) | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | Recommended | -| [`network.connection.type`](../attributes-registry/network.md) | string | The internet connection type. | `wifi` | Recommended | - -`network.connection.subtype` 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 | -|---|---| -| `gprs` | GPRS | -| `edge` | EDGE | -| `umts` | UMTS | -| `cdma` | CDMA | -| `evdo_0` | EVDO Rel. 0 | -| `evdo_a` | EVDO Rev. A | -| `cdma2000_1xrtt` | CDMA2000 1XRTT | -| `hsdpa` | HSDPA | -| `hsupa` | HSUPA | -| `hspa` | HSPA | -| `iden` | IDEN | -| `evdo_b` | EVDO Rev. B | -| `lte` | LTE | -| `ehrpd` | EHRPD | -| `hspap` | HSPAP | -| `gsm` | GSM | -| `td_scdma` | TD-SCDMA | -| `iwlan` | IWLAN | -| `nr` | 5G NR (New Radio) | -| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | -| `lte_ca` | LTE CA | - -`network.connection.type` 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 | -|---|---| -| `wifi` | wifi | -| `wired` | wired | -| `cell` | cell | -| `unavailable` | unavailable | -| `unknown` | unknown | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.carrier.icc`](../attributes-registry/network.md) | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.mcc`](../attributes-registry/network.md) | string | The mobile carrier country code. | `310` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.mnc`](../attributes-registry/network.md) | string | The mobile carrier network code. | `001` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.name`](../attributes-registry/network.md) | string | The name of the mobile carrier. | `sprint` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.connection.subtype`](../attributes-registry/network.md) | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.connection.type`](../attributes-registry/network.md) | string | The internet connection type. | `wifi` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`network.connection.subtype` 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 | Stability | +|---|---|---| +| `gprs` | GPRS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edge` | EDGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `umts` | UMTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma` | CDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_0` | EVDO Rel. 0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_a` | EVDO Rev. A | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma2000_1xrtt` | CDMA2000 1XRTT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsdpa` | HSDPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsupa` | HSUPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspa` | HSPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iden` | IDEN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_b` | EVDO Rev. B | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte` | LTE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ehrpd` | EHRPD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspap` | HSPAP | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gsm` | GSM | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `td_scdma` | TD-SCDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iwlan` | IWLAN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nr` | 5G NR (New Radio) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte_ca` | LTE CA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`network.connection.type` 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 | Stability | +|---|---|---| +| `wifi` | wifi | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `wired` | wired | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cell` | cell | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | For `Unix` and `pipe`, since the connection goes over the file system instead of being directly to a known peer, `server.address` is the only attribute that usually makes sense (see description of `server.address` below). @@ -294,9 +294,9 @@ Users can define what the name of a service is based on their particular semanti Instrumentations SHOULD provide a way for users to configure this name. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `peer.service` | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `peer.service` | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Examples of `peer.service` that users may specify: @@ -309,11 +309,11 @@ Examples of `peer.service` that users may specify: These attributes may be used for any operation with an authenticated and/or authorized enduser. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`enduser.id`](../attributes-registry/enduser.md) | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | Recommended | -| [`enduser.role`](../attributes-registry/enduser.md) | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | Recommended | -| [`enduser.scope`](../attributes-registry/enduser.md) | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`enduser.id`](../attributes-registry/enduser.md) | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`enduser.role`](../attributes-registry/enduser.md) | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`enduser.scope`](../attributes-registry/enduser.md) | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | These attributes describe the authenticated user driving the user agent making requests to the instrumented @@ -356,10 +356,10 @@ These attributes may be used for any operation to store information about a thread that started a span. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`thread.id`](../attributes-registry/thread.md) | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | Recommended | -| [`thread.name`](../attributes-registry/thread.md) | string | Current thread name. | `main` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`thread.id`](../attributes-registry/thread.md) | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`thread.name`](../attributes-registry/thread.md) | string | Current thread name. | `main` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Examples of where `thread.id` and `thread.name` can be extracted from: @@ -382,14 +382,14 @@ The attributes listed below allow to report this unit of code and therefore to p about the span. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`code.column`](../attributes-registry/code.md) | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | Recommended | -| [`code.filepath`](../attributes-registry/code.md) | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | Recommended | -| [`code.function`](../attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | Recommended | -| [`code.lineno`](../attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | Recommended | -| [`code.namespace`](../attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | Recommended | -| [`code.stacktrace`](../attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`code.column`](../attributes-registry/code.md) | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.filepath`](../attributes-registry/code.md) | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.function`](../attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.lineno`](../attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.namespace`](../attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.stacktrace`](../attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/events.md b/docs/general/events.md index 51f4ef29d9..8f3e51c2f8 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -53,9 +53,9 @@ the event names have low-cardinality, so care must be taken to use fields that identify the class of Events but not the instance of the Event. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. diff --git a/docs/general/logs.md b/docs/general/logs.md index 152950057a..2debe8fc08 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -36,9 +36,9 @@ OpenTelemetry also defines the concept of overarching [Resources](https://github These attributes may be used for identifying a Log Record. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. @@ -57,12 +57,12 @@ As such, these should be recorded as Log Record attributes when applicable. They **Description:** A file to which log was emitted. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `log.file.name` | string | The basename of the file. | `audit.log` | Recommended | -| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | Opt-In | -| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | Opt-In | -| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `log.file.name` | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### I/O Stream @@ -70,16 +70,16 @@ As such, these should be recorded as Log Record attributes when applicable. They **Description:** The I/O stream to which the log was emitted. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `log.iostream` MUST be one of the following: -| Value | Description | -|---|---| -| `stdout` | Logs from stdout stream | -| `stderr` | Events from stderr stream | +| Value | Description | Stability | +|---|---|---| +| `stdout` | Logs from stdout stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stderr` | Events from stderr stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/session.md b/docs/general/session.md index 9c58d3fc44..8b0fa3d2f0 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -18,10 +18,10 @@ backends can link the two sessions. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | -| `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index bfac2262af..abdc34d4f8 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -25,18 +25,18 @@ between a child Span and a parent Span, as defined by [OpenTracing](https://github.com/opentracing/specification/blob/master/specification.md). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The causal relationship between a child Span and a parent Span. `opentracing.ref_type` MUST be one of the following: -| Value | Description | -|---|---| -| `child_of` | The parent Span depends on the child Span in some capacity | -| `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | +| Value | Description | Stability | +|---|---|---| +| `child_of` | The parent Span depends on the child Span in some capacity | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/graphql/graphql-spans.md b/docs/graphql/graphql-spans.md index fb94a7b25e..98d62a4b61 100644 --- a/docs/graphql/graphql-spans.md +++ b/docs/graphql/graphql-spans.md @@ -15,21 +15,21 @@ span SHOULD be named ``. When `` MAY be used as span name. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | Recommended | -| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | Recommended | -| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value may be sanitized to exclude sensitive information. `graphql.operation.type` MUST be one of the following: -| Value | Description | -|---|---| -| `query` | GraphQL query | -| `mutation` | GraphQL mutation | -| `subscription` | GraphQL subscription | +| Value | Description | Stability | +|---|---|---| +| `query` | GraphQL query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mutation` | GraphQL mutation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `subscription` | GraphQL subscription | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index f6e5d7ec3c..f61c862e63 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -59,8 +59,6 @@ operations. By adding HTTP attributes to metric events it allows for finely tune ### Metric: `http.server.request.duration` -**Status**: [Stable][DocumentStatus] - This metric is required. When this metric is reported alongside an HTTP server span, the metric value SHOULD be the same as the HTTP server span duration. @@ -70,25 +68,42 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.server.request.duration` | Histogram | `s` | Duration of HTTP server requests. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.server.request.duration` | Histogram | `s` | Duration of HTTP server requests. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | - -**[1]:** If the request fails with an error before response status code was sent or received, +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[3]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -105,83 +120,64 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) -and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods -(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - -**[3]:** 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. +**[4]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** The value SHOULD be normalized to lowercase. +**[5]:** The value SHOULD be normalized to lowercase. -**[5]:** If not `http` and `network.protocol.version` is set. +**[6]:** If not `http` and `network.protocol.version` is set. -**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[9]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. - -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.server.active_requests` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.server.active_requests` | UpDownCounter | `{request}` | Number of active HTTP server requests. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.server.active_requests` | UpDownCounter | `{request}` | Number of active HTTP server requests. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Required | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -208,50 +204,65 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.server.request.body.size` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.server.request.body.size` | Histogram | `By` | Size of HTTP server request bodies. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.server.request.body.size` | Histogram | `By` | Size of HTTP server request bodies. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** 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. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | - -**[1]:** If the request fails with an error before response status code was sent or received, +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[3]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -268,92 +279,90 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) -and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods -(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - -**[3]:** 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. +**[4]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** The value SHOULD be normalized to lowercase. +**[5]:** The value SHOULD be normalized to lowercase. -**[5]:** If not `http` and `network.protocol.version` is set. +**[6]:** If not `http` and `network.protocol.version` is set. -**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[9]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. - -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.server.response.body.size` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.server.response.body.size` | Histogram | `By` | Size of HTTP server response bodies. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.server.response.body.size` | Histogram | `By` | Size of HTTP server response bodies. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** 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. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | 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.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | Conditionally Required: [5] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [8] | `80`; `8080`; `443` | Opt-In | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | - -**[1]:** If the request fails with an error before response status code was sent or received, +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[3]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -370,70 +379,51 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) -and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods -(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - -**[3]:** 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. +**[4]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** The value SHOULD be normalized to lowercase. +**[5]:** The value SHOULD be normalized to lowercase. -**[5]:** If not `http` and `network.protocol.version` is set. +**[6]:** If not `http` and `network.protocol.version` is set. -**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[8]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[9]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). > **Warning** > Since this attribute is based on HTTP headers, opting in to it may allow an attacker > to trigger cardinality limits, degrading the usefulness of the metric. -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. - -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## HTTP Client ### Metric: `http.client.request.duration` -**Status**: [Stable][DocumentStatus] - This metric is required. When this metric is reported alongside an HTTP client span, the metric value SHOULD be the same as the HTTP client span duration. @@ -443,41 +433,24 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.request.duration` | Histogram | `s` | Duration of HTTP client requests. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.request.duration` | Histogram | `s` | Duration of HTTP client requests. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | - -**[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) -or a component-specific low cardinality error identifier. - -If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. - -The `error.type` value SHOULD be predictable and SHOULD have low cardinality. -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low, but -telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time, when no -additional filters are applied. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -492,82 +465,80 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** The value SHOULD be normalized to lowercase. +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[4]:** If not `http` and `network.protocol.version` is set. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[4]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. -**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. -`error.type` 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. +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. -| Value | Description | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -`http.request.method` 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. +**[5]:** The value SHOULD be normalized to lowercase. -| Value | Description | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +**[6]:** If not `http` and `network.protocol.version` is set. + +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. + +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.client.request.body.size` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.request.body.size` | Histogram | `By` | Size of HTTP client request bodies. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.request.body.size` | Histogram | `By` | Size of HTTP client request bodies. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** 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. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | - -**[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) -or a component-specific low cardinality error identifier. - -If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. - -The `error.type` value SHOULD be predictable and SHOULD have low cardinality. -Instrumentations SHOULD document the list of errors they report. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -The cardinality of `error.type` within one instrumentation library SHOULD be low, but -telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time, when no -additional filters are applied. - -If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -582,82 +553,80 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** The value SHOULD be normalized to lowercase. +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[4]:** If not `http` and `network.protocol.version` is set. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[4]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. -**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -`error.type` 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. +**[5]:** The value SHOULD be normalized to lowercase. -| Value | Description | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +**[6]:** If not `http` and `network.protocol.version` is set. -`http.request.method` 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. +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -| Value | Description | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.client.response.body.size` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.response.body.size` | Histogram | `By` | Size of HTTP client response bodies. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.response.body.size` | Histogram | `By` | Size of HTTP client response bodies. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** 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. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [3] | `http`; `spdy` | Conditionally Required: [4] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [5] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [7] | `80`; `8080`; `443` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | - -**[1]:** If the request fails with an error before response status code was sent or received, -`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) -or a component-specific low cardinality error identifier. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), -`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. - -The `error.type` value SHOULD be predictable and SHOULD have low cardinality. -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low, but -telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time, when no -additional filters are applied. - -If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. - -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -672,72 +641,87 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[3]:** The value SHOULD be normalized to lowercase. +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[4]:** If not `http` and `network.protocol.version` is set. +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[4]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. -**[5]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. -**[6]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. + +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5]:** The value SHOULD be normalized to lowercase. -`error.type` 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. +**[6]:** If not `http` and `network.protocol.version` is set. -| Value | Description | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | +**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -`http.request.method` 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.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +| Value | Description | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `http.client.open_connections` -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`http.connection.state`](../attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | Required | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [1] | `1.1`; `2` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.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` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.connection.state`](../attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[3]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -`http.connection.state` 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.connection.state` 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 | -|---|---| -| `active` | active state. | -| `idle` | idle state. | +| Value | Description | Stability | +|---|---|---| +| `active` | active state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `http.client.connection.duration` @@ -746,30 +730,28 @@ This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -**Status**: [Experimental][DocumentStatus] - This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.connection.duration` | Histogram | `s` | The duration of the successfully established outbound HTTP connections. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.connection.duration` | Histogram | `s` | The duration of the successfully established outbound HTTP connections. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [1] | `1.1`; `2` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.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` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[3]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. ### Metric: `http.client.active_requests` @@ -779,20 +761,24 @@ This metric is optional. This metric is optional. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | Recommended | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.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` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +**[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[3]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). @@ -807,24 +793,20 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. - -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index fcbadbf9b3..07309707c9 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -115,20 +115,35 @@ the specific attributes listed in the [HTTP client](#http-client) and [HTTP serv sections below. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | Conditionally Required: If request has ended with an error. | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [3] | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | Opt-In | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | Conditionally Required: If and only if one was received/sent. | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | Conditionally Required: [6] | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | Recommended | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | Opt-In | - -**[1]:** If the request fails with an error before response status code was sent or received, +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [7] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -145,68 +160,53 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) -and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). +**[3]:** If and only if it's different than `http.request.method`. -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. +**[4]:** The value SHOULD be normalized to lowercase. -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods -(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +**[5]:** If not `http` and `network.protocol.version` is set. -**[3]:** If and only if it's different than `http.request.method`. +**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[4]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[7]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. -**[5]:** The value SHOULD be normalized to lowercase. - -**[6]:** If not `http` and `network.protocol.version` is set. - -**[7]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. - **[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`http.request.method`](../attributes-registry/http.md) -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`http.request.method` 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 | -|---|---| -| `CONNECT` | CONNECT method. | -| `DELETE` | DELETE method. | -| `GET` | GET method. | -| `HEAD` | HEAD method. | -| `OPTIONS` | OPTIONS method. | -| `PATCH` | PATCH method. | -| `POST` | POST method. | -| `PUT` | PUT method. | -| `TRACE` | TRACE method. | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | - -`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`network.transport` 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 | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## HTTP client @@ -224,30 +224,30 @@ This span type represents an outbound HTTP request. There are two ways this can For an HTTP client span, `SpanKind` MUST be `Client`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [2] | `3` | Recommended: if and only if request was retried. | -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [4] | `80`; `8080`; `443` | Required | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [5] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Required | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | Opt-In | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | Opt-In | - -**[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -**[2]:** 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). +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [4] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[3]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. +**[1]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[5]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +**[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. +**[4]:** 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). + +**[5]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`server.address`](../attributes-registry/server.md) @@ -336,52 +336,52 @@ This span type represents an inbound HTTP request. For an HTTP server span, `SpanKind` MUST be `Server`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `83.164.160.102` | Recommended | -| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [2] | `65123` | Opt-In | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [3] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | Conditionally Required: If and only if it's available | -| [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | Opt-In | -| [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | Opt-In | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [6] | `80`; `8080`; `443` | Conditionally Required: If `server.address` is set. | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [7] | `/search` | Required | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [8] | `q=OpenTelemetry` | Conditionally Required: If and only if one was received/sent. | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [9] | `http`; `https` | Required | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | Recommended | - -**[1]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. - -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. - -**[3]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -**[4]:** 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. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [1] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [5] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [8] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [9] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. + +**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[3]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[5]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[4]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[6]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[5]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. -**[7]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. +**[6]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[8]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. +**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[9]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +**[8]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. + +**[9]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* [`client.address`](../attributes-registry/client.md) -* [`http.request.header.`](../attributes-registry/http.md) -* [`server.address`](../attributes-registry/server.md) -* [`server.port`](../attributes-registry/server.md) * [`url.path`](../attributes-registry/url.md) -* [`url.query`](../attributes-registry/url.md) * [`url.scheme`](../attributes-registry/url.md) +* [`server.port`](../attributes-registry/server.md) +* [`url.query`](../attributes-registry/url.md) +* [`client.address`](../attributes-registry/client.md) +* [`server.address`](../attributes-registry/server.md) * [`user_agent.original`](../attributes-registry/user-agent.md) +* [`http.request.header.`](../attributes-registry/http.md) `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index e9b49cc5cf..8626cb2c2c 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -25,12 +25,12 @@ The span name SHOULD follow [the general messaging span name pattern](../messagi The following additional attributes are defined: -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.servicebus.destination.subscription_name`](../attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | Conditionally Required: If messages are received from the subscription. | -| [`messaging.servicebus.disposition_status`](../attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | Conditionally Required: if and only if `messaging.operation` is `settle`. | -| [`messaging.servicebus.message.delivery_count`](../attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | Conditionally Required: [1] | -| [`messaging.servicebus.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.servicebus.destination.subscription_name`](../attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | `Conditionally Required` If messages are received from the subscription. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.disposition_status`](../attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | `Conditionally Required` if and only if `messaging.operation` is `settle`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.message.delivery_count`](../attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If delivery count is available and is bigger than 0. @@ -52,11 +52,11 @@ contain a low-cardinality name of an operation the span describes: The following additional attributes are defined: -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id messages are sent to or received from, unique within the Event Hub." | `1` | Conditionally Required: If available. | -| [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | Conditionally Required: If not default ("$Default"). | -| [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id messages are sent to or received from, unique within the Event Hub." | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 17b74081a9..ad3b6fa0fb 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -13,10 +13,11 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub ## Span attributes For Google Cloud Pub/Sub, the following additional attributes are defined: +<<<<<<< HEAD -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | Conditionally Required: If the message type has an ordering key set. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Examples diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 522c4c2a16..c1affa011a 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -24,18 +24,19 @@ described on this page. For Apache Kafka, the following additional attributes are defined: +<<<<<<< HEAD -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id the message (or batch) is sent to or received from."" | `1` | Recommended | -| [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | Recommended | -| [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | Recommended | -| [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | Recommended | -| [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | Conditionally Required: [2] | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id the message (or batch) is sent to or received from."" | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [2] | `myKey` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. +**[1]:** If value is `true`. When missing, the value is assumed to be `false`. -**[2]:** If value is `true`. When missing, the value is assumed to be `false`. +**[2]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. For Apache Kafka producers, [`peer.service`](/docs/general/attributes.md#general-remote-service-attributes) SHOULD be set to the name of the broker or service the message will be sent to. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 4f2678243c..63caaf8e14 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -30,14 +30,14 @@ All messaging metrics share the same set of attributes: -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | Conditionally Required: [4] | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | Conditionally Required: if available. | -| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | `Conditionally Required` if available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. @@ -68,26 +68,26 @@ the broker doesn't have such notion, the destination name SHOULD uniquely identi **[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`messaging.system` 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 | -|---|---| -| `activemq` | Apache ActiveMQ | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `eventgrid` | Azure Event Grid | -| `eventhubs` | Azure Event Hubs | -| `servicebus` | Azure Service Bus | -| `gcp_pubsub` | Google Cloud Pub/Sub | -| `jms` | Java Message Service | -| `kafka` | Apache Kafka | -| `rabbitmq` | RabbitMQ | -| `rocketmq` | Apache RocketMQ | +`messaging.system` 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 | Stability | +|---|---|---| +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Producer metrics @@ -103,9 +103,9 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.publish.duration` | Histogram | `s` | Measures the duration of publish operation. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.publish.duration` | Histogram | `s` | Measures the duration of publish operation. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `messaging.publish.messages` @@ -113,9 +113,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 This metric is [required][MetricRequired] when the messaging system supports batch publishing. It's [opt-in][MetricOptIn] when the messaging system does not support batch publishing, since the message count can be derived from the `messaging.publish.duration` histogram. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.publish.messages` | Counter | `{message}` | Measures the number of published messages. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.publish.messages` | Counter | `{message}` | Measures the number of published messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | > The need to report `messaging.publish.messages` depends on the messaging system capabilities and not application scenarios or client library limitations. For example, RabbitMQ does not support batch publishing and corresponding instrumentations don't need to report `messaging.publish.messages`. Kafka supports both, single and batch publishing, and instrumentations MUST report `messaging.publish.messages` counter regardless of application scenarios or APIs available in the client library. @@ -133,9 +133,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 When this metric is reported alongside a messaging receive span, the metric value SHOULD be the same as the corresponding span duration. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.receive.duration` | Histogram | `s` | Measures the duration of receive operation. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.receive.duration` | Histogram | `s` | Measures the duration of receive operation. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `messaging.receive.messages` @@ -145,9 +145,9 @@ This metric is [required][MetricRequired] for batch receive operations. It's [op _Note: The need to report `messaging.receive.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.receive.messages` | Counter | `{message}` | Measures the number of received messages. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.receive.messages` | Counter | `{message}` | Measures the number of received messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `messaging.process.duration` @@ -161,9 +161,9 @@ This metric SHOULD be specified with of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.process.duration` | Histogram | `s` | Measures the duration of process operation. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.process.duration` | Histogram | `s` | Measures the duration of process operation. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `messaging.process.messages` @@ -173,9 +173,9 @@ This metric is [required][MetricRequired] for batch process operations, and [rec _Note: The need to report `messaging.process.messages` depends on the messaging system capabilities and not application scenarios or client library limitations._ -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `messaging.process.messages` | Counter | `{message}` | Measures the number of processed messages. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `messaging.process.messages` | Counter | `{message}` | Measures the number of processed messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.21.0/specification/document-status.md diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index f78ad5993c..ee1204f99c 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -279,27 +279,29 @@ Messaging system-specific attributes MUST be defined in the corresponding `messa as described in [Attributes specific to certain messaging systems](#attributes-specific-to-certain-messaging-systems). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | Conditionally Required: [2] | -| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | Conditionally Required: [4] | -| [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | Recommended: If a client id is available | -| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | Conditionally Required: [5] | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | Conditionally Required: [7] | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | Conditionally Required: [9] | -| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | Conditionally Required: [10] | -| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [11] | `1439` | Recommended | -| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | Recommended | -| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [12] | `2738` | Recommended | -| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | Recommended | -| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [13] | `publish` | Required | -| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | Required | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [14] | `10.1.2.80`; `/tmp/my.sock` | Recommended: If applicable for this messaging system. | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | Recommended: if and only if `network.peer.address` is set. | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [15] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Conditionally Required: If available. | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | Recommended | - -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [1] | `publish` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** If a custom value is used, it MUST be of low cardinality. + +**[2]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. @@ -315,71 +317,69 @@ it's RECOMMENDED to: * Use a domain-specific attribute * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -**[2]:** If and only if the messaging operation has failed. +**[3]:** If and only if the messaging operation has failed. -**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +**[4]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. -**[4]:** If the span describes an operation on a batch of messages. +**[5]:** If the span describes an operation on a batch of messages. -**[5]:** If value is `true`. When missing, the value is assumed to be `false`. +**[6]:** If value is `true`. When missing, the value is assumed to be `false`. -**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[7]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. -**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[9]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[10]:** If value is `true`. When missing, the value is assumed to be `false`. +**[11]:** If value is `true`. When missing, the value is assumed to be `false`. -**[11]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[12]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[13]:** If a custom value is used, it MUST be of low cardinality. - -**[14]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[15]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - **[16]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`error.type` 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 | -|---|---| -| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | - -`messaging.operation` 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 | -|---|---| -| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | -| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | -| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | -| `process` | One or more messages are delivered to or processed by a consumer. | -| `settle` | One or more messages are settled. | - -`messaging.system` 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 | -|---|---| -| `activemq` | Apache ActiveMQ | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | -| `eventgrid` | Azure Event Grid | -| `eventhubs` | Azure Event Hubs | -| `servicebus` | Azure Service Bus | -| `gcp_pubsub` | Google Cloud Pub/Sub | -| `jms` | Java Message Service | -| `kafka` | Apache Kafka | -| `rabbitmq` | RabbitMQ | -| `rocketmq` | Apache RocketMQ | +`messaging.operation` 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 | Stability | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.system` 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 | Stability | +|---|---|---| +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Consumer attributes @@ -394,10 +394,10 @@ consumer instrumentations SHOULD populate the attributes under the namespace `messaging.destination_publish.*` -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.destination_publish.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | Recommended | -| [`messaging.destination_publish.name`](../attributes-registry/messaging.md) | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.destination_publish.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination_publish.name`](../attributes-registry/messaging.md) | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 7852546f4d..6b792e3784 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -17,13 +17,14 @@ described on this page. In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. `messaging.destination.name` MUST be set to the name of the exchange. This will be an empty string if the default exchange is used. +<<<<<<< HEAD -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | Conditionally Required: If not empty. | -| [`messaging.rabbitmq.message.delivery_tag`](../attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | Conditionally Required: When available. | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | `Conditionally Required` If not empty. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rabbitmq.message.delivery_tag`](../attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | `Conditionally Required` When available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index eb0d8b3d5d..5454938a73 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -16,18 +16,19 @@ described on this page. Specific attributes for Apache RocketMQ are defined below. +<<<<<<< HEAD -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`messaging.rocketmq.client_group`](../attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | Required | -| [`messaging.rocketmq.consumption_model`](../attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering` | Recommended | -| [`messaging.rocketmq.message.delay_time_level`](../attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | Conditionally Required: [1] | -| [`messaging.rocketmq.message.delivery_timestamp`](../attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | Conditionally Required: [2] | -| [`messaging.rocketmq.message.group`](../attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | Conditionally Required: If the message type is FIFO. | -| [`messaging.rocketmq.message.keys`](../attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | Recommended | -| [`messaging.rocketmq.message.tag`](../attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | Recommended | -| [`messaging.rocketmq.message.type`](../attributes-registry/messaging.md) | string | Type of message. | `normal` | Recommended | -| [`messaging.rocketmq.namespace`](../attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`messaging.rocketmq.client_group`](../attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.namespace`](../attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delay_time_level`](../attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delivery_timestamp`](../attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.group`](../attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | `Conditionally Required` If the message type is FIFO. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.consumption_model`](../attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.keys`](../attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.tag`](../attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.type`](../attributes-registry/messaging.md) | string | Type of message. | `normal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the message type is delay and delivery timestamp is not specified. @@ -35,19 +36,19 @@ Specific attributes for Apache RocketMQ are defined below. `messaging.rocketmq.consumption_model` MUST be one of the following: -| Value | Description | -|---|---| -| `clustering` | Clustering consumption model | -| `broadcasting` | Broadcasting consumption model | +| Value | Description | Stability | +|---|---|---| +| `clustering` | Clustering consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `broadcasting` | Broadcasting consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.rocketmq.message.type` MUST be one of the following: -| Value | Description | -|---|---| -| `normal` | Normal message | -| `fifo` | FIFO message | -| `delay` | Delay message | -| `transaction` | Transaction message | +| Value | Description | Stability | +|---|---|---| +| `normal` | Normal message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fifo` | FIFO message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delay` | Delay message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `transaction` | Transaction message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.client_id` SHOULD be set to the client ID that is automatically generated by the Apache RocketMQ SDK. diff --git a/docs/mobile/events.md b/docs/mobile/events.md index e626f2c9c3..dd33a06cdd 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -26,21 +26,21 @@ mobile operating system (e.g. Android, iOS). The event name MUST be `device.app.lifecycle`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. `ios.state` MUST be one of the following: -| Value | Description | -|---|---| -| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | -| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | -| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | -| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | -| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | +| Value | Description | Stability | +|---|---|---| +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Android @@ -48,19 +48,19 @@ The event name MUST be `device.app.lifecycle`. The event name MUST be `device.app.lifecycle`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. `android.state` MUST be one of the following: -| Value | Description | -|---|---| -| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | -| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | -| `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | +| Value | Description | Stability | +|---|---|---| +| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index 4b5a0f4dfd..9f157352f1 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -12,14 +12,14 @@ that describe common AWS SDK attributes in addition to the Semantic Conventions described on this page. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | Recommended | -| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | Recommended | -| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | Recommended | -| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | Recommended | -| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | Recommended | -| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. diff --git a/docs/resource/README.md b/docs/resource/README.md index 5c62168b6c..18e8e6dbb1 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -80,10 +80,10 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **Description:** A service instance. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `service.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Logical name of the service. [1] | `shoppingcart` | Required | -| `service.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `service.name` | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. @@ -97,10 +97,10 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet **Description:** Additions to service instance. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | Recommended | -| `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to @@ -155,11 +155,11 @@ service.name = Shop.shoppingcart **Description:** The telemetry SDK used to capture data recorded by the instrumentation libraries. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `telemetry.sdk.language` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The language of the telemetry SDK. | `cpp` | Required | -| `telemetry.sdk.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The name of the telemetry SDK as defined above. [1] | `opentelemetry` | Required | -| `telemetry.sdk.version` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The version string of the telemetry SDK. | `1.2.3` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the @@ -168,22 +168,22 @@ or another suitable identifier depending on the language. The identifier `opentelemetry` is reserved and MUST NOT be used in this case. All custom identifiers SHOULD be stable across different versions of an implementation. -`telemetry.sdk.language` 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 | -|---|---| -| `cpp` | cpp | -| `dotnet` | dotnet | -| `erlang` | erlang | -| `go` | go | -| `java` | java | -| `nodejs` | nodejs | -| `php` | php | -| `python` | python | -| `ruby` | ruby | -| `rust` | rust | -| `swift` | swift | -| `webjs` | webjs | +`telemetry.sdk.language` 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 | Stability | +|---|---|---| +| `cpp` | cpp | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `dotnet` | dotnet | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `erlang` | erlang | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `go` | go | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `java` | java | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `nodejs` | nodejs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `php` | php | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `python` | python | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ruby` | ruby | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `rust` | rust | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `swift` | swift | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `webjs` | webjs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Telemetry SDK (Experimental) @@ -195,10 +195,10 @@ All custom identifiers SHOULD be stable across different versions of an implemen **Description:** Additions to the telemetry SDK. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | Recommended | -| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. diff --git a/docs/resource/android.md b/docs/resource/android.md index aa635d29ef..ab94f1cc98 100644 --- a/docs/resource/android.md +++ b/docs/resource/android.md @@ -7,9 +7,9 @@ **Description**: The Android platform on which the Android application is running. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`android.os.api_level`](../attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`android.os.api_level`](../attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/browser.md b/docs/resource/browser.md index da7818bb5f..4ab2541c1c 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -9,13 +9,13 @@ All of these attributes can be provided by the user agent itself in the form of an HTTP header (e.g. Sec-CH-UA, Sec-CH-Platform, User-Agent). However, the headers could be removed by proxy servers, and are tied to calls from individual clients. In order to support batching through services like the Collector and to prevent loss of data (e.g. due to proxy servers removing headers), these attributes should be used when possible. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`browser.brands`](../attributes-registry/browser.md) | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | Recommended | -| [`browser.language`](../attributes-registry/browser.md) | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | Recommended | -| [`browser.mobile`](../attributes-registry/browser.md) | boolean | A boolean that is true if the browser is running on a mobile device [3] | | Recommended | -| [`browser.platform`](../attributes-registry/browser.md) | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | Recommended | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`browser.brands`](../attributes-registry/browser.md) | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.language`](../attributes-registry/browser.md) | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.mobile`](../attributes-registry/browser.md) | boolean | A boolean that is true if the browser is running on a mobile device [3] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.platform`](../attributes-registry/browser.md) | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index 2edafe56b9..a8fe3942bc 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -7,22 +7,22 @@ **Description:** Resources used by AWS Elastic Container Service (ECS). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | Recommended | -| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | Recommended | -| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | Recommended | -| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | Recommended | -| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | Recommended | -| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | Conditionally Required: If and only if `task.arn` is populated. | -| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Conditionally Required` If and only if `task.arn` is populated. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `aws.ecs.launchtype` MUST be one of the following: -| Value | Description | -|---|---| -| `ec2` | ec2 | -| `fargate` | fargate | +| Value | Description | Stability | +|---|---|---| +| `ec2` | ec2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fargate` | fargate | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/eks.md b/docs/resource/cloud-provider/aws/eks.md index 9bc4e42500..a52ac56557 100644 --- a/docs/resource/cloud-provider/aws/eks.md +++ b/docs/resource/cloud-provider/aws/eks.md @@ -7,9 +7,9 @@ **Description:** Resources used by AWS Elastic Kubernetes Service (EKS). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index 6d7606664d..95558b7b77 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -7,12 +7,12 @@ **Description:** Log attributes for Amazon Web Services. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | Recommended | -| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | Recommended | -| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | Recommended | -| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index 1f79773078..e188ddf688 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -9,10 +9,10 @@ These conventions are recommended for resources running on Cloud Run. **Description:** Resource attributes for Cloud Run. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp-cloud-run.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | Recommended | -| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp-cloud-run.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp-cloud-run.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp-cloud-run.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/gce.md b/docs/resource/cloud-provider/gcp/gce.md index 4e2855ed76..347388be66 100644 --- a/docs/resource/cloud-provider/gcp/gce.md +++ b/docs/resource/cloud-provider/gcp/gce.md @@ -5,8 +5,8 @@ **Description:** Resource attributes for GCE instances. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp-gce.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | Recommended | -| [`gcp.gce.instance.name`](../../../attributes-registry/gcp-gce.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp-gce.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.gce.instance.name`](../../../attributes-registry/gcp-gce.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index 7e20ce9e47..244133673e 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -7,11 +7,11 @@ **Description:** [Heroku dyno metadata] -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | Opt-In | -| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | Opt-In | -| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **Mapping:** diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index 8d047494b4..b112f948d5 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -7,14 +7,14 @@ **Description:** A cloud infrastructure (e.g. GCP, Azure, AWS). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`cloud.account.id`](../attributes-registry/cloud.md) | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | Recommended | -| [`cloud.availability_zone`](../attributes-registry/cloud.md) | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | Recommended | -| [`cloud.platform`](../attributes-registry/cloud.md) | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | Recommended | -| [`cloud.provider`](../attributes-registry/cloud.md) | string | Name of the cloud provider. | `alibaba_cloud` | Recommended | -| [`cloud.region`](../attributes-registry/cloud.md) | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | Recommended | -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloud.account.id`](../attributes-registry/cloud.md) | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.availability_zone`](../attributes-registry/cloud.md) | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.platform`](../attributes-registry/cloud.md) | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.provider`](../attributes-registry/cloud.md) | string | Name of the cloud provider. | `alibaba_cloud` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.region`](../attributes-registry/cloud.md) | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. @@ -40,50 +40,50 @@ The following well-known definitions MUST be used if you set this attribute and This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. -`cloud.platform` 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. +`cloud.platform` 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 | -|---|---| -| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | -| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | -| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | -| `aws_ec2` | AWS Elastic Compute Cloud | -| `aws_ecs` | AWS Elastic Container Service | -| `aws_eks` | AWS Elastic Kubernetes Service | -| `aws_lambda` | AWS Lambda | -| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | -| `aws_app_runner` | AWS App Runner | -| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | -| `azure_vm` | Azure Virtual Machines | -| `azure_container_apps` | Azure Container Apps | -| `azure_container_instances` | Azure Container Instances | -| `azure_aks` | Azure Kubernetes Service | -| `azure_functions` | Azure Functions | -| `azure_app_service` | Azure App Service | -| `azure_openshift` | Azure Red Hat OpenShift | -| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | -| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | -| `gcp_cloud_run` | Google Cloud Run | -| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | -| `gcp_cloud_functions` | Google Cloud Functions (GCF) | -| `gcp_app_engine` | Google Cloud App Engine (GAE) | -| `gcp_openshift` | Red Hat OpenShift on Google Cloud | -| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | -| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | -| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | -| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ec2` | AWS Elastic Compute Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ecs` | AWS Elastic Container Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_eks` | AWS Elastic Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_lambda` | AWS Lambda | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_app_runner` | AWS App Runner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_vm` | Azure Virtual Machines | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_apps` | Azure Container Apps | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_instances` | Azure Container Instances | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_aks` | Azure Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_functions` | Azure Functions | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_app_service` | Azure App Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_openshift` | Azure Red Hat OpenShift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_run` | Google Cloud Run | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_functions` | Google Cloud Functions (GCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_app_engine` | Google Cloud App Engine (GAE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_openshift` | Red Hat OpenShift on Google Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`cloud.provider` 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. +`cloud.provider` 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 | -|---|---| -| `alibaba_cloud` | Alibaba Cloud | -| `aws` | Amazon Web Services | -| `azure` | Microsoft Azure | -| `gcp` | Google Cloud Platform | -| `heroku` | Heroku Platform as a Service | -| `ibm_cloud` | IBM Cloud | -| `tencent_cloud` | Tencent Cloud | +| Value | Description | Stability | +|---|---|---| +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku` | Heroku Platform as a Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud` | IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/container.md b/docs/resource/container.md index 7606ce6178..4f5ddb2211 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -7,31 +7,31 @@ **Description:** A container instance. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`container.command`](../attributes-registry/container.md) | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | Opt-In | -| [`container.command_args`](../attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | Opt-In | -| [`container.command_line`](../attributes-registry/container.md) | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | Opt-In | -| [`container.id`](../attributes-registry/container.md) | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | Recommended | -| [`container.image.id`](../attributes-registry/container.md) | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | Recommended | -| [`container.image.name`](../attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | Recommended | -| [`container.image.repo_digests`](../attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | Recommended | -| [`container.image.tags`](../attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | Recommended | -| [`container.label.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | Recommended | -| [`container.name`](../attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | Recommended | -| [`container.runtime`](../attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | Recommended | -| [`oci.manifest.digest`](../attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [4] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | Recommended | - -**[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. - -**[2]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`container.id`](../attributes-registry/container.md) | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.id`](../attributes-registry/container.md) | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [1] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.name`](../attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.repo_digests`](../attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [2] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.tags`](../attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.label.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.name`](../attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.runtime`](../attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`oci.manifest.digest`](../attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [3] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command`](../attributes-registry/container.md) | string | The command used to run the container (i.e. the command name). [4] | `otelcontribcol` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command_args`](../attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command_line`](../attributes-registry/container.md) | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. -**[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. +**[2]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. -**[4]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). +**[3]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). + +**[4]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index 12301f3ae5..7957a9a3ff 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -7,9 +7,9 @@ **Description:** The software deployment. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`deployment.environment`](../attributes-registry/deployment.md) | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`deployment.environment`](../attributes-registry/deployment.md) | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** `deployment.environment` does not affect the uniqueness constraints defined through the `service.namespace`, `service.name` and `service.instance.id` resource attributes. diff --git a/docs/resource/device.md b/docs/resource/device.md index 57bd6dea97..603ef93c51 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -7,12 +7,12 @@ **Description**: The device on which the process represented by this resource is running. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`device.id`](../attributes-registry/device.md) | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | Recommended | -| [`device.manufacturer`](../attributes-registry/device.md) | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | Recommended | -| [`device.model.identifier`](../attributes-registry/device.md) | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | Recommended | -| [`device.model.name`](../attributes-registry/device.md) | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`device.id`](../attributes-registry/device.md) | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.manufacturer`](../attributes-registry/device.md) | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.model.identifier`](../attributes-registry/device.md) | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.model.name`](../attributes-registry/device.md) | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. diff --git a/docs/resource/faas.md b/docs/resource/faas.md index b354c2fdad..c7c3bc76d5 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -14,15 +14,32 @@ See also: ## FaaS resource attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | Recommended | -| [`faas.instance`](../attributes-registry/faas.md) | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | Recommended | -| [`faas.max_memory`](../attributes-registry/faas.md) | int | The amount of memory available to the serverless function converted to Bytes. [3] | `134217728` | Recommended | -| [`faas.name`](../attributes-registry/faas.md) | string | The name of the single function that this runtime instance executes. [4] | `my-function`; `myazurefunctionapp/some-function-name` | Required | -| [`faas.version`](../attributes-registry/faas.md) | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | Recommended | - -**[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`faas.name`](../attributes-registry/faas.md) | string | The name of the single function that this runtime instance executes. [1] | `my-function`; `myazurefunctionapp/some-function-name` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [2] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.instance`](../attributes-registry/faas.md) | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [3] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.max_memory`](../attributes-registry/faas.md) | int | The amount of memory available to the serverless function converted to Bytes. [4] | `134217728` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.version`](../attributes-registry/faas.md) | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the name of the function as configured/deployed on the FaaS +platform and is usually different from the name of the callback +function (which may be stored in the +[`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) +span attributes). + +For some cloud providers, the above definition is ambiguous. The following +definition of function name MUST be used for this attribute +(and consequently the span name) for the listed cloud providers/products: + +* **Azure:** The full name `/`, i.e., function app name + followed by a forward slash followed by the function name (this form + can also be seen in the resource JSON for the function). + This means that a span attribute MUST be used, as an Azure function + app can host multiple functions that would usually share + a TracerProvider (see also the `cloud.resource_id` attribute). + +**[2]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. The exact value to use for `cloud.resource_id` depends on the cloud provider. @@ -40,26 +57,9 @@ The following well-known definitions MUST be used if you set this attribute and This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. -**[2]:** * **AWS Lambda:** Use the (full) log stream name. +**[3]:** * **AWS Lambda:** Use the (full) log stream name. -**[3]:** It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). - -**[4]:** This is the name of the function as configured/deployed on the FaaS -platform and is usually different from the name of the callback -function (which may be stored in the -[`code.namespace`/`code.function`](/docs/general/attributes.md#source-code-attributes) -span attributes). - -For some cloud providers, the above definition is ambiguous. The following -definition of function name MUST be used for this attribute -(and consequently the span name) for the listed cloud providers/products: - -* **Azure:** The full name `/`, i.e., function app name - followed by a forward slash followed by the function name (this form - can also be seen in the resource JSON for the function). - This means that a span attribute MUST be used, as an Azure function - app can host multiple functions that would usually share - a TracerProvider (see also the `cloud.resource_id` attribute). +**[4]:** It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). **[5]:** Depending on the cloud provider and platform, use: diff --git a/docs/resource/host.md b/docs/resource/host.md index da04a28970..7eb33feb17 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -10,47 +10,47 @@ The `host.*` namespace SHOULD be exclusively used to capture resource attributes To report host metrics, the `system.*` namespace SHOULD be used. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`host.arch`](../attributes-registry/host.md) | string | The CPU architecture the host system is running on. | `amd64` | Recommended | -| [`host.id`](../attributes-registry/host.md) | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | Recommended | -| [`host.image.id`](../attributes-registry/host.md) | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | Recommended | -| [`host.image.name`](../attributes-registry/host.md) | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | Recommended | -| [`host.image.version`](../attributes-registry/host.md) | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | Recommended | -| [`host.ip`](../attributes-registry/host.md) | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | Opt-In | -| [`host.mac`](../attributes-registry/host.md) | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | Opt-In | -| [`host.name`](../attributes-registry/host.md) | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | Recommended | -| [`host.type`](../attributes-registry/host.md) | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`host.arch`](../attributes-registry/host.md) | string | The CPU architecture the host system is running on. | `amd64` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.id`](../attributes-registry/host.md) | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.id`](../attributes-registry/host.md) | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.name`](../attributes-registry/host.md) | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.version`](../attributes-registry/host.md) | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.name`](../attributes-registry/host.md) | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.type`](../attributes-registry/host.md) | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.ip`](../attributes-registry/host.md) | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.mac`](../attributes-registry/host.md) | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. **[2]:** MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. -`host.arch` 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 | -|---|---| -| `amd64` | AMD64 | -| `arm32` | ARM32 | -| `arm64` | ARM64 | -| `ia64` | Itanium | -| `ppc32` | 32-bit PowerPC | -| `ppc64` | 64-bit PowerPC | -| `s390x` | IBM z/Architecture | -| `x86` | 32-bit x86 | +`host.arch` 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 | Stability | +|---|---|---| +| `amd64` | AMD64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm32` | ARM32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm64` | ARM64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ia64` | Itanium | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc32` | 32-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc64` | 64-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `s390x` | IBM z/Architecture | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `x86` | 32-bit x86 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **type:** `host.cpu` -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`host.cpu.cache.l2.size`](../attributes-registry/host.md) | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | Opt-In | -| [`host.cpu.family`](../attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | Opt-In | -| [`host.cpu.model.id`](../attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | Opt-In | -| [`host.cpu.model.name`](../attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | Opt-In | -| [`host.cpu.stepping`](../attributes-registry/host.md) | string | Stepping or core revisions. | `1`; `r1p1` | Opt-In | -| [`host.cpu.vendor.id`](../attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`host.cpu.cache.l2.size`](../attributes-registry/host.md) | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.family`](../attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.model.id`](../attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.model.name`](../attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.stepping`](../attributes-registry/host.md) | string | Stepping or core revisions. | `1`; `r1p1` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.vendor.id`](../attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index 1dd9a9fdee..f67ad0957b 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -22,10 +22,10 @@ Kubernetes object, but "name" is usually more user friendly so can be also set. **Description:** A Kubernetes Cluster. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.cluster.name`](../attributes-registry/k8s.md) | string | The name of the cluster. | `opentelemetry-cluster` | Recommended | -| [`k8s.cluster.uid`](../attributes-registry/k8s.md) | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.cluster.name`](../attributes-registry/k8s.md) | string | The name of the cluster. | `opentelemetry-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cluster.uid`](../attributes-registry/k8s.md) | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the @@ -58,10 +58,10 @@ conflict. **Description:** A Kubernetes Node. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.node.name`](../attributes-registry/k8s.md) | string | The name of the Node. | `node-1` | Recommended | -| [`k8s.node.uid`](../attributes-registry/k8s.md) | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.node.name`](../attributes-registry/k8s.md) | string | The name of the Node. | `node-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.node.uid`](../attributes-registry/k8s.md) | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Namespace @@ -74,9 +74,9 @@ a namespace, but not across namespaces. **Description:** A Kubernetes Namespace. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.namespace.name`](../attributes-registry/k8s.md) | string | The name of the namespace that the pod is running in. | `default` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.namespace.name`](../attributes-registry/k8s.md) | string | The name of the namespace that the pod is running in. | `default` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Pod @@ -89,12 +89,12 @@ containers on your cluster. **Description:** A Kubernetes Pod object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.pod.annotation.`](../attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | Opt-In | -| [`k8s.pod.label.`](../attributes-registry/k8s.md) | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | Recommended | -| [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | Recommended | -| [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.pod.label.`](../attributes-registry/k8s.md) | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.name`](../attributes-registry/k8s.md) | string | The name of the Pod. | `opentelemetry-pod-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.uid`](../attributes-registry/k8s.md) | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.pod.annotation.`](../attributes-registry/k8s.md) | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Container @@ -111,10 +111,10 @@ to a running container. **Description:** A container in a [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.container.name`](../attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | Recommended | -| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.container.name`](../attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## ReplicaSet @@ -127,10 +127,10 @@ any given time. **Description:** A Kubernetes ReplicaSet object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.replicaset.name`](../attributes-registry/k8s.md) | string | The name of the ReplicaSet. | `opentelemetry` | Recommended | -| [`k8s.replicaset.uid`](../attributes-registry/k8s.md) | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.replicaset.name`](../attributes-registry/k8s.md) | string | The name of the ReplicaSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.replicaset.uid`](../attributes-registry/k8s.md) | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Deployment @@ -144,10 +144,10 @@ distributed among the nodes of a cluster. **Description:** A Kubernetes Deployment object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.deployment.name`](../attributes-registry/k8s.md) | string | The name of the Deployment. | `opentelemetry` | Recommended | -| [`k8s.deployment.uid`](../attributes-registry/k8s.md) | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.deployment.name`](../attributes-registry/k8s.md) | string | The name of the Deployment. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.deployment.uid`](../attributes-registry/k8s.md) | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## StatefulSet @@ -160,10 +160,10 @@ about the ordering and uniqueness of these Pods. **Description:** A Kubernetes StatefulSet object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.statefulset.name`](../attributes-registry/k8s.md) | string | The name of the StatefulSet. | `opentelemetry` | Recommended | -| [`k8s.statefulset.uid`](../attributes-registry/k8s.md) | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.statefulset.name`](../attributes-registry/k8s.md) | string | The name of the StatefulSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.statefulset.uid`](../attributes-registry/k8s.md) | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DaemonSet @@ -175,10 +175,10 @@ A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. **Description:** A Kubernetes DaemonSet object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.daemonset.name`](../attributes-registry/k8s.md) | string | The name of the DaemonSet. | `opentelemetry` | Recommended | -| [`k8s.daemonset.uid`](../attributes-registry/k8s.md) | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.daemonset.name`](../attributes-registry/k8s.md) | string | The name of the DaemonSet. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.daemonset.uid`](../attributes-registry/k8s.md) | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Job @@ -191,10 +191,10 @@ successfully terminate. **Description:** A Kubernetes Job object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.job.name`](../attributes-registry/k8s.md) | string | The name of the Job. | `opentelemetry` | Recommended | -| [`k8s.job.uid`](../attributes-registry/k8s.md) | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.job.name`](../attributes-registry/k8s.md) | string | The name of the Job. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.job.uid`](../attributes-registry/k8s.md) | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## CronJob @@ -206,10 +206,10 @@ A CronJob creates Jobs on a repeating schedule. **Description:** A Kubernetes CronJob object. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`k8s.cronjob.name`](../attributes-registry/k8s.md) | string | The name of the CronJob. | `opentelemetry` | Recommended | -| [`k8s.cronjob.uid`](../attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`k8s.cronjob.name`](../attributes-registry/k8s.md) | string | The name of the CronJob. | `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.cronjob.uid`](../attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/os.md b/docs/resource/os.md index 4b681018d9..02fb418bea 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -9,29 +9,29 @@ In case of virtualized environments, this is the operating system as it is observed by the process, i.e., the virtualized guest rather than the underlying host. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`os.build_id`](../attributes-registry/os.md) | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | Recommended | -| [`os.description`](../attributes-registry/os.md) | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | Recommended | -| [`os.name`](../attributes-registry/os.md) | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | Recommended | -| [`os.type`](../attributes-registry/os.md) | string | The operating system type. | `windows` | Required | -| [`os.version`](../attributes-registry/os.md) | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | Recommended | - -`os.type` 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 | -|---|---| -| `windows` | Microsoft Windows | -| `linux` | Linux | -| `darwin` | Apple Darwin | -| `freebsd` | FreeBSD | -| `netbsd` | NetBSD | -| `openbsd` | OpenBSD | -| `dragonflybsd` | DragonFly BSD | -| `hpux` | HP-UX (Hewlett Packard Unix) | -| `aix` | AIX (Advanced Interactive eXecutive) | -| `solaris` | SunOS, Oracle Solaris | -| `z_os` | IBM z/OS | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`os.type`](../attributes-registry/os.md) | string | The operating system type. | `windows` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.build_id`](../attributes-registry/os.md) | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.description`](../attributes-registry/os.md) | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.name`](../attributes-registry/os.md) | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.version`](../attributes-registry/os.md) | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`os.type` 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 | Stability | +|---|---|---| +| `windows` | Microsoft Windows | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `linux` | Linux | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `darwin` | Apple Darwin | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `freebsd` | FreeBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netbsd` | NetBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openbsd` | OpenBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dragonflybsd` | DragonFly BSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hpux` | HP-UX (Hewlett Packard Unix) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aix` | AIX (Advanced Interactive eXecutive) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `solaris` | SunOS, Oracle Solaris | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `z_os` | IBM z/OS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/resource/process.md b/docs/resource/process.md index 36403a2de4..f52861ee86 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -25,16 +25,16 @@ **Description:** An operating system process. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | Conditionally Required: See alternative attributes below. | -| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | Conditionally Required: See alternative attributes below. | -| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | Conditionally Required: See alternative attributes below. | -| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | Conditionally Required: See alternative attributes below. | -| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | Conditionally Required: See alternative attributes below. | -| [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | Recommended | -| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | Recommended | -| [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **Additional attribute requirements:** At least one of the following sets of attributes is required: @@ -60,11 +60,11 @@ In that case it MUST be interpreted as if it was `process.command_args`. **Description:** The single (language) runtime instance which is monitored. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`process.runtime.description`](../attributes-registry/process.md) | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | Recommended | -| [`process.runtime.name`](../attributes-registry/process.md) | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | Recommended | -| [`process.runtime.version`](../attributes-registry/process.md) | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`process.runtime.description`](../attributes-registry/process.md) | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.runtime.name`](../attributes-registry/process.md) | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.runtime.version`](../attributes-registry/process.md) | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | How to set these attributes for particular runtime kinds is described in the following subsections. diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 0d23bbdd1b..6589e85faf 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -7,11 +7,11 @@ **Description:** Resource describing the packaged software running the application code. Web engines are typically executed using process.runtime. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | Recommended | -| `webengine.name` | string | The name of the web engine. | `WildFly` | Required | -| `webengine.version` | string | The version of the web engine. | `21.0.0` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `webengine.name` | string | The name of the web engine. | `WildFly` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `webengine.version` | string | The version of the web engine. | `21.0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Information describing the web engine SHOULD be captured using the values acquired from the API provided by the web engine, preferably during runtime, to avoid maintenance burden on engine version upgrades. As an example - Java engines are often but not always packaged as application servers. For Java application servers supporting Servlet API the required information MAY be captured by invoking `ServletContext.getServerInfo()` during runtime and parsing the result. diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index dd590f75dd..8cebaabebf 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -17,11 +17,11 @@ described on this page. Below is a table of attributes that SHOULD be included on client and server Connect RPC measurements. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`rpc.connect_rpc.error_code`](../attributes-registry/rpc.md) | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | Conditionally Required: [1] | -| [`rpc.connect_rpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| [`rpc.connect_rpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.connect_rpc.error_code`](../attributes-registry/rpc.md) | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.connect_rpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.connect_rpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If response is not successful and if error code available. @@ -31,24 +31,24 @@ Below is a table of attributes that SHOULD be included on client and server Conn `rpc.connect_rpc.error_code` MUST be one of the following: -| Value | Description | -|---|---| -| `cancelled` | cancelled | -| `unknown` | unknown | -| `invalid_argument` | invalid_argument | -| `deadline_exceeded` | deadline_exceeded | -| `not_found` | not_found | -| `already_exists` | already_exists | -| `permission_denied` | permission_denied | -| `resource_exhausted` | resource_exhausted | -| `failed_precondition` | failed_precondition | -| `aborted` | aborted | -| `out_of_range` | out_of_range | -| `unimplemented` | unimplemented | -| `internal` | internal | -| `unavailable` | unavailable | -| `data_loss` | data_loss | -| `unauthenticated` | unauthenticated | +| Value | Description | Stability | +|---|---|---| +| `cancelled` | cancelled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `invalid_argument` | invalid_argument | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `deadline_exceeded` | deadline_exceeded | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `not_found` | not_found | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `already_exists` | already_exists | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `permission_denied` | permission_denied | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `resource_exhausted` | resource_exhausted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `failed_precondition` | failed_precondition | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aborted` | aborted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out_of_range` | out_of_range | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unimplemented` | unimplemented | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `internal` | internal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `data_loss` | data_loss | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unauthenticated` | unauthenticated | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Connect RPC Status diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 100f17dc4b..32ce3d5f7a 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -17,11 +17,11 @@ described on this page. Below is a table of attributes that SHOULD be included on client and server gRPC measurements. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`rpc.grpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | Opt-In | -| [`rpc.grpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | Opt-In | -| [`rpc.grpc.status_code`](../attributes-registry/rpc.md) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.grpc.status_code`](../attributes-registry/rpc.md) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.grpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.grpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -29,25 +29,25 @@ Below is a table of attributes that SHOULD be included on client and server gRPC `rpc.grpc.status_code` MUST be one of the following: -| Value | Description | -|---|---| -| `0` | OK | -| `1` | CANCELLED | -| `2` | UNKNOWN | -| `3` | INVALID_ARGUMENT | -| `4` | DEADLINE_EXCEEDED | -| `5` | NOT_FOUND | -| `6` | ALREADY_EXISTS | -| `7` | PERMISSION_DENIED | -| `8` | RESOURCE_EXHAUSTED | -| `9` | FAILED_PRECONDITION | -| `10` | ABORTED | -| `11` | OUT_OF_RANGE | -| `12` | UNIMPLEMENTED | -| `13` | INTERNAL | -| `14` | UNAVAILABLE | -| `15` | DATA_LOSS | -| `16` | UNAUTHENTICATED | +| Value | Description | Stability | +|---|---|---| +| `0` | OK | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `1` | CANCELLED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `2` | UNKNOWN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `3` | INVALID_ARGUMENT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `4` | DEADLINE_EXCEEDED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `5` | NOT_FOUND | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `6` | ALREADY_EXISTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `7` | PERMISSION_DENIED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `8` | RESOURCE_EXHAUSTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `9` | FAILED_PRECONDITION | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `10` | ABORTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `11` | OUT_OF_RANGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `12` | UNIMPLEMENTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `13` | INTERNAL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `14` | UNAVAILABLE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `15` | DATA_LOSS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `16` | UNAUTHENTICATED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## gRPC Status diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index dbf79fca70..e0978e3e06 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -15,13 +15,13 @@ described on this page. `rpc.system` MUST be set to `"jsonrpc"`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`rpc.jsonrpc.error_code`](../attributes-registry/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | Conditionally Required: If response is not successful. | -| [`rpc.jsonrpc.error_message`](../attributes-registry/rpc.md) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | Recommended | -| [`rpc.jsonrpc.request_id`](../attributes-registry/rpc.md) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | Recommended | -| [`rpc.jsonrpc.version`](../attributes-registry/rpc.md) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | Conditionally Required: If other than the default version (`1.0`) | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | Required | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.error_code`](../attributes-registry/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response is not successful. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.version`](../attributes-registry/rpc.md) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | `Conditionally Required` If other than the default version (`1.0`) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.error_message`](../attributes-registry/rpc.md) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.request_id`](../attributes-registry/rpc.md) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 6369eb4461..4c8e433fff 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -77,9 +77,9 @@ Below is a list of RPC server metric instruments. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.server.duration` | Histogram | `ms` | Measures the duration of inbound RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.server.duration` | Histogram | `ms` | Measures the duration of inbound RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. @@ -92,9 +92,9 @@ to end-of-batch, it's hard to interpret in practice. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.server.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.server.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** **Streaming**: Recorded per message in a streaming batch @@ -104,9 +104,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.server.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.server.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** **Streaming**: Recorded per response in a streaming batch @@ -116,9 +116,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.server.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.server.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Should be 1 for all non-streaming RPCs. @@ -130,9 +130,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.server.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.server.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Should be 1 for all non-streaming RPCs. @@ -149,9 +149,9 @@ These apply to traditional RPC usage, not streaming RPCs. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.client.duration` | Histogram | `ms` | Measures the duration of outbound RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.client.duration` | Histogram | `ms` | Measures the duration of outbound RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** While streaming RPCs may record this metric as start-of-batch to end-of-batch, it's hard to interpret in practice. @@ -164,9 +164,9 @@ to end-of-batch, it's hard to interpret in practice. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.client.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.client.request.size` | Histogram | `By` | Measures the size of RPC request messages (uncompressed). [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** **Streaming**: Recorded per message in a streaming batch @@ -176,9 +176,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.client.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.client.response.size` | Histogram | `By` | Measures the size of RPC response messages (uncompressed). [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** **Streaming**: Recorded per response in a streaming batch @@ -188,9 +188,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.client.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.client.requests_per_rpc` | Histogram | `{count}` | Measures the number of messages received per RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Should be 1 for all non-streaming RPCs. @@ -202,9 +202,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `rpc.client.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `rpc.client.responses_per_rpc` | Histogram | `{count}` | Measures the number of messages sent per RPC. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Should be 1 for all non-streaming RPCs. @@ -217,15 +217,15 @@ Below is a table of attributes that SHOULD be included on client and server RPC measurements. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | -| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -243,31 +243,31 @@ different processes could be listening on TCP port 12345 and UDP port 12345. **[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`network.transport` 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. +`rpc.system` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.type` 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. +`network.transport` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`rpc.system` 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. +`network.type` 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 | -|---|---| -| `grpc` | gRPC | -| `java_rmi` | Java RMI | -| `dotnet_wcf` | .NET WCF | -| `apache_dubbo` | Apache Dubbo | -| `connect_rpc` | Connect RPC | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | For client-side metrics `server.port` is required if the connection is IP-based and the port is available (it describes the server port they are connecting to). diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 0fc18c483d..b91d7cbd21 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -82,59 +82,59 @@ Examples of span names: ### Common attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | Recommended | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | Recommended | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | Recommended | -| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | Required | -| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | Required | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | Conditionally Required: [7] | - -**[1]:** The value SHOULD be normalized to lowercase. +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. +**[1]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. + +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[2]:** The value SHOULD be normalized to lowercase. +**[3]:** if the port is supported by the network transport used for communication. -**[3]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[4]:** The value SHOULD be normalized to lowercase. -**[4]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. -**[5]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. +**[5]:** The value SHOULD be normalized to lowercase. -**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[6]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[7]:** if the port is supported by the network transport used for communication. +**[7]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -`network.transport` 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. +`rpc.system` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.type` 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. +`network.transport` 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 | -|---|---| -| `ipv4` | IPv4 | -| `ipv6` | IPv6 | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`rpc.system` 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. +`network.type` 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 | -|---|---| -| `grpc` | gRPC | -| `java_rmi` | Java RMI | -| `dotnet_wcf` | .NET WCF | -| `apache_dubbo` | Apache Dubbo | -| `connect_rpc` | Connect RPC | +| Value | Description | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | #### Service name @@ -154,23 +154,23 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service ### Client attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Server attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | Recommended | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | Recommended | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | Recommended: If `network.peer.address` is set. | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | Recommended | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. @@ -194,21 +194,21 @@ and one received message will be recorded for both client and server spans. The event name MUST be `message`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `message.compressed_size` | int | Compressed size of the message in bytes. | | Recommended | -| `message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | Recommended | -| `message.type` | string | Whether this is a received or sent message. | `SENT` | Recommended | -| `message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `message.compressed_size` | int | Compressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `message.type` | string | Whether this is a received or sent message. | `SENT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This way we guarantee that the values will be consistent between different implementations. `message.type` MUST be one of the following: -| Value | Description | -|---|---| -| `SENT` | sent | -| `RECEIVED` | received | +| Value | Description | Stability | +|---|---|---| +| `SENT` | sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `RECEIVED` | received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Distinction from HTTP spans diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 7d2d27d148..8128f8371c 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -51,25 +51,25 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.used` | UpDownCounter | `By` | Measure of memory used. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.memory.used` | UpDownCounter | `By` | Measure of memory used. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). `jvm.memory.type` MUST be one of the following: -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `jvm.memory.committed` @@ -78,25 +78,25 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.memory.committed` | UpDownCounter | `By` | Measure of memory committed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). `jvm.memory.type` MUST be one of the following: -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `jvm.memory.limit` @@ -105,25 +105,25 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.memory.limit` | UpDownCounter | `By` | Measure of max obtainable memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). `jvm.memory.type` MUST be one of the following: -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `jvm.memory.used_after_last_gc` @@ -132,25 +132,25 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getCollectionUsage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.used_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.memory.used_after_last_gc` | UpDownCounter | `By` | Measure of memory used, as measured after the most recent garbage collection event on this pool. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). `jvm.memory.type` MUST be one of the following: -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## JVM Garbage Collection @@ -170,16 +170,16 @@ This metric SHOULD be specified with of `[ 0.01, 0.1, 1, 10 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.gc.duration` | Histogram | `s` | Duration of JVM garbage collection actions. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.gc.action` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | Recommended | -| `jvm.gc.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). @@ -205,27 +205,27 @@ This metric is obtained from a combination of Note that this is the number of platform threads (as opposed to virtual threads). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.thread.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.thread.count` | UpDownCounter | `{thread}` | Number of executing platform threads. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.thread.daemon` | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Whether the thread is daemon or not. | | Recommended | -| `jvm.thread.state` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
State of the thread. | `runnable`; `blocked` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `jvm.thread.state` MUST be one of the following: -| Value | Description | -|---|---| -| `new` | A thread that has not yet started is in this state. | -| `runnable` | A thread executing in the Java virtual machine is in this state. | -| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | -| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | -| `timed_waiting` | A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. | -| `terminated` | A thread that has exited is in this state. | +| Value | Description | Stability | +|---|---|---| +| `new` | A thread that has not yet started is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `runnable` | A thread executing in the Java virtual machine is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timed_waiting` | A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `terminated` | A thread that has exited is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## JVM Classes @@ -240,9 +240,9 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getTotalLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getTotalLoadedClassCount--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.class.loaded` | Counter | `{class}` | Number of classes loaded since JVM start. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -254,9 +254,9 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getUnloadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getUnloadedClassCount--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.class.unloaded` | Counter | `{class}` | Number of classes unloaded since JVM start. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -268,9 +268,9 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`ClassLoadingMXBean#getLoadedClassCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/ClassLoadingMXBean.html#getLoadedClassCount--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.class.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.class.count` | UpDownCounter | `{class}` | Number of classes currently loaded. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -290,9 +290,9 @@ This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getProce and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuTime()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html#getProcessCpuTime--) on OpenJ9. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.cpu.time` | Counter | `s` | CPU time used by the process as reported by the JVM. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -305,9 +305,9 @@ This metric is obtained from [`Runtime#availableProcessors()`](https://docs.orac Note that this is always an integer value (i.e. fractional or millicores are not represented). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.count` | UpDownCounter | `{cpu}` | Number of processors available to the Java virtual machine. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.cpu.count` | UpDownCounter | `{cpu}` | Number of processors available to the Java virtual machine. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -321,9 +321,9 @@ and [`com.ibm.lang.management.OperatingSystemMXBean#getProcessCpuLoad()`](https: Note that the JVM does not provide a definition of what "recent" means. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.cpu.recent_utilization` | Gauge | `1` | Recent CPU utilization for the process as reported by the JVM. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). @@ -343,25 +343,25 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryPoolMXBean.html#getUsage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.memory.init` | UpDownCounter | `By` | Measure of initial memory requested. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.memory.pool.name` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | Recommended | -| `jvm.memory.type` | string | ![Stable](https://img.shields.io/badge/-stable-lightgreen)
The type of memory. | `heap`; `non_heap` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). `jvm.memory.type` MUST be one of the following: -| Value | Description | -|---|---| -| `heap` | Heap memory. | -| `non_heap` | Non-heap memory | +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `jvm.system.cpu.utilization` @@ -371,9 +371,9 @@ This metric is obtained from [`com.sun.management.OperatingSystemMXBean#getSyste and [`com.ibm.lang.management.OperatingSystemMXBean#getSystemCpuLoad()`](https://www.ibm.com/docs/api/v1/content/SSYKE2_8.0.0/openj9/api/jdk8/jre/management/extension/com/ibm/lang/management/OperatingSystemMXBean.html) on OpenJ9. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.system.cpu.utilization` | Gauge | `1` | Recent CPU utilization for the whole system as reported by the JVM. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getCpuLoad()). @@ -387,9 +387,9 @@ This metric is [Opt-In][MetricOptIn]. This metric is obtained from [`OperatingSystemMXBean#getSystemLoadAverage()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.system.cpu.load_1m` | Gauge | `{run_queue_item}` | Average CPU load of the whole system for the last minute as reported by the JVM. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value range is [0,n], where n is the number of CPU cores - or a negative number if the value is not available. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html#getSystemLoadAverage()). @@ -403,15 +403,15 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getMemoryUsed--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.memory.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.buffer.memory.usage` | UpDownCounter | `By` | Measure of memory used by buffers. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -422,15 +422,15 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getTotalCapacity--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.memory.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.buffer.memory.limit` | UpDownCounter | `By` | Measure of total memory capacity of buffers. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -441,15 +441,15 @@ This metric is [recommended][MetricRecommended]. This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/BufferPoolMXBean.html#getCount--). -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `jvm.buffer.count` | UpDownCounter | `{buffer}` | Number of buffers in the pool. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md index d5df4933b2..4879ff95f0 100644 --- a/docs/system/container-metrics.md +++ b/docs/system/container-metrics.md @@ -13,25 +13,25 @@ linkTitle: Container This metric is [opt-in][MetricOptIn]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `container.cpu.time` | Counter | `s` | Total CPU time consumed [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `container.cpu.time` | Counter | `s` | Total CPU time consumed [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Total CPU time consumed by the specific container on all available CPU cores -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`container.cpu.state`](../attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | Opt-In | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`container.cpu.state`](../attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`container.cpu.state` 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. +`container.cpu.state` 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 | -|---|---| -| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | -| `system` | When CPU is used by the system (host OS) | -| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | +| Value | Description | Stability | +|---|---|---| +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `container.memory.usage` @@ -39,9 +39,9 @@ This metric is [opt-in][MetricOptIn]. This metric is [opt-in][MetricOptIn]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `container.memory.usage` | Counter | `By` | Memory usage of the container. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `container.memory.usage` | Counter | `By` | Memory usage of the container. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Memory usage of the container. @@ -54,25 +54,25 @@ This metric is [opt-in][MetricOptIn]. This metric is [opt-in][MetricOptIn]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `container.disk.io` | Counter | `By` | Disk bytes for the container. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `container.disk.io` | Counter | `By` | Disk bytes for the container. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The total number of bytes read/written successfully (aggregated from all disks). -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `container.network.io` @@ -80,25 +80,25 @@ This metric is [opt-in][MetricOptIn]. This metric is [opt-in][MetricOptIn]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `container.network.io` | Counter | `By` | Network bytes for the container. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `container.network.io` | Counter | `By` | Network bytes for the container. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The number of bytes sent/received on all network interfaces by the container. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 3feb662a15..6c28dde6a8 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -50,23 +50,23 @@ metrics](/docs/runtime/README.md#metrics). This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.cpu.time` | Counter | `s` | Total CPU seconds broken down by different states. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.cpu.time` | Counter | `s` | Total CPU seconds broken down by different states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`process.cpu.state` 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. +`process.cpu.state` 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 | -|---|---| -| `system` | system | -| `user` | user | -| `wait` | wait | +| Value | Description | Stability | +|---|---|---| +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `wait` | wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `process.cpu.utilization` @@ -74,23 +74,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.cpu.utilization` | Gauge | `1` | Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.cpu.utilization` | Gauge | `1` | Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`process.cpu.state` 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. +`process.cpu.state` 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 | -|---|---| -| `system` | system | -| `user` | user | -| `wait` | wait | +| Value | Description | Stability | +|---|---|---| +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `wait` | wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `process.memory.usage` @@ -98,9 +98,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.memory.usage` | UpDownCounter | `By` | The amount of physical memory in use. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.memory.usage` | UpDownCounter | `By` | The amount of physical memory in use. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -111,9 +111,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.memory.virtual` | UpDownCounter | `By` | The amount of committed virtual memory. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.memory.virtual` | UpDownCounter | `By` | The amount of committed virtual memory. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -124,22 +124,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.disk.io` | Counter | `By` | Disk bytes transferred. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.disk.io` | Counter | `By` | Disk bytes transferred. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `process.network.io` @@ -147,22 +147,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.network.io` | Counter | `By` | Network bytes transferred. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.network.io` | Counter | `By` | Network bytes transferred. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `process.thread.count` @@ -170,9 +170,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.thread.count` | UpDownCounter | `{thread}` | Process threads count. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.thread.count` | UpDownCounter | `{thread}` | Process threads count. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -183,9 +183,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.open_file_descriptor.count` | UpDownCounter | `{count}` | Number of file descriptors in use by the process. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.open_file_descriptor.count` | UpDownCounter | `{count}` | Number of file descriptors in use by the process. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -196,22 +196,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.context_switches` | Counter | `{count}` | Number of times the process has been context switched. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.context_switches` | Counter | `{count}` | Number of times the process has been context switched. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `process.context_switch_type` | string | Specifies whether the context switches for this data point were voluntary or involuntary. | `voluntary` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `process.context_switch_type` | string | Specifies whether the context switches for this data point were voluntary or involuntary. | `voluntary` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`process.context_switch_type` 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. +`process.context_switch_type` 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 | -|---|---| -| `voluntary` | voluntary | -| `involuntary` | involuntary | +| Value | Description | Stability | +|---|---|---| +| `voluntary` | voluntary | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `involuntary` | involuntary | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `process.paging.faults` @@ -219,22 +219,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `process.paging.faults` | Counter | `{fault}` | Number of page faults the process has made. | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `process.paging.faults` | Counter | `{fault}` | Number of page faults the process has made. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `process.paging.fault_type` | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `process.paging.fault_type` | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`process.paging.fault_type` 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. +`process.paging.fault_type` 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 | -|---|---| -| `major` | major | -| `minor` | minor | +| Value | Description | Stability | +|---|---|---| +| `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 7bc0a81a2c..af298da177 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -78,28 +78,28 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.cpu.time` | Counter | `s` | Seconds each logical CPU spent on each mode | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.cpu.time` | Counter | `s` | Seconds each logical CPU spent on each mode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | -| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.cpu.state` 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. +`system.cpu.state` 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 | -|---|---| -| `user` | user | -| `system` | system | -| `nice` | nice | -| `idle` | idle | -| `iowait` | iowait | -| `interrupt` | interrupt | -| `steal` | steal | +| Value | Description | Stability | +|---|---|---| +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.cpu.utilization` @@ -107,28 +107,28 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.cpu.utilization` | Gauge | `1` | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.cpu.utilization` | Gauge | `1` | Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | -| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.cpu.state` 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. +`system.cpu.state` 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 | -|---|---| -| `user` | user | -| `system` | system | -| `nice` | nice | -| `idle` | idle | -| `iowait` | iowait | -| `interrupt` | interrupt | -| `steal` | steal | +| Value | Description | Stability | +|---|---|---| +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.cpu.physical.count` @@ -136,9 +136,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.cpu.physical.count` | UpDownCounter | `{cpu}` | Reports the number of actual physical processor cores on the hardware | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.cpu.physical.count` | UpDownCounter | `{cpu}` | Reports the number of actual physical processor cores on the hardware | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -149,9 +149,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.cpu.logical.count` | UpDownCounter | `{cpu}` | Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.cpu.logical.count` | UpDownCounter | `{cpu}` | Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -162,15 +162,15 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.cpu.frequency` | Gauge | `{Hz}` | Reports the current frequency of the CPU in Hz | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.cpu.frequency` | Gauge | `{Hz}` | Reports the current frequency of the CPU in Hz | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Memory Metrics @@ -183,28 +183,28 @@ This does not include [paging/swap memory](#pagingswap-metrics). This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.memory.usage` | UpDownCounter | `By` | Reports memory in use by state. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.memory.usage` | UpDownCounter | `By` | Reports memory in use by state. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The sum over all `system.memory.state` values SHOULD equal the total memory available on the system, that is `system.memory.limit`. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.memory.state` | string | The memory state | `free`; `cached` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.memory.state` | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.memory.state` 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. +`system.memory.state` 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 | -|---|---| -| `used` | used | -| `free` | free | -| `shared` | shared | -| `buffers` | buffers | -| `cached` | cached | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.memory.limit` @@ -212,9 +212,9 @@ available on the system, that is `system.memory.limit`. This metric is [opt-in][MetricOptIn]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.memory.limit` | UpDownCounter | `By` | Total memory available in the system. [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.memory.limit` | UpDownCounter | `By` | Total memory available in the system. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Its value SHOULD equal the sum of `system.memory.state` over all states. @@ -227,25 +227,25 @@ This metric is [opt-in][MetricOptIn]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.memory.utilization` | Gauge | `1` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.memory.utilization` | Gauge | `1` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.memory.state` | string | The memory state | `free`; `cached` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.memory.state` | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.memory.state` 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. +`system.memory.state` 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 | -|---|---| -| `used` | used | -| `free` | free | -| `shared` | shared | -| `buffers` | buffers | -| `cached` | cached | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Paging/Swap Metrics @@ -257,22 +257,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.paging.usage` | UpDownCounter | `By` | Unix swap or windows pagefile usage | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.paging.usage` | UpDownCounter | `By` | Unix swap or windows pagefile usage | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.paging.state` | string | The memory paging state | `free` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.paging.state` | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.state` MUST be one of the following: -| Value | Description | -|---|---| -| `used` | used | -| `free` | free | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.paging.utilization` @@ -280,22 +280,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.paging.utilization` | Gauge | `1` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.paging.utilization` | Gauge | `1` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.paging.state` | string | The memory paging state | `free` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.paging.state` | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.state` MUST be one of the following: -| Value | Description | -|---|---| -| `used` | used | -| `free` | free | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.paging.faults` @@ -303,22 +303,22 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.paging.faults` | Counter | `{fault}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.paging.faults` | Counter | `{fault}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.paging.type` | string | The memory paging type | `minor` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.paging.type` | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.type` MUST be one of the following: -| Value | Description | -|---|---| -| `major` | major | -| `minor` | minor | +| Value | Description | Stability | +|---|---|---| +| `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.paging.operations` @@ -326,30 +326,30 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.paging.operations` | Counter | `{operation}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.paging.operations` | Counter | `{operation}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.paging.direction` | string | The paging access direction | `in` | Recommended | -| `system.paging.type` | string | The memory paging type | `minor` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.paging.direction` | string | The paging access direction | `in` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.paging.type` | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `in` | in | -| `out` | out | +| Value | Description | Stability | +|---|---|---| +| `in` | in | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out` | out | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.type` MUST be one of the following: -| Value | Description | -|---|---| -| `major` | major | -| `minor` | minor | +| Value | Description | Stability | +|---|---|---| +| `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Disk Controller Metrics @@ -361,23 +361,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.disk.io` | Counter | `By` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.disk.io` | Counter | `By` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.operations` @@ -385,23 +385,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.disk.operations` | Counter | `{operation}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.disk.operations` | Counter | `{operation}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.io_time` @@ -409,9 +409,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.disk.io_time` | Counter | `s` | Time disk spent activated [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.disk.io_time` | Counter | `s` | Time disk spent activated [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not counted). Measured as: @@ -422,9 +422,9 @@ This metric is [recommended][MetricRecommended]. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.operation_time` @@ -432,9 +432,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.disk.operation_time` | Counter | `s` | Sum of the time each operation took to complete [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.disk.operation_time` | Counter | `s` | Sum of the time each operation took to complete [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Because it is the sum of time each request took, parallel-issued requests each contribute to make the count grow. Measured as: @@ -443,17 +443,17 @@ This metric is [recommended][MetricRecommended]. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.merged` @@ -461,23 +461,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.disk.merged` | Counter | `{operation}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.disk.merged` | Counter | `{operation}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `read` | read | -| `write` | write | +| Value | Description | Stability | +|---|---|---| +| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Filesystem Metrics @@ -489,38 +489,38 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.filesystem.usage` | UpDownCounter | `By` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.filesystem.usage` | UpDownCounter | `By` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | Recommended | -| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | Recommended | -| `system.filesystem.state` | string | The filesystem state | `used` | Recommended | -| `system.filesystem.type` | string | The filesystem type | `ext4` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.state` | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.type` | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.filesystem.state` MUST be one of the following: -| Value | Description | -|---|---| -| `used` | used | -| `free` | free | -| `reserved` | reserved | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `reserved` | reserved | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.type` 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. +`system.filesystem.type` 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 | -|---|---| -| `fat32` | fat32 | -| `exfat` | exfat | -| `ntfs` | ntfs | -| `refs` | refs | -| `hfsplus` | hfsplus | -| `ext4` | ext4 | +| Value | Description | Stability | +|---|---|---| +| `fat32` | fat32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `exfat` | exfat | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ntfs` | ntfs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `refs` | refs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hfsplus` | hfsplus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ext4` | ext4 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.filesystem.utilization` @@ -528,38 +528,38 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.filesystem.utilization` | Gauge | `1` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.filesystem.utilization` | Gauge | `1` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | Recommended | -| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | Recommended | -| `system.filesystem.state` | string | The filesystem state | `used` | Recommended | -| `system.filesystem.type` | string | The filesystem type | `ext4` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.state` | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.type` | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.filesystem.state` MUST be one of the following: -| Value | Description | -|---|---| -| `used` | used | -| `free` | free | -| `reserved` | reserved | +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `reserved` | reserved | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.type` 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. +`system.filesystem.type` 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 | -|---|---| -| `fat32` | fat32 | -| `exfat` | exfat | -| `ntfs` | ntfs | -| `refs` | refs | -| `hfsplus` | hfsplus | -| `ext4` | ext4 | +| Value | Description | Stability | +|---|---|---| +| `fat32` | fat32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `exfat` | exfat | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ntfs` | ntfs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `refs` | refs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hfsplus` | hfsplus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ext4` | ext4 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Network Metrics @@ -571,9 +571,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.network.dropped` | Counter | `{packet}` | Count of packets that are dropped or discarded even though there was no error [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.network.dropped` | Counter | `{packet}` | Count of packets that are dropped or discarded even though there was no error [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Measured as: @@ -583,17 +583,17 @@ This metric is [recommended][MetricRecommended]. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.network.packets` @@ -601,23 +601,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.network.packets` | Counter | `{packet}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.network.packets` | Counter | `{packet}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.network.errors` @@ -625,9 +625,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.network.errors` | Counter | `{error}` | Count of network errors detected [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.network.errors` | Counter | `{error}` | Count of network errors detected [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Measured as: @@ -637,17 +637,17 @@ This metric is [recommended][MetricRecommended]. -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.network.io` @@ -655,23 +655,23 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.network.io` | Counter | `By` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.network.io` | Counter | `By` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: -| Value | Description | -|---|---| -| `transmit` | transmit | -| `receive` | receive | +| Value | Description | Stability | +|---|---|---| +| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.network.connections` @@ -679,17 +679,17 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.network.connections` | UpDownCounter | `{connection}` | | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.network.connections` | UpDownCounter | `{connection}` | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | Recommended | -| `system.device` | string | The device identifier | `(identifier)` | Recommended | -| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value SHOULD be normalized to lowercase. @@ -697,31 +697,31 @@ Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -`network.transport` 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. +`network.transport` 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 | -|---|---| -| `tcp` | TCP | -| `udp` | UDP | -| `pipe` | Named or anonymous pipe. | -| `unix` | Unix domain socket | +| Value | Description | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `system.network.state` MUST be one of the following: -| Value | Description | -|---|---| -| `close` | close | -| `close_wait` | close_wait | -| `closing` | closing | -| `delete` | delete | -| `established` | established | -| `fin_wait_1` | fin_wait_1 | -| `fin_wait_2` | fin_wait_2 | -| `last_ack` | last_ack | -| `listen` | listen | -| `syn_recv` | syn_recv | -| `syn_sent` | syn_sent | -| `time_wait` | time_wait | +| Value | Description | Stability | +|---|---|---| +| `close` | close | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `close_wait` | close_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `closing` | closing | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `established` | established | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_1` | fin_wait_1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_2` | fin_wait_2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `last_ack` | last_ack | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `listen` | listen | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_recv` | syn_recv | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_sent` | syn_sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `time_wait` | time_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Aggregate System Process Metrics @@ -733,24 +733,24 @@ For metrics at the individual process level, see [process metrics](process-metri This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.process.count` | UpDownCounter | `{process}` | Total number of processes in each state | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.process.count` | UpDownCounter | `{process}` | Total number of processes in each state | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.process.status` 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. +`system.process.status` 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 | -|---|---| -| `running` | running | -| `sleeping` | sleeping | -| `stopped` | stopped | -| `defunct` | defunct | +| Value | Description | Stability | +|---|---|---| +| `running` | running | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sleeping` | sleeping | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stopped` | stopped | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defunct` | defunct | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.process.created` @@ -758,9 +758,9 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.process.created` | Counter | `{process}` | Total number of processes created over uptime of the host | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.process.created` | Counter | `{process}` | Total number of processes created over uptime of the host | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -801,9 +801,9 @@ an `{os}` prefix to split this metric across OSes. ### Metric: `system.linux.memory.available` -| Name | Instrument Type | Unit (UCUM) | Description | -| -------- | --------------- | ----------- | -------------- | -| `system.linux.memory.available` | UpDownCounter | `By` | An estimate of how much memory is available for starting new applications, without causing swapping [1] | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.linux.memory.available` | UpDownCounter | `By` | An estimate of how much memory is available for starting new applications, without causing swapping [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is an alternative to `system.memory.usage` metric with `state=free`. Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values. diff --git a/docs/url/url.md b/docs/url/url.md index 77cdbf1109..28db25cab4 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -23,13 +23,13 @@ This document defines semantic conventions that describe URL and its components. ## Attributes -| Attribute | Type | Description | Examples | Requirement Level | -|---|---|---|---|---| -| [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | Recommended | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | Recommended | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | Recommended | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | Recommended | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | Recommended | +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. diff --git a/internal/tools/schema_check.sh b/internal/tools/schema_check.sh index 801fcee04f..e71451ef7c 100755 --- a/internal/tools/schema_check.sh +++ b/internal/tools/schema_check.sh @@ -6,7 +6,7 @@ set -e -BUILD_TOOL_SCHEMAS_VERSION=0.23.0 +BUILD_TOOL_SCHEMAS_VERSION=0.24.0 # List of versions that do not require or have a schema. declare -a skip_versions=("1.0.0" "1.0.1" "1.1.0" "1.2.0" "1.3.0" "1.6.0") diff --git a/model/README.md b/model/README.md index f5968affd5..dd1886f0ed 100644 --- a/model/README.md +++ b/model/README.md @@ -14,12 +14,12 @@ Semantic conventions for the spec MUST adhere to the [attribute requirement level](../docs/general/attribute-requirement-level.md), and [metric requirement level](../docs/general/metric-requirement-level.md) conventions. -Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/syntax.md) +Refer to the [syntax](https://github.com/open-telemetry/build-tools/tree/v0.24.0/semantic-conventions/syntax.md) for how to write the YAML files for semantic conventions and what the YAML properties mean. A schema file for VS code is configured in the `/.vscode/settings.json` of this repository, enabling auto-completion and additional checks. Refer to -[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions/README.md) for what extension you need. +[the generator README](https://github.com/open-telemetry/build-tools/tree/v0.24.0/semantic-conventions/README.md) for what extension you need. ## Generating markdown @@ -30,7 +30,7 @@ formatted Markdown tables for all semantic conventions in the specification. Run make table-generation ``` -For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.23.0/semantic-conventions) +For more information, see the [semantic convention generator](https://github.com/open-telemetry/build-tools/tree/v0.24.0/semantic-conventions) in the OpenTelemetry build tools repository. Using this build tool, it is also possible to generate code for use in OpenTelemetry language projects. diff --git a/model/logs/media.yaml b/model/logs/media.yaml index d2ac89f470..b6bfea89d4 100644 --- a/model/logs/media.yaml +++ b/model/logs/media.yaml @@ -15,9 +15,11 @@ groups: - id: stdout value: 'stdout' brief: 'Logs from stdout stream' + stability: experimental - id: stderr value: 'stderr' brief: 'Events from stderr stream' + stability: experimental - id: attributes.log.file prefix: log.file type: attribute_group diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index 0ae14ca975..7fee308596 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -21,24 +21,29 @@ groups: value: 'active' brief: > The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + stability: experimental - id: inactive value: 'inactive' brief: > The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + stability: experimental - id: background value: 'background' brief: > The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. + stability: experimental - id: foreground value: 'foreground' brief: > The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. + stability: experimental - id: terminate value: 'terminate' brief: > The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + stability: experimental - id: android.lifecycle.events type: event prefix: android @@ -62,13 +67,16 @@ groups: brief: > Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. + stability: experimental - id: background value: 'background' brief: > Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. + stability: experimental - id: foreground value: 'foreground' brief: > Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. + stability: experimental diff --git a/model/metrics/container.yaml b/model/metrics/container.yaml index 3904f168be..f0e15ed596 100644 --- a/model/metrics/container.yaml +++ b/model/metrics/container.yaml @@ -3,6 +3,7 @@ groups: - id: metric.container.cpu.time type: metric metric_name: container.cpu.time + stability: experimental brief: "Total CPU time consumed" note: > Total CPU time consumed by the specific container on all available CPU cores @@ -17,6 +18,7 @@ groups: - id: metric.container.memory.usage type: metric metric_name: container.memory.usage + stability: experimental brief: "Memory usage of the container." note: > Memory usage of the container. @@ -27,6 +29,7 @@ groups: - id: metric.container.disk.io type: metric metric_name: container.disk.io + stability: experimental brief: "Disk bytes for the container." note: > The total number of bytes read/written @@ -41,6 +44,7 @@ groups: - id: metric.container.network.io type: metric metric_name: container.network.io + stability: experimental brief: "Network bytes for the container." note: > The number of bytes sent/received diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index bfcc7020ec..d172d9e4b6 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -10,8 +10,10 @@ groups: members: - id: idle value: 'idle' + stability: experimental - id: used value: 'used' + stability: experimental requirement_level: required brief: "The state of a connection in the pool" examples: ["idle"] diff --git a/model/metrics/dotnet/dotnet-aspnetcore.yaml b/model/metrics/dotnet/dotnet-aspnetcore.yaml index 89ce151d2d..da851f57fb 100644 --- a/model/metrics/dotnet/dotnet-aspnetcore.yaml +++ b/model/metrics/dotnet/dotnet-aspnetcore.yaml @@ -18,15 +18,19 @@ groups: - id: acquired value: 'acquired' brief: "Lease was acquired" + stability: stable - id: endpoint_limiter value: 'endpoint_limiter' brief: "Lease request was rejected by the endpoint limiter" + stability: stable - id: global_limiter value: 'global_limiter' brief: "Lease request was rejected by the global limiter" + stability: stable - id: request_canceled value: 'request_canceled' brief: "Lease request was canceled" + stability: stable stability: stable brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason examples: ["acquired", "request_canceled"] @@ -78,9 +82,11 @@ groups: - id: success value: 'success' brief: 'Match succeeded' + stability: stable - id: failure value: 'failure' brief: 'Match failed' + stability: stable stability: stable requirement_level: required brief: Match result - success or failure @@ -108,15 +114,19 @@ groups: - id: handled value: 'handled' brief: "Exception was handled by the exception handling middleware." + stability: stable - id: unhandled value: 'unhandled' brief: "Exception was not handled by the exception handling middleware." + stability: stable - id: skipped value: 'skipped' brief: "Exception handling was skipped because the response had started." + stability: stable - id: aborted value: 'aborted' brief: "Exception handling didn't run because the request was aborted." + stability: stable stability: stable requirement_level: required brief: ASP.NET Core exception middleware handling result diff --git a/model/metrics/dotnet/dotnet-kestrel.yaml b/model/metrics/dotnet/dotnet-kestrel.yaml index 9a4a231f51..0d1499a34c 100644 --- a/model/metrics/dotnet/dotnet-kestrel.yaml +++ b/model/metrics/dotnet/dotnet-kestrel.yaml @@ -38,7 +38,6 @@ groups: - ref: network.protocol.version examples: ["1.1", "2"] - ref: tls.protocol.version - stability: experimental - ref: error.type brief: The full name of exception type. requirement_level: @@ -110,7 +109,6 @@ groups: extends: common.kestrel.attributes attributes: - ref: tls.protocol.version - stability: experimental - ref: error.type brief: The full name of exception type. note: "Captures the exception type when a TLS handshake fails." diff --git a/model/metrics/dotnet/dotnet-signalr.yaml b/model/metrics/dotnet/dotnet-signalr.yaml index b47ebf6908..e6233fc3cd 100644 --- a/model/metrics/dotnet/dotnet-signalr.yaml +++ b/model/metrics/dotnet/dotnet-signalr.yaml @@ -10,12 +10,15 @@ groups: - id: normal_closure value: 'normal_closure' brief: "The connection was closed normally." + stability: stable - id: timeout value: 'timeout' brief: "The connection was closed due to a timeout." + stability: stable - id: app_shutdown value: 'app_shutdown' brief: "The connection was closed because the app is shutting down." + stability: stable stability: stable brief: SignalR HTTP connection closure status. examples: ["app_shutdown", "timeout"] @@ -27,12 +30,15 @@ groups: - id: server_sent_events value: 'server_sent_events' brief: "ServerSentEvents protocol" + stability: stable - id: long_polling value: 'long_polling' brief: "LongPolling protocol" + stability: stable - id: web_sockets value: 'web_sockets' brief: "WebSockets protocol" + stability: stable stability: stable examples: ["web_sockets", "long_polling"] diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index b28b175130..5247f4165e 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -12,9 +12,11 @@ groups: - id: heap value: 'heap' brief: 'Heap memory.' + stability: stable - id: non_heap value: 'non_heap' brief: 'Non-heap memory' + stability: stable requirement_level: recommended brief: The type of memory. examples: ["heap", "non_heap"] @@ -113,21 +115,27 @@ groups: - id: new value: 'new' brief: 'A thread that has not yet started is in this state.' + stability: stable - id: runnable value: 'runnable' brief: 'A thread executing in the Java virtual machine is in this state.' + stability: stable - id: blocked value: 'blocked' brief: 'A thread that is blocked waiting for a monitor lock is in this state.' + stability: stable - id: waiting value: 'waiting' brief: 'A thread that is waiting indefinitely for another thread to perform a particular action is in this state.' + stability: stable - id: timed_waiting value: 'timed_waiting' brief: 'A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.' + stability: stable - id: terminated value: 'terminated' brief: 'A thread that has exited is in this state.' + stability: stable brief: "State of the thread." examples: ["runnable", "blocked"] stability: stable diff --git a/model/metrics/process-metrics.yaml b/model/metrics/process-metrics.yaml index d6735399a1..b6e99ed9f0 100644 --- a/model/metrics/process-metrics.yaml +++ b/model/metrics/process-metrics.yaml @@ -11,10 +11,13 @@ groups: members: - id: system value: 'system' + stability: experimental - id: user value: 'user' + stability: experimental - id: wait value: 'wait' + stability: experimental stability: experimental - id: metric.process.cpu.time type: metric @@ -106,8 +109,10 @@ groups: members: - id: voluntary value: 'voluntary' + stability: experimental - id: involuntary value: 'involuntary' + stability: experimental stability: experimental - id: metric.process.paging.faults type: metric @@ -124,6 +129,8 @@ groups: members: - id: major value: 'major' + stability: experimental - id: minor value: 'minor' + stability: experimental stability: experimental diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index 2424b1aa41..e567fb8a41 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -23,18 +23,25 @@ groups: members: - id: user value: 'user' + stability: experimental - id: system value: 'system' + stability: experimental - id: nice value: 'nice' + stability: experimental - id: idle value: 'idle' + stability: experimental - id: iowait value: 'iowait' + stability: experimental - id: interrupt value: 'interrupt' + stability: experimental - id: steal value: 'steal' + stability: experimental brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." stability: experimental examples: ["idle", "interrupt"] @@ -106,14 +113,19 @@ groups: members: - id: used value: 'used' + stability: experimental - id: free value: 'free' + stability: experimental - id: shared value: 'shared' + stability: experimental - id: buffers value: 'buffers' + stability: experimental - id: cached value: 'cached' + stability: experimental stability: experimental brief: "The memory state" examples: ["free", "cached"] @@ -163,8 +175,10 @@ groups: members: - id: used value: 'used' + stability: experimental - id: free value: 'free' + stability: experimental stability: experimental brief: "The memory paging state" examples: ["free"] @@ -174,8 +188,10 @@ groups: members: - id: major value: 'major' + stability: experimental - id: minor value: 'minor' + stability: experimental stability: experimental brief: "The memory paging type" examples: ["minor"] @@ -185,8 +201,10 @@ groups: members: - id: in value: 'in' + stability: experimental - id: out value: 'out' + stability: experimental stability: experimental brief: "The paging access direction" examples: ["in"] @@ -311,10 +329,13 @@ groups: members: - id: used value: 'used' + stability: experimental - id: free value: 'free' + stability: experimental - id: reserved value: 'reserved' + stability: experimental stability: experimental examples: ["used"] - id: type @@ -323,16 +344,22 @@ groups: members: - id: fat32 value: 'fat32' + stability: experimental - id: exfat value: 'exfat' + stability: experimental - id: ntfs value: 'ntfs' + stability: experimental - id: refs value: 'refs' + stability: experimental - id: hfsplus value: 'hfsplus' + stability: experimental - id: ext4 value: 'ext4' + stability: experimental stability: experimental brief: "The filesystem type" examples: ["ext4"] @@ -389,28 +416,40 @@ groups: members: - id: close value: 'close' + stability: experimental - id: close_wait value: 'close_wait' + stability: experimental - id: closing value: 'closing' + stability: experimental - id: delete value: 'delete' + stability: experimental - id: established value: 'established' + stability: experimental - id: fin_wait_1 value: 'fin_wait_1' + stability: experimental - id: fin_wait_2 value: 'fin_wait_2' + stability: experimental - id: last_ack value: 'last_ack' + stability: experimental - id: listen value: 'listen' + stability: experimental - id: syn_recv value: 'syn_recv' + stability: experimental - id: syn_sent value: 'syn_sent' + stability: experimental - id: time_wait value: 'time_wait' + stability: experimental stability: experimental brief: "A stateless protocol MUST NOT set this attribute" examples: ["close_wait"] @@ -495,12 +534,16 @@ groups: members: - id: running value: 'running' + stability: experimental - id: sleeping value: 'sleeping' + stability: experimental - id: stopped value: 'stopped' + stability: experimental - id: defunct value: 'defunct' + stability: experimental stability: experimental brief: > The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) diff --git a/model/registry/cloud.yaml b/model/registry/cloud.yaml index e3ce26b0e4..1fa9ba3982 100644 --- a/model/registry/cloud.yaml +++ b/model/registry/cloud.yaml @@ -12,24 +12,31 @@ groups: - id: 'alibaba_cloud' value: 'alibaba_cloud' brief: 'Alibaba Cloud' + stability: experimental - id: 'aws' value: 'aws' brief: 'Amazon Web Services' + stability: experimental - id: 'azure' value: 'azure' brief: 'Microsoft Azure' + stability: experimental - id: 'gcp' value: 'gcp' brief: 'Google Cloud Platform' + stability: experimental - id: 'heroku' value: 'heroku' brief: 'Heroku Platform as a Service' + stability: experimental - id: 'ibm_cloud' value: 'ibm_cloud' brief: 'IBM Cloud' + stability: experimental - id: 'tencent_cloud' value: 'tencent_cloud' brief: 'Tencent Cloud' + stability: experimental stability: experimental brief: > Name of the cloud provider. @@ -99,87 +106,115 @@ groups: - id: alibaba_cloud_ecs value: 'alibaba_cloud_ecs' brief: Alibaba Cloud Elastic Compute Service + stability: experimental - id: alibaba_cloud_fc value: 'alibaba_cloud_fc' brief: Alibaba Cloud Function Compute + stability: experimental - id: alibaba_cloud_openshift value: 'alibaba_cloud_openshift' brief: Red Hat OpenShift on Alibaba Cloud + stability: experimental - id: aws_ec2 value: 'aws_ec2' brief: AWS Elastic Compute Cloud + stability: experimental - id: aws_ecs value: 'aws_ecs' brief: AWS Elastic Container Service + stability: experimental - id: aws_eks value: 'aws_eks' brief: AWS Elastic Kubernetes Service + stability: experimental - id: aws_lambda value: 'aws_lambda' brief: AWS Lambda + stability: experimental - id: aws_elastic_beanstalk value: 'aws_elastic_beanstalk' brief: AWS Elastic Beanstalk + stability: experimental - id: aws_app_runner value: 'aws_app_runner' brief: AWS App Runner + stability: experimental - id: aws_openshift value: 'aws_openshift' brief: Red Hat OpenShift on AWS (ROSA) + stability: experimental - id: azure_vm value: 'azure_vm' brief: Azure Virtual Machines + stability: experimental - id: azure_container_apps value: 'azure_container_apps' brief: Azure Container Apps + stability: experimental - id: azure_container_instances value: 'azure_container_instances' brief: Azure Container Instances + stability: experimental - id: azure_aks value: 'azure_aks' brief: Azure Kubernetes Service + stability: experimental - id: azure_functions value: 'azure_functions' brief: Azure Functions + stability: experimental - id: azure_app_service value: 'azure_app_service' brief: Azure App Service + stability: experimental - id: azure_openshift value: 'azure_openshift' brief: Azure Red Hat OpenShift + stability: experimental - id: gcp_bare_metal_solution value: 'gcp_bare_metal_solution' brief: Google Bare Metal Solution (BMS) + stability: experimental - id: gcp_compute_engine value: 'gcp_compute_engine' brief: Google Cloud Compute Engine (GCE) + stability: experimental - id: gcp_cloud_run value: 'gcp_cloud_run' brief: Google Cloud Run + stability: experimental - id: gcp_kubernetes_engine value: 'gcp_kubernetes_engine' brief: Google Cloud Kubernetes Engine (GKE) + stability: experimental - id: gcp_cloud_functions value: 'gcp_cloud_functions' brief: Google Cloud Functions (GCF) + stability: experimental - id: gcp_app_engine value: 'gcp_app_engine' brief: Google Cloud App Engine (GAE) + stability: experimental - id: gcp_openshift value: 'gcp_openshift' brief: Red Hat OpenShift on Google Cloud + stability: experimental - id: ibm_cloud_openshift value: 'ibm_cloud_openshift' brief: Red Hat OpenShift on IBM Cloud + stability: experimental - id: tencent_cloud_cvm value: 'tencent_cloud_cvm' brief: Tencent Cloud Cloud Virtual Machine (CVM) + stability: experimental - id: tencent_cloud_eks value: 'tencent_cloud_eks' brief: Tencent Cloud Elastic Kubernetes Service (EKS) + stability: experimental - id: tencent_cloud_scf value: 'tencent_cloud_scf' brief: Tencent Cloud Serverless Cloud Function (SCF) + stability: experimental stability: experimental brief: > The cloud platform in use. diff --git a/model/registry/container.yaml b/model/registry/container.yaml index 2878766b66..e04514e57a 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -103,10 +103,14 @@ groups: - id: user value: 'user' brief: "When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows)." + stability: experimental - id: system value: 'system' brief: "When CPU is used by the system (host OS)" + stability: experimental - id: kernel value: 'kernel' brief: "When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows)." + stability: experimental + stability: experimental examples: ["user", "kernel"] diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 781cc68f9f..f56a830fcb 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -26,26 +26,37 @@ groups: members: - id: all value: 'all' + stability: experimental - id: each_quorum value: 'each_quorum' + stability: experimental - id: quorum value: 'quorum' + stability: experimental - id: local_quorum value: 'local_quorum' + stability: experimental - id: one value: 'one' + stability: experimental - id: two value: 'two' + stability: experimental - id: three value: 'three' + stability: experimental - id: local_one value: 'local_one' + stability: experimental - id: any value: 'any' + stability: experimental - id: serial value: 'serial' + stability: experimental - id: local_serial value: 'local_serial' + stability: experimental stability: experimental tag: tech-specific-cassandra - id: cassandra.idempotence @@ -94,9 +105,11 @@ groups: - id: gateway value: 'gateway' brief: Gateway (HTTP) connections mode + stability: experimental - id: direct value: 'direct' brief: Direct connection. + stability: experimental stability: experimental brief: Cosmos client connection mode. tag: tech-specific-cosmosdb @@ -112,34 +125,49 @@ groups: members: - id: invalid value: 'Invalid' + stability: experimental - id: create value: 'Create' + stability: experimental - id: patch value: 'Patch' + stability: experimental - id: read value: 'Read' + stability: experimental - id: read_feed value: 'ReadFeed' + stability: experimental - id: delete value: 'Delete' + stability: experimental - id: replace value: 'Replace' + stability: experimental - id: execute value: 'Execute' + stability: experimental - id: query value: 'Query' + stability: experimental - id: head value: 'Head' + stability: experimental - id: head_feed value: 'HeadFeed' + stability: experimental - id: upsert value: 'Upsert' + stability: experimental - id: batch value: 'Batch' + stability: experimental - id: query_plan value: 'QueryPlan' + stability: experimental - id: execute_javascript value: 'ExecuteJavaScript' + stability: experimental stability: experimental brief: CosmosDB Operation Type. tag: tech-specific-cosmosdb @@ -267,159 +295,211 @@ groups: - id: other_sql value: 'other_sql' brief: 'Some other SQL database. Fallback only. See notes.' + stability: experimental - id: mssql value: 'mssql' brief: 'Microsoft SQL Server' + stability: experimental - id: mssqlcompact value: 'mssqlcompact' brief: 'Microsoft SQL Server Compact' + stability: experimental - id: mysql value: 'mysql' brief: 'MySQL' + stability: experimental - id: oracle value: 'oracle' brief: 'Oracle Database' + stability: experimental - id: db2 value: 'db2' brief: 'IBM Db2' + stability: experimental - id: postgresql value: 'postgresql' brief: 'PostgreSQL' + stability: experimental - id: redshift value: 'redshift' brief: 'Amazon Redshift' + stability: experimental - id: hive value: 'hive' brief: 'Apache Hive' + stability: experimental - id: cloudscape value: 'cloudscape' brief: 'Cloudscape' + stability: experimental - id: hsqldb value: 'hsqldb' brief: 'HyperSQL DataBase' + stability: experimental - id: progress value: 'progress' brief: 'Progress Database' + stability: experimental - id: maxdb value: 'maxdb' brief: 'SAP MaxDB' + stability: experimental - id: hanadb value: 'hanadb' brief: 'SAP HANA' + stability: experimental - id: ingres value: 'ingres' brief: 'Ingres' + stability: experimental - id: firstsql value: 'firstsql' brief: 'FirstSQL' + stability: experimental - id: edb value: 'edb' brief: 'EnterpriseDB' + stability: experimental - id: cache value: 'cache' brief: 'InterSystems Caché' + stability: experimental - id: adabas value: 'adabas' brief: 'Adabas (Adaptable Database System)' + stability: experimental - id: firebird value: 'firebird' brief: 'Firebird' + stability: experimental - id: derby value: 'derby' brief: 'Apache Derby' + stability: experimental - id: filemaker value: 'filemaker' brief: 'FileMaker' + stability: experimental - id: informix value: 'informix' brief: 'Informix' + stability: experimental - id: instantdb value: 'instantdb' brief: 'InstantDB' + stability: experimental - id: interbase value: 'interbase' brief: 'InterBase' + stability: experimental - id: mariadb value: 'mariadb' brief: 'MariaDB' + stability: experimental - id: netezza value: 'netezza' brief: 'Netezza' + stability: experimental - id: pervasive value: 'pervasive' brief: 'Pervasive PSQL' + stability: experimental - id: pointbase value: 'pointbase' brief: 'PointBase' + stability: experimental - id: sqlite value: 'sqlite' brief: 'SQLite' + stability: experimental - id: sybase value: 'sybase' brief: 'Sybase' + stability: experimental - id: teradata value: 'teradata' brief: 'Teradata' + stability: experimental - id: vertica value: 'vertica' brief: 'Vertica' + stability: experimental - id: h2 value: 'h2' brief: 'H2' + stability: experimental - id: coldfusion value: 'coldfusion' brief: 'ColdFusion IMQ' + stability: experimental - id: cassandra value: 'cassandra' brief: 'Apache Cassandra' + stability: experimental - id: hbase value: 'hbase' brief: 'Apache HBase' + stability: experimental - id: mongodb value: 'mongodb' brief: 'MongoDB' + stability: experimental - id: redis value: 'redis' brief: 'Redis' + stability: experimental - id: couchbase value: 'couchbase' brief: 'Couchbase' + stability: experimental - id: couchdb value: 'couchdb' brief: 'CouchDB' + stability: experimental - id: cosmosdb value: 'cosmosdb' brief: 'Microsoft Azure Cosmos DB' + stability: experimental - id: dynamodb value: 'dynamodb' brief: 'Amazon DynamoDB' + stability: experimental - id: neo4j value: 'neo4j' brief: 'Neo4j' + stability: experimental - id: geode value: 'geode' brief: 'Apache Geode' + stability: experimental - id: elasticsearch value: 'elasticsearch' brief: 'Elasticsearch' + stability: experimental - id: memcached value: 'memcached' brief: 'Memcached' + stability: experimental - id: cockroachdb value: 'cockroachdb' brief: 'CockroachDB' + stability: experimental - id: opensearch value: 'opensearch' brief: 'OpenSearch' + stability: experimental - id: clickhouse value: 'clickhouse' brief: 'ClickHouse' + stability: experimental - id: spanner value: 'spanner' brief: 'Cloud Spanner' + stability: experimental - id: trino value: 'trino' brief: 'Trino' + stability: experimental stability: experimental tag: db-generic - id: user diff --git a/model/registry/deprecated/container.yaml b/model/registry/deprecated/container.yaml index 8c19e64f8b..49190f6918 100644 --- a/model/registry/deprecated/container.yaml +++ b/model/registry/deprecated/container.yaml @@ -7,4 +7,5 @@ groups: type: template[string] examples: [ 'container.label.app=nginx' ] brief: "Deprecated, use `container.label` instead." + stability: experimental deprecated: "Replaced by `container.label`." diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 76430d1b1b..c2f94cfe22 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -8,16 +8,19 @@ groups: - id: connection_string type: string brief: 'Deprecated, use `server.address`, `server.port` attributes instead.' + stability: experimental deprecated: > "Replaced by `server.address` and `server.port`." examples: Server=(localdb)\v11.0;Integrated Security=true; - id: jdbc.driver_classname type: string brief: 'Removed, no replacement at this time.' + stability: experimental deprecated: 'Removed as not used.' examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - id: elasticsearch.node.name type: string brief: 'Deprecated, use `db.instance.id` instead.' deprecated: "Replaced by `db.instance.id`." + stability: experimental examples: ["instance-0000000001"] diff --git a/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index 9c255eb9f2..746d8f1db4 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -7,36 +7,43 @@ groups: - id: method type: string brief: 'Deprecated, use `http.request.method` instead.' + stability: experimental deprecated: "Replaced by `http.request.method`." examples: ["GET", "POST", "HEAD"] - id: status_code type: int brief: 'Deprecated, use `http.response.status_code` instead.' + stability: experimental deprecated: "Replaced by `http.response.status_code`." examples: [200] - id: scheme type: string brief: 'Deprecated, use `url.scheme` instead.' + stability: experimental deprecated: "Replaced by `url.scheme` instead." examples: ['http', 'https'] - id: url type: string brief: 'Deprecated, use `url.full` instead.' + stability: experimental deprecated: "Replaced by `url.full`." examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv'] - id: target type: string brief: 'Deprecated, use `url.path` and `url.query` instead.' + stability: experimental deprecated: "Split to `url.path` and `url.query." examples: ['/search?q=OpenTelemetry#SemConv'] - id: request_content_length type: int brief: 'Deprecated, use `http.request.header.content-length` instead.' + stability: experimental deprecated: "Replaced by `http.request.header.content-length`." examples: 3495 - id: response_content_length type: int brief: 'Deprecated, use `http.response.header.content-length` instead.' + stability: experimental deprecated: "Replaced by `http.response.header.content-length`." examples: 3495 - id: flavor @@ -46,26 +53,34 @@ groups: - id: http_1_0 value: '1.0' brief: 'HTTP/1.0' + stability: experimental - id: http_1_1 value: '1.1' brief: 'HTTP/1.1' + stability: experimental - id: http_2_0 value: '2.0' brief: 'HTTP/2' + stability: experimental - id: http_3_0 value: '3.0' brief: 'HTTP/3' + stability: experimental - id: spdy value: 'SPDY' brief: 'SPDY protocol.' + stability: experimental - id: quic value: 'QUIC' brief: 'QUIC protocol.' + stability: experimental brief: 'Deprecated, use `network.protocol.name` instead.' deprecated: "Replaced by `network.protocol.name`." + stability: experimental - id: user_agent type: string brief: 'Deprecated, use `user_agent.original` instead.' examples: ['CERN-LineMode/2.15 libwww/2.17b3', 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1'] deprecated: "Replaced by `user_agent.original`." + stability: experimental diff --git a/model/registry/deprecated/k8s.yaml b/model/registry/deprecated/k8s.yaml index 5793257d7f..ae471dd896 100644 --- a/model/registry/deprecated/k8s.yaml +++ b/model/registry/deprecated/k8s.yaml @@ -7,4 +7,5 @@ groups: type: template[string] examples: ['k8s.pod.label.app=my-app'] brief: "Deprecated, use `k8s.pod.label` instead." + stability: experimental deprecated: "Replaced by `k8s.pod.label`." diff --git a/model/registry/deprecated/messaging.yaml b/model/registry/deprecated/messaging.yaml index 015f428818..97da3c55bb 100644 --- a/model/registry/deprecated/messaging.yaml +++ b/model/registry/deprecated/messaging.yaml @@ -9,3 +9,4 @@ groups: "Deprecated, use `messaging.destination.partition.id` instead." examples: 2 deprecated: "Replaced by `messaging.destination.partition.id`." + stability: experimental diff --git a/model/registry/deprecated/network.yaml b/model/registry/deprecated/network.yaml index 63e3959d7e..8377f727e6 100644 --- a/model/registry/deprecated/network.yaml +++ b/model/registry/deprecated/network.yaml @@ -8,46 +8,55 @@ groups: - id: sock.peer.name type: string deprecated: "Removed." + stability: experimental brief: Deprecated, no replacement at this time. examples: ['/var/my.sock'] - id: sock.peer.addr type: string deprecated: "Replaced by `network.peer.address`." + stability: experimental brief: Deprecated, use `network.peer.address`. examples: ['192.168.0.1'] - id: sock.peer.port type: int deprecated: "Replaced by `network.peer.port`." + stability: experimental examples: [65531] brief: Deprecated, use `network.peer.port`. - id: peer.name type: string deprecated: "Replaced by `server.address` on client spans and `client.address` on server spans." + stability: experimental brief: Deprecated, use `server.address` on client spans and `client.address` on server spans. examples: ['example.com'] - id: peer.port type: int deprecated: "Replaced by `server.port` on client spans and `client.port` on server spans." + stability: experimental brief: Deprecated, use `server.port` on client spans and `client.port` on server spans. examples: [8080] - id: host.name type: string deprecated: "Replaced by `server.address`." + stability: experimental brief: Deprecated, use `server.address`. examples: ['example.com'] - id: host.port type: int deprecated: "Replaced by `server.port`." + stability: experimental brief: Deprecated, use `server.port`. examples: [8080] - id: sock.host.addr type: string deprecated: "Replaced by `network.local.address`." + stability: experimental brief: Deprecated, use `network.local.address`. examples: ['/var/my.sock'] - id: sock.host.port type: int deprecated: "Replaced by `network.local.port`." + stability: experimental brief: Deprecated, use `network.local.port`. examples: [8080] - id: transport @@ -56,31 +65,39 @@ groups: members: - id: ip_tcp value: "ip_tcp" + stability: experimental - id: ip_udp value: "ip_udp" + stability: experimental - id: pipe value: "pipe" brief: 'Named or anonymous pipe.' + stability: experimental - id: inproc value: "inproc" brief: 'In-process communication.' + stability: experimental note: > Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. - id: other value: "other" + stability: experimental brief: 'Something else (non IP-based).' deprecated: "Replaced by `network.transport`." + stability: experimental brief: Deprecated, use `network.transport`. - id: protocol.name type: string deprecated: "Replaced by `network.protocol.name`." + stability: experimental brief: Deprecated, use `network.protocol.name`. examples: ['amqp', 'http', 'mqtt'] - id: protocol.version type: string deprecated: "Replaced by `network.protocol.version`." + stability: experimental brief: Deprecated, use `network.protocol.version`. examples: '3.1.1' - id: sock.family @@ -90,11 +107,15 @@ groups: - id: inet value: 'inet' brief: "IPv4 address" + stability: experimental - id: inet6 value: 'inet6' brief: "IPv6 address" + stability: experimental - id: unix value: 'unix' brief: "Unix domain socket path" + stability: experimental deprecated: "Split to `network.transport` and `network.type`." + stability: experimental brief: Deprecated, use `network.transport` and `network.type`. diff --git a/model/registry/deprecated/system.yaml b/model/registry/deprecated/system.yaml index 2356ebc562..bda1dc0e9b 100644 --- a/model/registry/deprecated/system.yaml +++ b/model/registry/deprecated/system.yaml @@ -9,12 +9,17 @@ groups: members: - id: running value: 'running' + stability: experimental - id: sleeping value: 'sleeping' + stability: experimental - id: stopped value: 'stopped' + stability: experimental - id: defunct value: 'defunct' + stability: experimental brief: "Deprecated, use `system.process.status` instead." deprecated: "Replaced by `system.process.status`." + stability: experimental examples: ["running"] diff --git a/model/registry/disk.yaml b/model/registry/disk.yaml index d8aba1e251..aa8c091135 100644 --- a/model/registry/disk.yaml +++ b/model/registry/disk.yaml @@ -11,8 +11,10 @@ groups: members: - id: read value: 'read' + stability: experimental - id: write value: 'write' + stability: experimental stability: experimental brief: "The disk IO operation direction." examples: ["read"] diff --git a/model/registry/error.yaml b/model/registry/error.yaml index 683012e361..9864db9ce3 100644 --- a/model/registry/error.yaml +++ b/model/registry/error.yaml @@ -14,6 +14,7 @@ groups: members: - id: other value: "_OTHER" + stability: stable brief: > A fallback error value to be used when the instrumentation doesn't define a custom value. examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] diff --git a/model/registry/faas.yaml b/model/registry/faas.yaml index 12c5816a20..a4fc8a3d55 100644 --- a/model/registry/faas.yaml +++ b/model/registry/faas.yaml @@ -72,18 +72,23 @@ groups: - id: datasource value: 'datasource' brief: 'A response to some data source operation such as a database or filesystem read/write' + stability: experimental - id: http value: 'http' brief: 'To provide an answer to an inbound HTTP request' + stability: experimental - id: pubsub value: 'pubsub' brief: 'A function is set to be executed when messages are sent to a messaging system' + stability: experimental - id: timer value: 'timer' brief: 'A function is scheduled to be executed regularly' + stability: experimental - id: other value: 'other' brief: 'If none of the others apply' + stability: experimental - id: invoked_name type: string stability: experimental @@ -101,18 +106,23 @@ groups: - id: 'alibaba_cloud' value: 'alibaba_cloud' brief: 'Alibaba Cloud' + stability: experimental - id: 'aws' value: 'aws' brief: 'Amazon Web Services' + stability: experimental - id: 'azure' value: 'azure' brief: 'Microsoft Azure' + stability: experimental - id: 'gcp' value: 'gcp' brief: 'Google Cloud Platform' + stability: experimental - id: 'tencent_cloud' value: 'tencent_cloud' brief: 'Tencent Cloud' + stability: experimental brief: > The cloud provider of the invoked function. note: > @@ -170,12 +180,15 @@ groups: - id: insert value: 'insert' brief: 'When a new object is created.' + stability: experimental - id: edit value: 'edit' brief: 'When an object is modified.' + stability: experimental - id: delete value: 'delete' brief: 'When an object is deleted.' + stability: experimental brief: 'Describes the type of the operation that was performed on the data.' - id: document.time type: string diff --git a/model/registry/file.yaml b/model/registry/file.yaml index 6a86aa9f9b..bbe0f99fd2 100644 --- a/model/registry/file.yaml +++ b/model/registry/file.yaml @@ -8,11 +8,13 @@ groups: type: string brief: > Directory where the file is located. It should include the drive letter, when appropriate. + stability: experimental examples: ['/home/user', 'C:\Program Files\MyApp'] - id: extension type: string brief: > File extension, excluding the leading dot. + stability: experimental examples: ['png', 'gz'] note: > When the file name has multiple extensions (example.tar.gz), only the last one should @@ -21,13 +23,16 @@ groups: type: string brief: > Name of the file including the extension, without the directory. + stability: experimental examples: ['example.png'] - id: path type: string brief: > Full path to the file, including the file name. It should include the drive letter, when appropriate. + stability: experimental examples: ['/home/alice/example.png', 'C:\Program Files\MyApp\myapp.exe'] - id: size type: int brief: > File size in bytes. + stability: experimental diff --git a/model/registry/host.yaml b/model/registry/host.yaml index f427266375..332ea01f9c 100644 --- a/model/registry/host.yaml +++ b/model/registry/host.yaml @@ -34,27 +34,35 @@ groups: - id: amd64 value: 'amd64' brief: "AMD64" + stability: experimental - id: arm32 value: 'arm32' brief: "ARM32" + stability: experimental - id: arm64 value: 'arm64' brief: "ARM64" + stability: experimental - id: ia64 value: 'ia64' brief: "Itanium" + stability: experimental - id: ppc32 value: 'ppc32' brief: "32-bit PowerPC" + stability: experimental - id: ppc64 value: 'ppc64' brief: "64-bit PowerPC" + stability: experimental - id: s390x value: 's390x' brief: "IBM z/Architecture" + stability: experimental - id: x86 value: 'x86' brief: "32-bit x86" + stability: experimental stability: experimental brief: > The CPU architecture the host system is running on. diff --git a/model/registry/http.yaml b/model/registry/http.yaml index ee0ff93293..e013704a49 100644 --- a/model/registry/http.yaml +++ b/model/registry/http.yaml @@ -36,33 +36,43 @@ groups: - id: connect value: "CONNECT" brief: 'CONNECT method.' + stability: stable - id: delete value: "DELETE" brief: 'DELETE method.' + stability: stable - id: get value: "GET" brief: 'GET method.' + stability: stable - id: head value: "HEAD" brief: 'HEAD method.' + stability: stable - id: options value: "OPTIONS" brief: 'OPTIONS method.' + stability: stable - id: patch value: "PATCH" brief: 'PATCH method.' + stability: stable - id: post value: "POST" brief: 'POST method.' + stability: stable - id: put value: "PUT" brief: 'PUT method.' + stability: stable - id: trace value: "TRACE" brief: 'TRACE method.' + stability: stable - id: other value: "_OTHER" brief: 'Any HTTP method that the instrumentation has no prior knowledge of.' + stability: stable brief: 'HTTP request method.' examples: ["GET", "POST", "HEAD"] note: | @@ -154,9 +164,11 @@ groups: - id: active value: "active" brief: 'active state.' + stability: experimental - id: idle value: "idle" brief: 'idle state.' + stability: experimental brief: State of the HTTP connection in the HTTP connection pool. stability: experimental examples: ["active", "idle"] diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 5e6846abd7..4938ddd045 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -148,24 +148,29 @@ groups: brief: > One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. + stability: experimental - id: create value: "create" brief: > A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. + stability: experimental - id: receive value: "receive" brief: > One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. + stability: experimental - id: deliver value: "process" brief: > One or more messages are delivered to or processed by a consumer. + stability: experimental - id: settle value: "settle" brief: > One or more messages are settled. + stability: experimental stability: experimental brief: > A string identifying the kind of messaging operation. @@ -200,9 +205,11 @@ groups: - id: clustering value: 'clustering' brief: 'Clustering consumption model' + stability: experimental - id: broadcasting value: 'broadcasting' brief: 'Broadcasting consumption model' + stability: experimental stability: experimental brief: > Model of message consumption. This only applies to consumer spans. @@ -249,15 +256,19 @@ groups: - id: normal value: 'normal' brief: "Normal message" + stability: experimental - id: fifo value: 'fifo' brief: 'FIFO message' + stability: experimental - id: delay value: 'delay' brief: 'Delay message' + stability: experimental - id: transaction value: 'transaction' brief: 'Transaction message' + stability: experimental stability: experimental brief: > Type of message. @@ -285,33 +296,43 @@ groups: - id: activemq value: 'activemq' brief: 'Apache ActiveMQ' + stability: experimental - id: aws_sqs value: 'aws_sqs' brief: 'Amazon Simple Queue Service (SQS)' + stability: experimental - id: eventgrid value: 'eventgrid' brief: 'Azure Event Grid' + stability: experimental - id: eventhubs value: 'eventhubs' brief: 'Azure Event Hubs' + stability: experimental - id: servicebus value: 'servicebus' brief: 'Azure Service Bus' + stability: experimental - id: gcp_pubsub value: 'gcp_pubsub' brief: 'Google Cloud Pub/Sub' + stability: experimental - id: jms value: 'jms' brief: 'Java Message Service' + stability: experimental - id: kafka value: 'kafka' brief: 'Apache Kafka' + stability: experimental - id: rabbitmq value: 'rabbitmq' brief: 'RabbitMQ' + stability: experimental - id: rocketmq value: 'rocketmq' brief: 'Apache RocketMQ' + stability: experimental stability: experimental tag: messaging-generic - id: servicebus.message.delivery_count @@ -344,15 +365,19 @@ groups: - id: complete value: 'complete' brief: 'Message is completed' + stability: experimental - id: abandon value: 'abandon' brief: 'Message is abandoned' + stability: experimental - id: dead_letter value: 'dead_letter' brief: 'Message is sent to dead letter queue' + stability: experimental - id: defer value: 'defer' brief: 'Message is deferred' + stability: experimental stability: experimental tag: tech-specific-servicebus - id: eventhubs.message.enqueued_time diff --git a/model/registry/network.yaml b/model/registry/network.yaml index 0c1da314c4..2f3f19576c 100644 --- a/model/registry/network.yaml +++ b/model/registry/network.yaml @@ -32,66 +32,87 @@ groups: - id: gprs brief: GPRS value: "gprs" + stability: experimental - id: edge brief: EDGE value: "edge" + stability: experimental - id: umts brief: UMTS value: "umts" + stability: experimental - id: cdma brief: CDMA value: "cdma" + stability: experimental - id: evdo_0 brief: EVDO Rel. 0 value: "evdo_0" + stability: experimental - id: evdo_a brief: "EVDO Rev. A" value: "evdo_a" + stability: experimental - id: cdma2000_1xrtt brief: CDMA2000 1XRTT value: "cdma2000_1xrtt" + stability: experimental - id: hsdpa brief: HSDPA value: "hsdpa" + stability: experimental - id: hsupa brief: HSUPA value: "hsupa" + stability: experimental - id: hspa brief: HSPA value: "hspa" + stability: experimental - id: iden brief: IDEN value: "iden" + stability: experimental - id: evdo_b brief: "EVDO Rev. B" value: "evdo_b" + stability: experimental - id: lte brief: LTE value: "lte" + stability: experimental - id: ehrpd brief: EHRPD value: "ehrpd" + stability: experimental - id: hspap brief: HSPAP value: "hspap" + stability: experimental - id: gsm brief: GSM value: "gsm" + stability: experimental - id: td_scdma brief: TD-SCDMA value: "td_scdma" + stability: experimental - id: iwlan brief: IWLAN value: "iwlan" + stability: experimental - id: nr brief: "5G NR (New Radio)" value: "nr" + stability: experimental - id: nrnsa brief: "5G NRNSA (New Radio Non-Standalone)" value: "nrnsa" + stability: experimental - id: lte_ca brief: LTE CA value: "lte_ca" + stability: experimental stability: experimental brief: 'This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.' examples: 'LTE' @@ -101,14 +122,19 @@ groups: members: - id: wifi value: "wifi" + stability: experimental - id: wired value: "wired" + stability: experimental - id: cell value: "cell" + stability: experimental - id: unavailable value: "unavailable" + stability: experimental - id: unknown value: "unknown" + stability: experimental stability: experimental brief: 'The internet connection type.' examples: 'wifi' @@ -155,15 +181,19 @@ groups: - id: tcp value: 'tcp' brief: "TCP" + stability: stable - id: udp value: 'udp' brief: "UDP" + stability: stable - id: pipe value: "pipe" brief: 'Named or anonymous pipe.' + stability: stable - id: unix value: 'unix' brief: "Unix domain socket" + stability: stable brief: > [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). @@ -182,9 +212,11 @@ groups: - id: ipv4 value: 'ipv4' brief: "IPv4" + stability: stable - id: ipv6 value: 'ipv6' brief: "IPv6" + stability: stable brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' note: The value SHOULD be normalized to lowercase. examples: ['ipv4', 'ipv6'] @@ -194,8 +226,10 @@ groups: members: - id: transmit value: 'transmit' + stability: experimental - id: receive value: 'receive' + stability: experimental stability: experimental brief: "The network IO operation direction." examples: ["transmit"] diff --git a/model/registry/os.yaml b/model/registry/os.yaml index 113901906a..3317958f16 100644 --- a/model/registry/os.yaml +++ b/model/registry/os.yaml @@ -15,36 +15,47 @@ groups: - id: windows value: 'windows' brief: "Microsoft Windows" + stability: experimental - id: linux value: 'linux' brief: "Linux" + stability: experimental - id: darwin value: 'darwin' brief: "Apple Darwin" + stability: experimental - id: freebsd value: 'freebsd' brief: "FreeBSD" + stability: experimental - id: netbsd value: 'netbsd' brief: "NetBSD" + stability: experimental - id: openbsd value: 'openbsd' brief: "OpenBSD" + stability: experimental - id: dragonflybsd value: 'dragonflybsd' brief: "DragonFly BSD" + stability: experimental - id: hpux value: 'hpux' brief: "HP-UX (Hewlett Packard Unix)" + stability: experimental - id: aix value: 'aix' brief: "AIX (Advanced Interactive eXecutive)" + stability: experimental - id: solaris value: 'solaris' brief: "SunOS, Oracle Solaris" + stability: experimental - id: z_os value: 'z_os' brief: "IBM z/OS" + stability: experimental brief: > The operating system type. stability: experimental diff --git a/model/registry/rpc.yaml b/model/registry/rpc.yaml index cfc1e45017..e7400d540e 100644 --- a/model/registry/rpc.yaml +++ b/model/registry/rpc.yaml @@ -9,36 +9,52 @@ groups: members: - id: cancelled value: cancelled + stability: experimental - id: unknown value: unknown + stability: experimental - id: invalid_argument value: invalid_argument + stability: experimental - id: deadline_exceeded value: deadline_exceeded + stability: experimental - id: not_found value: not_found + stability: experimental - id: already_exists value: already_exists + stability: experimental - id: permission_denied value: permission_denied + stability: experimental - id: resource_exhausted value: resource_exhausted + stability: experimental - id: failed_precondition value: failed_precondition + stability: experimental - id: aborted value: aborted + stability: experimental - id: out_of_range value: out_of_range + stability: experimental - id: unimplemented value: unimplemented + stability: experimental - id: internal value: internal + stability: experimental - id: unavailable value: unavailable + stability: experimental - id: data_loss value: data_loss + stability: experimental - id: unauthenticated value: unauthenticated + stability: experimental stability: experimental brief: "The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values." - id: connect_rpc.request.metadata @@ -64,54 +80,71 @@ groups: members: - id: ok brief: OK + stability: experimental value: 0 - id: cancelled brief: CANCELLED + stability: experimental value: 1 - id: unknown brief: UNKNOWN + stability: experimental value: 2 - id: invalid_argument brief: INVALID_ARGUMENT + stability: experimental value: 3 - id: deadline_exceeded brief: DEADLINE_EXCEEDED + stability: experimental value: 4 - id: not_found brief: NOT_FOUND + stability: experimental value: 5 - id: already_exists brief: ALREADY_EXISTS + stability: experimental value: 6 - id: permission_denied brief: PERMISSION_DENIED + stability: experimental value: 7 - id: resource_exhausted brief: RESOURCE_EXHAUSTED + stability: experimental value: 8 - id: failed_precondition brief: FAILED_PRECONDITION + stability: experimental value: 9 - id: aborted brief: ABORTED + stability: experimental value: 10 - id: out_of_range brief: OUT_OF_RANGE + stability: experimental value: 11 - id: unimplemented brief: UNIMPLEMENTED + stability: experimental value: 12 - id: internal brief: INTERNAL + stability: experimental value: 13 - id: unavailable brief: UNAVAILABLE + stability: experimental value: 14 - id: data_loss brief: DATA_LOSS + stability: experimental value: 15 - id: unauthenticated brief: UNAUTHENTICATED + stability: experimental value: 16 stability: experimental brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." @@ -188,16 +221,21 @@ groups: - id: grpc value: 'grpc' brief: 'gRPC' + stability: experimental - id: java_rmi value: 'java_rmi' brief: 'Java RMI' + stability: experimental - id: dotnet_wcf value: 'dotnet_wcf' brief: '.NET WCF' + stability: experimental - id: apache_dubbo value: 'apache_dubbo' brief: 'Apache Dubbo' + stability: experimental - id: connect_rpc value: 'connect_rpc' brief: 'Connect RPC' + stability: experimental stability: experimental diff --git a/model/registry/tls.yaml b/model/registry/tls.yaml index 1f0c880bc2..d327cf5005 100644 --- a/model/registry/tls.yaml +++ b/model/registry/tls.yaml @@ -117,8 +117,10 @@ groups: members: - id: ssl value: ssl + stability: experimental - id: tls value: tls + stability: experimental stability: experimental - id: protocol.version brief: > diff --git a/model/resource/cloud_provider/aws/ecs.yaml b/model/resource/cloud_provider/aws/ecs.yaml index a3c4b3f8b1..af24faf1ca 100644 --- a/model/resource/cloud_provider/aws/ecs.yaml +++ b/model/resource/cloud_provider/aws/ecs.yaml @@ -23,8 +23,10 @@ groups: members: - id: ec2 value: "ec2" + stability: experimental - id: fargate value: "fargate" + stability: experimental stability: experimental brief: > The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. diff --git a/model/resource/telemetry.yaml b/model/resource/telemetry.yaml index 9b57a7afd2..be016372b7 100644 --- a/model/resource/telemetry.yaml +++ b/model/resource/telemetry.yaml @@ -25,28 +25,40 @@ groups: members: - id: cpp value: "cpp" + stability: stable - id: dotnet value: "dotnet" + stability: stable - id: erlang value: "erlang" + stability: stable - id: go value: "go" + stability: stable - id: java value: "java" + stability: stable - id: nodejs value: "nodejs" + stability: stable - id: php value: "php" + stability: stable - id: python value: "python" + stability: stable - id: ruby value: "ruby" + stability: stable - id: rust value: "rust" + stability: stable - id: swift value: "swift" + stability: stable - id: webjs value: "webjs" + stability: stable stability: stable requirement_level: required brief: > diff --git a/model/scope/exporter/exporter.yaml b/model/scope/exporter/exporter.yaml index 259061d3ad..41b27571b4 100644 --- a/model/scope/exporter/exporter.yaml +++ b/model/scope/exporter/exporter.yaml @@ -23,10 +23,12 @@ groups: - id: name type: string deprecated: use the `otel.scope.name` attribute. + stability: experimental brief: examples: ['io.opentelemetry.contrib.mongodb'] - id: version type: string deprecated: use the `otel.scope.version` attribute. + stability: experimental brief: examples: ['1.0.0'] diff --git a/model/trace/compatibility.yaml b/model/trace/compatibility.yaml index b24b39a339..2ed1de06b4 100644 --- a/model/trace/compatibility.yaml +++ b/model/trace/compatibility.yaml @@ -17,6 +17,8 @@ groups: - id: child_of value: 'child_of' brief: "The parent Span depends on the child Span in some capacity" + stability: experimental - id: follows_from value: 'follows_from' brief: "The parent Span doesn't depend in any way on the result of the child Span" + stability: experimental diff --git a/model/trace/exporter/exporter.yaml b/model/trace/exporter/exporter.yaml index 23b5f921b3..124c5da191 100644 --- a/model/trace/exporter/exporter.yaml +++ b/model/trace/exporter/exporter.yaml @@ -11,9 +11,11 @@ groups: - id: ok value: OK brief: 'The operation has been validated by an Application developer or Operator to have completed successfully.' + stability: experimental - id: error value: ERROR brief: 'The operation contains an error.' + stability: experimental brief: Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. stability: stable - id: status_description diff --git a/model/trace/instrumentation/graphql.yml b/model/trace/instrumentation/graphql.yml index f3f28d1585..6e311afa69 100644 --- a/model/trace/instrumentation/graphql.yml +++ b/model/trace/instrumentation/graphql.yml @@ -20,12 +20,15 @@ groups: - id: query value: "query" brief: "GraphQL query" + stability: experimental - id: mutation value: "mutation" brief: "GraphQL mutation" + stability: experimental - id: subscription value: "subscription" brief: "GraphQL subscription" + stability: experimental examples: ['query', 'mutation', 'subscription'] - id: document brief: "The GraphQL document being executed." diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 42a3211d26..7e259966f8 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -98,8 +98,10 @@ groups: members: - id: sent value: "SENT" + stability: experimental - id: received value: "RECEIVED" + stability: experimental stability: experimental brief: "Whether this is a received or sent message." - id: id From c33835975b3426c44ecdbefc9917935ca5da8827 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 2 Apr 2024 04:10:57 -0700 Subject: [PATCH 406/482] [chore] Fix md generation commands in makefile (#865) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index dedc29b494..f330c83b3d 100644 --- a/Makefile +++ b/Makefile @@ -95,13 +95,13 @@ yamllint: .PHONY: table-generation table-generation: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec # Check if current markdown tables differ from the ones that would be generated from YAML definitions .PHONY: table-check table-check: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check .PHONY: schema-check schema-check: From 8df21008493940e9ab80a22e9911df45c4cbd001 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 2 Apr 2024 08:14:23 -0700 Subject: [PATCH 407/482] [chore] Remove constraints from faas (#861) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- model/trace/faas.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/model/trace/faas.yaml b/model/trace/faas.yaml index 58dba9d979..5b3e53b09b 100644 --- a/model/trace/faas.yaml +++ b/model/trace/faas.yaml @@ -40,16 +40,12 @@ groups: brief: > Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write. - constraints: - - include: trace.http.server - id: faas_span.pubsub type: span brief: > Semantic Convention for FaaS set to be executed when messages are sent to a messaging system. - constraints: - - include: messaging - id: faas_span.timer prefix: faas From d8b6c93ff62fdfbb25ecb2a2b2649d5d0c3d7667 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 2 Apr 2024 08:32:24 -0700 Subject: [PATCH 408/482] [chore] Cleanup minor issues in messaging semconv (#859) --- docs/messaging/azure-messaging.md | 2 +- docs/messaging/gcp-pubsub.md | 2 +- docs/messaging/kafka.md | 3 +-- docs/messaging/messaging-spans.md | 1 + docs/messaging/rabbitmq.md | 1 - docs/messaging/rocketmq.md | 1 - model/trace/messaging.yaml | 8 ++++++-- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 8626cb2c2c..69318fa60c 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -54,7 +54,7 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id messages are sent to or received from, unique within the Event Hub." | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | String representation of the partition id messages are sent to or received from, unique within the Event Hub. | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index ad3b6fa0fb..4729aab9bf 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -13,7 +13,7 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub ## Span attributes For Google Cloud Pub/Sub, the following additional attributes are defined: -<<<<<<< HEAD + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index c1affa011a..9fefba9f85 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -24,12 +24,11 @@ described on this page. For Apache Kafka, the following additional attributes are defined: -<<<<<<< HEAD | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | "String representation of the partition id the message (or batch) is sent to or received from."" | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | String representation of the partition id the message (or batch) is sent to or received from. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [2] | `myKey` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index ee1204f99c..12bb3cdc56 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -291,6 +291,7 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 6b792e3784..c46a42a9ee 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -17,7 +17,6 @@ described on this page. In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. `messaging.destination.name` MUST be set to the name of the exchange. This will be an empty string if the default exchange is used. -<<<<<<< HEAD | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index 5454938a73..da940b4e89 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -16,7 +16,6 @@ described on this page. Specific attributes for Apache RocketMQ are defined below. -<<<<<<< HEAD | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 75410d34de..2c669cce82 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -65,6 +65,9 @@ groups: - ref: messaging.destination.name requirement_level: conditionally_required: If span describes operation on a single message or if the value applies to all messages in the batch. + - ref: messaging.destination.partition.id + requirement_level: + recommended: When applicable. - ref: messaging.destination.template requirement_level: conditionally_required: > @@ -134,7 +137,8 @@ groups: attributes: - ref: messaging.destination.partition.id brief: > - "String representation of the partition id the message (or batch) is sent to or received from."" + String representation of the partition id the message (or batch) is sent to or received from. + requirement_level: recommended tag: tech-specific - ref: messaging.kafka.message.key tag: tech-specific @@ -213,7 +217,7 @@ groups: attributes: - ref: messaging.destination.partition.id brief: > - "String representation of the partition id messages are sent to or received from, unique within the Event Hub." + String representation of the partition id messages are sent to or received from, unique within the Event Hub. requirement_level: conditionally_required: If available. - ref: messaging.eventhubs.message.enqueued_time From 8dc38ecc97e3dbefaf246a91c58d8d58ef794d56 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:20:42 +0200 Subject: [PATCH 409/482] [chore] Move Dynamodb attributes to the registry (#850) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/aws.md | 35 ++ docs/database/dynamodb.md | 114 +++---- model/registry/aws.yaml | 242 ++++++++++++++ model/trace/instrumentation/aws-sdk.yml | 339 ++++++-------------- 8 files changed, 428 insertions(+), 306 deletions(-) create mode 100644 docs/attributes-registry/aws.md create mode 100644 model/registry/aws.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index de2be6b191..c000e27b9b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -20,6 +20,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aws - area:browser - area:client - area:cloud diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 5b1f182e55..0047654c5b 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -13,6 +13,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aws - area:browser - area:client - area:cloud diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index da5ba98845..fa40eee8c9 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -22,6 +22,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aws - area:browser - area:client - area:cloud diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 07c0d1754a..015dbb718b 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -28,6 +28,7 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: * [Android](android.md) +* [AWS](aws.md) * [Browser](browser.md) * [Client](client.md) * [Cloud](cloud.md) diff --git a/docs/attributes-registry/aws.md b/docs/attributes-registry/aws.md new file mode 100644 index 0000000000..0cc9f4d0d8 --- /dev/null +++ b/docs/attributes-registry/aws.md @@ -0,0 +1,35 @@ +# AWS + + + +- [AWS DynamoDB Attributes](#aws-dynamodb-attributes) + + + +## AWS DynamoDB Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index b81e58fdda..09f1a98082 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -27,8 +27,8 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.BatchWriteItem @@ -36,9 +36,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.CreateTable @@ -46,13 +46,13 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.global_secondary_indexes`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.local_secondary_indexes`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_read_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_write_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteItem @@ -60,9 +60,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteTable @@ -70,7 +70,7 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DescribeTable @@ -78,7 +78,7 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.GetItem @@ -86,10 +86,10 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.ListTables @@ -97,9 +97,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.exclusive_start_table`](../attributes-registry/aws.md) | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_count`](../attributes-registry/aws.md) | int | The number of items in the `TableNames` response parameter. | `20` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.PutItem @@ -107,9 +107,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Query @@ -117,15 +117,15 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attributes_to_get`](../attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.index_name`](../attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.scan_forward`](../attributes-registry/aws.md) | boolean | The value of the `ScanIndexForward` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.select`](../attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Scan @@ -133,18 +133,18 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attributes_to_get`](../attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.count`](../attributes-registry/aws.md) | int | The value of the `Count` response parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.index_name`](../attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.scanned_count`](../attributes-registry/aws.md) | int | The value of the `ScannedCount` response parameter. | `50` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.segment`](../attributes-registry/aws.md) | int | The value of the `Segment` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.select`](../attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.total_segments`](../attributes-registry/aws.md) | int | The value of the `TotalSegments` request parameter. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateItem @@ -152,9 +152,9 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateTable @@ -162,12 +162,12 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attribute_definitions`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.global_secondary_index_updates`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_read_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_write_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/aws.yaml b/model/registry/aws.yaml new file mode 100644 index 0000000000..c0c0686089 --- /dev/null +++ b/model/registry/aws.yaml @@ -0,0 +1,242 @@ +groups: + - id: registry.aws.dynamodb + prefix: aws.dynamodb + type: attribute_group + brief: > + This document defines attributes for AWS DynamoDB. + attributes: + - id: table_names + type: string[] + stability: experimental + brief: The keys in the `RequestItems` object field. + examples: + - Users + - Cats + - id: consumed_capacity + type: string[] + stability: experimental + brief: "The JSON-serialized value of each item in the `ConsumedCapacity` response field." + examples: + - '{ + "CapacityUnits": number, + "GlobalSecondaryIndexes": { + "string" : { + "CapacityUnits": number, + "ReadCapacityUnits": number, + "WriteCapacityUnits": number + } + }, + "LocalSecondaryIndexes": { + "string" : { + "CapacityUnits": number, + "ReadCapacityUnits": number, + "WriteCapacityUnits": number + } + }, + "ReadCapacityUnits": number, + "Table": { + "CapacityUnits": number, + "ReadCapacityUnits": number, + "WriteCapacityUnits": number + }, + "TableName": "string", + "WriteCapacityUnits": number + }' + - id: item_collection_metrics + type: string + stability: experimental + brief: "The JSON-serialized value of the `ItemCollectionMetrics` response field." + examples: + - '{ + "string" : [ + { + "ItemCollectionKey": { + "string" : { + "B": blob, + "BOOL": boolean, + "BS": [ blob ], + "L": [ + "AttributeValue" + ], + "M": { + "string" : "AttributeValue" + }, + "N": "string", + "NS": [ "string" ], + "NULL": boolean, + "S": "string", + "SS": [ "string" ] + } + }, + "SizeEstimateRangeGB": [ number ] + } + ] + }' + - id: provisioned_read_capacity + type: double + stability: experimental + brief: "The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter." + examples: + - 1.0 + - 2.0 + - id: provisioned_write_capacity + type: double + stability: experimental + brief: "The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter." + examples: + - 1.0 + - 2.0 + - id: consistent_read + type: boolean + stability: experimental + brief: "The value of the `ConsistentRead` request parameter." + - id: projection + type: string + stability: experimental + brief: "The value of the `ProjectionExpression` request parameter." + examples: + - Title + - Title, Price, Color + - Title, Description, RelatedItems, ProductReviews + - id: limit + type: int + stability: experimental + brief: "The value of the `Limit` request parameter." + examples: + - 10 + - id: attributes_to_get + type: string[] + stability: experimental + brief: "The value of the `AttributesToGet` request parameter." + examples: + - lives + - id + - id: index_name + type: string + stability: experimental + brief: "The value of the `IndexName` request parameter." + examples: + - name_to_group + - id: select + type: string + stability: experimental + brief: "The value of the `Select` request parameter." + examples: + - ALL_ATTRIBUTES + - COUNT + - id: global_secondary_indexes + type: string[] + stability: experimental + brief: "The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field" + examples: + - '{ + "IndexName": "string", + "KeySchema": [ + { + "AttributeName": "string", + "KeyType": "string" + } + ], + "Projection": { + "NonKeyAttributes": [ "string" ], + "ProjectionType": "string" + }, + "ProvisionedThroughput": { + "ReadCapacityUnits": number, + "WriteCapacityUnits": number + } + }' + - id: local_secondary_indexes + type: string[] + stability: experimental + brief: "The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field." + examples: + - '{ + "IndexArn": "string", + "IndexName": "string", + "IndexSizeBytes": number, + "ItemCount": number, + "KeySchema": [ + { + "AttributeName": "string", + "KeyType": "string" + } + ], + "Projection": { + "NonKeyAttributes": [ "string" ], + "ProjectionType": "string" + } + }' + - id: exclusive_start_table + type: string + stability: experimental + brief: "The value of the `ExclusiveStartTableName` request parameter." + examples: + - Users + - CatsTable + - id: table_count + type: int + stability: experimental + brief: "The number of items in the `TableNames` response parameter." + examples: + - 20 + - id: scan_forward + type: boolean + stability: experimental + brief: "The value of the `ScanIndexForward` request parameter." + - id: segment + type: int + stability: experimental + brief: "The value of the `Segment` request parameter." + examples: + - 10 + - id: total_segments + type: int + stability: experimental + brief: "The value of the `TotalSegments` request parameter." + examples: + - 100 + - id: count + type: int + stability: experimental + brief: "The value of the `Count` response parameter." + examples: + - 10 + - id: scanned_count + type: int + stability: experimental + brief: "The value of the `ScannedCount` response parameter." + examples: + - 50 + - id: attribute_definitions + type: string[] + stability: experimental + brief: "The JSON-serialized value of each item in the `AttributeDefinitions` request field." + examples: + - '{ + "AttributeName": "string", + "AttributeType": "string" + }' + - id: global_secondary_index_updates + type: string[] + stability: experimental + brief: "The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field." + examples: + - '{ + "Create": { + "IndexName": "string", + "KeySchema": [ + { + "AttributeName": "string", + "KeyType": "string" + } + ], + "Projection": { + "NonKeyAttributes": [ "string" ], + "ProjectionType": "string" + }, + "ProvisionedThroughput": { + "ReadCapacityUnits": number, + "WriteCapacityUnits": number + } + }' diff --git a/model/trace/instrumentation/aws-sdk.yml b/model/trace/instrumentation/aws-sdk.yml index 1817c66281..6b6f541544 100644 --- a/model/trace/instrumentation/aws-sdk.yml +++ b/model/trace/instrumentation/aws-sdk.yml @@ -46,7 +46,6 @@ groups: - id: dynamodb.shared extends: aws - prefix: aws.dynamodb type: span brief: "Attributes that exist for multiple DynamoDB request types." attributes: @@ -55,223 +54,96 @@ groups: examples: - GetItem - PutItem - - id: table_names - type: string[] - stability: experimental - brief: The keys in the `RequestItems` object field. - examples: - - Users - - Cats - - id: consumed_capacity - type: string[] - stability: experimental - brief: "The JSON-serialized value of each item in the `ConsumedCapacity` response field." - examples: - - '{ - "CapacityUnits": number, - "GlobalSecondaryIndexes": { - "string" : { - "CapacityUnits": number, - "ReadCapacityUnits": number, - "WriteCapacityUnits": number - } - }, - "LocalSecondaryIndexes": { - "string" : { - "CapacityUnits": number, - "ReadCapacityUnits": number, - "WriteCapacityUnits": number - } - }, - "ReadCapacityUnits": number, - "Table": { - "CapacityUnits": number, - "ReadCapacityUnits": number, - "WriteCapacityUnits": number - }, - "TableName": "string", - "WriteCapacityUnits": number - }' - - id: item_collection_metrics - type: string - stability: experimental - brief: "The JSON-serialized value of the `ItemCollectionMetrics` response field." - examples: - - '{ - "string" : [ - { - "ItemCollectionKey": { - "string" : { - "B": blob, - "BOOL": boolean, - "BS": [ blob ], - "L": [ - "AttributeValue" - ], - "M": { - "string" : "AttributeValue" - }, - "N": "string", - "NS": [ "string" ], - "NULL": boolean, - "S": "string", - "SS": [ "string" ] - } - }, - "SizeEstimateRangeGB": [ number ] - } - ] - }' - - id: provisioned_read_capacity - type: double - stability: experimental - brief: "The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter." - examples: - - 1.0 - - 2.0 - - id: provisioned_write_capacity - type: double - stability: experimental - brief: "The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter." - examples: - - 1.0 - - 2.0 - - id: consistent_read - type: boolean - stability: experimental - brief: "The value of the `ConsistentRead` request parameter." - - id: projection - type: string - stability: experimental - brief: "The value of the `ProjectionExpression` request parameter." - examples: - - Title - - Title, Price, Color - - Title, Description, RelatedItems, ProductReviews - - id: limit - type: int - stability: experimental - brief: "The value of the `Limit` request parameter." - examples: - - 10 - - id: attributes_to_get - type: string[] - stability: experimental - brief: "The value of the `AttributesToGet` request parameter." - examples: - - lives - - id - - id: index_name - type: string - stability: experimental - brief: "The value of the `IndexName` request parameter." - examples: - - name_to_group - - id: select - type: string - stability: experimental - brief: "The value of the `Select` request parameter." - examples: - - ALL_ATTRIBUTES - - COUNT + - ref: aws.dynamodb.table_names + requirement_level: recommended + - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended + - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended + - ref: aws.dynamodb.provisioned_read_capacity + requirement_level: recommended + - ref: aws.dynamodb.provisioned_write_capacity + requirement_level: recommended + - ref: aws.dynamodb.consistent_read + requirement_level: recommended + - ref: aws.dynamodb.projection + requirement_level: recommended + - ref: aws.dynamodb.limit + requirement_level: recommended + - ref: aws.dynamodb.attributes_to_get + requirement_level: recommended + - ref: aws.dynamodb.index_name + requirement_level: recommended + - ref: aws.dynamodb.select + requirement_level: recommended - id: dynamodb.batchgetitem brief: DynamoDB.BatchGetItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - id: dynamodb.batchwriteitem brief: DynamoDB.BatchWriteItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended - id: dynamodb.createtable brief: DynamoDB.CreateTable extends: aws - prefix: aws.dynamodb type: span attributes: - - id: global_secondary_indexes - type: string[] - stability: experimental - brief: "The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field" - examples: - - '{ - "IndexName": "string", - "KeySchema": [ - { - "AttributeName": "string", - "KeyType": "string" - } - ], - "Projection": { - "NonKeyAttributes": [ "string" ], - "ProjectionType": "string" - }, - "ProvisionedThroughput": { - "ReadCapacityUnits": number, - "WriteCapacityUnits": number - } - }' - - id: local_secondary_indexes - type: string[] - stability: experimental - brief: "The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field." - examples: - - '{ - "IndexArn": "string", - "IndexName": "string", - "IndexSizeBytes": number, - "ItemCount": number, - "KeySchema": [ - { - "AttributeName": "string", - "KeyType": "string" - } - ], - "Projection": { - "NonKeyAttributes": [ "string" ], - "ProjectionType": "string" - } - }' + - ref: aws.dynamodb.global_secondary_indexes + requirement_level: recommended + - ref: aws.dynamodb.local_secondary_indexes + requirement_level: recommended - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended - ref: aws.dynamodb.provisioned_read_capacity + requirement_level: recommended - ref: aws.dynamodb.provisioned_write_capacity + requirement_level: recommended - id: dynamodb.deleteitem brief: DynamoDB.DeleteItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended - id: dynamodb.deletetable brief: DynamoDB.DeleteTable extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users @@ -279,10 +151,10 @@ groups: - id: dynamodb.describetable brief: DynamoDB.DescribeTable extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users @@ -290,170 +162,139 @@ groups: - id: dynamodb.getitem brief: DynamoDB.GetItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.consistent_read + requirement_level: recommended - ref: aws.dynamodb.projection + requirement_level: recommended - id: dynamodb.listtables brief: DynamoDB.ListTables extends: aws - prefix: aws.dynamodb type: span attributes: - - id: exclusive_start_table - type: string - stability: experimental - brief: "The value of the `ExclusiveStartTableName` request parameter." - examples: - - Users - - CatsTable - - id: table_count - type: int - stability: experimental - brief: "The number of items in the `TableNames` response parameter." - examples: - - 20 + - ref: aws.dynamodb.exclusive_start_table + requirement_level: recommended + - ref: aws.dynamodb.table_count + requirement_level: recommended - ref: aws.dynamodb.limit + requirement_level: recommended - id: dynamodb.putitem brief: DynamoDB.PutItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended - id: dynamodb.query brief: DynamoDB.Query extends: aws - prefix: aws.dynamodb type: span attributes: - - id: scan_forward - type: boolean - stability: experimental - brief: "The value of the `ScanIndexForward` request parameter." + - ref: aws.dynamodb.scan_forward + requirement_level: recommended - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.consistent_read + requirement_level: recommended - ref: aws.dynamodb.limit + requirement_level: recommended - ref: aws.dynamodb.projection + requirement_level: recommended - ref: aws.dynamodb.attributes_to_get + requirement_level: recommended - ref: aws.dynamodb.index_name + requirement_level: recommended - ref: aws.dynamodb.select + requirement_level: recommended - id: dynamodb.scan brief: DynamoDB.Scan extends: aws - prefix: aws.dynamodb type: span attributes: - - id: segment - type: int - stability: experimental - brief: "The value of the `Segment` request parameter." - examples: - - 10 - - id: total_segments - type: int - stability: experimental - brief: "The value of the `TotalSegments` request parameter." - examples: - - 100 - - id: count - type: int - stability: experimental - brief: "The value of the `Count` response parameter." - examples: - - 10 - - id: scanned_count - type: int - stability: experimental - brief: "The value of the `ScannedCount` response parameter." - examples: - - 50 + - ref: aws.dynamodb.segment + requirement_level: recommended + - ref: aws.dynamodb.total_segments + requirement_level: recommended + - ref: aws.dynamodb.count + requirement_level: recommended + - ref: aws.dynamodb.scanned_count + requirement_level: recommended - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.consistent_read + requirement_level: recommended - ref: aws.dynamodb.limit + requirement_level: recommended - ref: aws.dynamodb.projection + requirement_level: recommended - ref: aws.dynamodb.attributes_to_get + requirement_level: recommended - ref: aws.dynamodb.index_name + requirement_level: recommended - ref: aws.dynamodb.select + requirement_level: recommended - id: dynamodb.updateitem brief: DynamoDB.UpdateItem extends: aws - prefix: aws.dynamodb type: span attributes: - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.item_collection_metrics + requirement_level: recommended - id: dynamodb.updatetable brief: DynamoDB.UpdateTable extends: aws - prefix: aws.dynamodb type: span attributes: - - id: attribute_definitions - type: string[] - stability: experimental - brief: "The JSON-serialized value of each item in the `AttributeDefinitions` request field." - examples: - - '{ - "AttributeName": "string", - "AttributeType": "string" - }' - - id: global_secondary_index_updates - type: string[] - stability: experimental - brief: "The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field." - examples: - - '{ - "Create": { - "IndexName": "string", - "KeySchema": [ - { - "AttributeName": "string", - "KeyType": "string" - } - ], - "Projection": { - "NonKeyAttributes": [ "string" ], - "ProjectionType": "string" - }, - "ProvisionedThroughput": { - "ReadCapacityUnits": number, - "WriteCapacityUnits": number - } - }' + - ref: aws.dynamodb.attribute_definitions + requirement_level: recommended + - ref: aws.dynamodb.global_secondary_index_updates + requirement_level: recommended - ref: aws.dynamodb.table_names + requirement_level: recommended brief: "A single-element array with the value of the TableName request parameter." examples: - Users - ref: aws.dynamodb.consumed_capacity + requirement_level: recommended - ref: aws.dynamodb.provisioned_read_capacity + requirement_level: recommended - ref: aws.dynamodb.provisioned_write_capacity + requirement_level: recommended - id: aws.s3 extends: aws From bc4146949ea37b4e4c39e9f95876e794e7d3dd8b Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:28:57 +0200 Subject: [PATCH 410/482] [chore] Move Peer to registry (#853) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/peer.md | 12 ++++++++++++ docs/general/attributes.md | 2 +- model/general.yaml | 10 ++-------- model/registry/peer.yaml | 15 +++++++++++++++ 8 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 docs/attributes-registry/peer.md create mode 100644 model/registry/peer.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index c000e27b9b..4453e430d9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -48,6 +48,7 @@ body: - area:network - area:oci - area:os + - area:peer - area:process - area:rpc - area:server diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 0047654c5b..7ca04917ef 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -41,6 +41,7 @@ body: - area:network - area:oci - area:os + - area:peer - area:process - area:rpc - area:server diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index fa40eee8c9..cb66735b41 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -50,6 +50,7 @@ body: - area:network - area:oci - area:os + - area:peer - area:process - area:rpc - area:server diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 015dbb718b..f8fcc96414 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -54,6 +54,7 @@ Currently, the following namespaces exist: * [Network](network.md) * [OCI](oci.md) * [OS](os.md) +* [Peer](peer.md) * [Process](process.md) * [RPC](rpc.md) * [Server](server.md) diff --git a/docs/attributes-registry/peer.md b/docs/attributes-registry/peer.md new file mode 100644 index 0000000000..e83991a403 --- /dev/null +++ b/docs/attributes-registry/peer.md @@ -0,0 +1,12 @@ + + +# Peer + +## Peer Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `peer.service` | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 2c6f13649d..5db478df4e 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -296,7 +296,7 @@ Instrumentations SHOULD provide a way for users to configure this name. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `peer.service` | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`peer.service`](../attributes-registry/peer.md) | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Examples of `peer.service` that users may specify: diff --git a/model/general.yaml b/model/general.yaml index 23ec6cd32e..88693dd442 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -32,14 +32,8 @@ groups: type: span brief: "Operations that access some remote service." attributes: - - id: service - type: string - stability: experimental - brief: > - The [`service.name`](/docs/resource/README.md#service) - of the remote service. SHOULD be equal to the actual `service.name` - resource attribute of the remote service if any. - examples: "AuthTokenCache" + - ref: peer.service + requirement_level: recommended - id: identity type: span brief: > diff --git a/model/registry/peer.yaml b/model/registry/peer.yaml new file mode 100644 index 0000000000..58ee700904 --- /dev/null +++ b/model/registry/peer.yaml @@ -0,0 +1,15 @@ +groups: + - id: registry.peer + type: span + prefix: peer + brief: > + Operations that access some remote service. + attributes: + - id: service + type: string + stability: experimental + brief: > + The [`service.name`](/docs/resource/README.md#service) + of the remote service. SHOULD be equal to the actual `service.name` + resource attribute of the remote service if any. + examples: "AuthTokenCache" From be971eeb1aebdfb3d0200d0b4b17363860d1c647 Mon Sep 17 00:00:00 2001 From: Gergely Kalapos Date: Wed, 3 Apr 2024 13:19:15 +0200 Subject: [PATCH 411/482] Moved Service attributes to registry (#758) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/service.md | 46 +++++++++++++ docs/resource/README.md | 8 +-- model/registry/service.yaml | 71 +++++++++++++++++++++ model/resource/service.yaml | 19 +----- model/resource/service_experimental.yaml | 49 +------------- 9 files changed, 129 insertions(+), 68 deletions(-) create mode 100644 docs/attributes-registry/service.md create mode 100644 model/registry/service.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4453e430d9..fdb256bcf2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -52,6 +52,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 7ca04917ef..f8f8e1aa55 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -45,6 +45,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index cb66735b41..60cc97b2b5 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -54,6 +54,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index f8fcc96414..343b0702c0 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -58,6 +58,7 @@ Currently, the following namespaces exist: * [Process](process.md) * [RPC](rpc.md) * [Server](server.md) +* [Service](service.md) * [Source](source.md) * [Thread](thread.md) * [TLS](tls.md) diff --git a/docs/attributes-registry/service.md b/docs/attributes-registry/service.md new file mode 100644 index 0000000000..9022d5ac94 --- /dev/null +++ b/docs/attributes-registry/service.md @@ -0,0 +1,46 @@ + + +# Service + +## Service Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.name` | string | Logical name of the service. [2] | `shoppingcart` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `service.namespace` | string | A namespace for `service.name`. [3] | `Shop` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words +`service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to +distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled +service). + +Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC +4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of +this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and +SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + +UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is +needed. Similar to what can be seen in the man page for the +[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying +data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it +or not via another resource attribute. + +For applications running behind an application server (like unicorn), we do not recommend using one identifier +for all processes participating in the application. Instead, it's recommended each division (e.g. a worker +thread in unicorn) to have its own instance.id. + +It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the +service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will +likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. +However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance +for that telemetry. This is typically the case for scraping receivers, as they know the target address and +port. + +**[2]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. + +**[3]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + \ No newline at end of file diff --git a/docs/resource/README.md b/docs/resource/README.md index 18e8e6dbb1..bcbaf2ed41 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -82,8 +82,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `service.name` | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.name`](../attributes-registry/service.md) | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.version`](../attributes-registry/service.md) | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. @@ -99,8 +99,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.instance.id`](../attributes-registry/service.md) | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.namespace`](../attributes-registry/service.md) | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to diff --git a/model/registry/service.yaml b/model/registry/service.yaml new file mode 100644 index 0000000000..4e139da36b --- /dev/null +++ b/model/registry/service.yaml @@ -0,0 +1,71 @@ +groups: + - id: registry.service + prefix: service + type: attribute_group + brief: > + A service instance. + attributes: + - id: name + type: string + brief: > + Logical name of the service. + note: > + MUST be the same for all instances of horizontally scaled services. + If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated + with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. + If `process.executable.name` is not available, the value MUST be set to `unknown_service`. + examples: ["shoppingcart"] + stability: stable + - id: version + type: string + brief: > + The version string of the service API or implementation. The format is not defined by these conventions. + examples: ["2.0.0", "a01dbef8a"] + stability: stable + - id: namespace + type: string + stability: experimental + brief: > + A namespace for `service.name`. + note: > + A string value having a meaning that helps to distinguish a group of services, + for example the team name that owns a group of services. + `service.name` is expected to be unique within the same namespace. + If `service.namespace` is not specified in the Resource then `service.name` + is expected to be unique for all services that have no explicit namespace defined + (so the empty/unspecified namespace is simply one more valid namespace). + Zero-length namespace string is assumed equal to unspecified namespace. + examples: ["Shop"] + - id: instance.id + type: string + stability: experimental + brief: > + The string ID of the service instance. + note: | + MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words + `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to + distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + service). + + Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC + 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of + this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and + SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + + UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + needed. Similar to what can be seen in the man page for the + [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying + data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it + or not via another resource attribute. + + For applications running behind an application server (like unicorn), we do not recommend using one identifier + for all processes participating in the application. Instead, it's recommended each division (e.g. a worker + thread in unicorn) to have its own instance.id. + + It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the + service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will + likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance + for that telemetry. This is typically the case for scraping receivers, as they know the target address and + port. + examples: ["627cc493-f310-47de-96bd-71410b7dec09"] diff --git a/model/resource/service.yaml b/model/resource/service.yaml index 05b2e02698..6384246ae6 100644 --- a/model/resource/service.yaml +++ b/model/resource/service.yaml @@ -5,21 +5,6 @@ groups: brief: > A service instance. attributes: - - id: name - type: string - stability: stable + - ref: service.name requirement_level: required - brief: > - Logical name of the service. - note: > - MUST be the same for all instances of horizontally scaled services. - If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated - with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. - If `process.executable.name` is not available, the value MUST be set to `unknown_service`. - examples: ["shoppingcart"] - - id: version - type: string - stability: stable - brief: > - The version string of the service API or implementation. The format is not defined by these conventions. - examples: ["2.0.0", "a01dbef8a"] + - ref: service.version diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index a11a30a048..97a58f6f6e 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -5,50 +5,5 @@ groups: brief: > A service instance. attributes: - - id: namespace - type: string - stability: experimental - brief: > - A namespace for `service.name`. - note: > - A string value having a meaning that helps to distinguish a group of services, - for example the team name that owns a group of services. - `service.name` is expected to be unique within the same namespace. - If `service.namespace` is not specified in the Resource then `service.name` - is expected to be unique for all services that have no explicit namespace defined - (so the empty/unspecified namespace is simply one more valid namespace). - Zero-length namespace string is assumed equal to unspecified namespace. - examples: ["Shop"] - - id: instance.id - type: string - stability: experimental - brief: > - The string ID of the service instance. - note: | - MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words - `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to - distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled - service). - - Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC - 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of - this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and - SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. - - UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is - needed. Similar to what can be seen in the man page for the - [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying - data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it - or not via another resource attribute. - - For applications running behind an application server (like unicorn), we do not recommend using one identifier - for all processes participating in the application. Instead, it's recommended each division (e.g. a worker - thread in unicorn) to have its own instance.id. - - It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the - service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will - likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. - However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance - for that telemetry. This is typically the case for scraping receivers, as they know the target address and - port. - examples: ["627cc493-f310-47de-96bd-71410b7dec09"] + - ref: service.namespace + - ref: service.instance.id From fdb088cfa996387836e11bfabb85e585a8693742 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:58:09 +0200 Subject: [PATCH 412/482] [chore] Add registry prefix to registry namespaces that missing it (#851) --- docs/attributes-registry/client.md | 2 +- docs/attributes-registry/destination.md | 2 +- docs/attributes-registry/server.md | 2 +- docs/attributes-registry/source.md | 2 +- docs/general/attributes.md | 8 ++++---- model/general.yaml | 8 ++++---- model/registry/browser.yaml | 2 +- model/registry/client.yaml | 2 +- model/registry/code.yaml | 2 +- model/registry/destination.yaml | 2 +- model/registry/k8s.yaml | 2 +- model/registry/server.yaml | 2 +- model/registry/source.yaml | 2 +- model/registry/thread.yaml | 2 +- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/attributes-registry/client.md b/docs/attributes-registry/client.md index e5ad30b661..f09e3b672b 100644 --- a/docs/attributes-registry/client.md +++ b/docs/attributes-registry/client.md @@ -11,7 +11,7 @@ connection (an exception is made for peer-to-peer communication over TCP where t protocol / API does not expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `client.address` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/destination.md b/docs/attributes-registry/destination.md index 1e5d7339d5..b20874d107 100644 --- a/docs/attributes-registry/destination.md +++ b/docs/attributes-registry/destination.md @@ -11,7 +11,7 @@ there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API does not expose a clear notion of client and server. - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/server.md b/docs/attributes-registry/server.md index a55453f54a..f455e8611e 100644 --- a/docs/attributes-registry/server.md +++ b/docs/attributes-registry/server.md @@ -11,7 +11,7 @@ connection (an exception is made for peer-to-peer communication over TCP where t protocol / API does not expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `server.address` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/source.md b/docs/attributes-registry/source.md index b4d4af5da1..d16285965f 100644 --- a/docs/attributes-registry/source.md +++ b/docs/attributes-registry/source.md @@ -11,7 +11,7 @@ there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API does not expose a clear notion of client and server. - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 5db478df4e..f0df39d9c8 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -66,7 +66,7 @@ identify the transport, then setting [`network.transport`](#other-network-attrib Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed if they do not cause breaking changes to HTTP semantic conventions. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -103,7 +103,7 @@ For Unix domain socket, `server.address` attribute represents remote endpoint ad Once the HTTP semantic conventions are declared stable, changes to the attributes in this section will only be allowed if they do not cause breaking changes to HTTP semantic conventions. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -125,7 +125,7 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t #### Source - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`source.address`](../attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -138,7 +138,7 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t Destination fields capture details about the receiver of a network exchange/packet. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`destination.address`](../attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/general.yaml b/model/general.yaml index 88693dd442..26df3efc1a 100644 --- a/model/general.yaml +++ b/model/general.yaml @@ -1,26 +1,26 @@ groups: - - id: general.client + - id: client type: attribute_group brief: > General client attributes. attributes: - ref: client.address - ref: client.port - - id: general.server + - id: server type: attribute_group brief: > General server attributes. attributes: - ref: server.address - ref: server.port - - id: general.source + - id: source type: attribute_group brief: > General source attributes. attributes: - ref: source.address - ref: source.port - - id: general.destination + - id: destination type: attribute_group brief: > General destination attributes. diff --git a/model/registry/browser.yaml b/model/registry/browser.yaml index 286c95b193..fad84c9787 100644 --- a/model/registry/browser.yaml +++ b/model/registry/browser.yaml @@ -1,7 +1,7 @@ groups: - id: registry.browser prefix: browser - type: resource + type: attribute_group brief: > The web browser attributes attributes: diff --git a/model/registry/client.yaml b/model/registry/client.yaml index bd214a1708..3b17ed8b4e 100644 --- a/model/registry/client.yaml +++ b/model/registry/client.yaml @@ -1,5 +1,5 @@ groups: - - id: client + - id: registry.client prefix: client type: attribute_group brief: > diff --git a/model/registry/code.yaml b/model/registry/code.yaml index 5848b4fa60..967607205a 100644 --- a/model/registry/code.yaml +++ b/model/registry/code.yaml @@ -1,7 +1,7 @@ groups: - id: registry.code prefix: code - type: span + type: attribute_group brief: > These attributes allow to report this unit of code and therefore to provide more context about the span. attributes: diff --git a/model/registry/destination.yaml b/model/registry/destination.yaml index 99adf1a872..c05a0c992a 100644 --- a/model/registry/destination.yaml +++ b/model/registry/destination.yaml @@ -1,5 +1,5 @@ groups: - - id: destination + - id: registry.destination prefix: destination type: attribute_group brief: > diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index ca878b8fd8..c4bfcd4765 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -1,7 +1,7 @@ groups: - id: registry.k8s prefix: k8s - type: resource + type: attribute_group brief: > Kubernetes resource attributes. attributes: diff --git a/model/registry/server.yaml b/model/registry/server.yaml index f47174dda2..d6927fe98a 100644 --- a/model/registry/server.yaml +++ b/model/registry/server.yaml @@ -1,5 +1,5 @@ groups: - - id: server + - id: registry.server prefix: server type: attribute_group brief: > diff --git a/model/registry/source.yaml b/model/registry/source.yaml index 2f9a967919..077da82310 100644 --- a/model/registry/source.yaml +++ b/model/registry/source.yaml @@ -1,5 +1,5 @@ groups: - - id: source + - id: registry.source prefix: source type: attribute_group brief: > diff --git a/model/registry/thread.yaml b/model/registry/thread.yaml index 688b0ec8e2..9c99772b9b 100644 --- a/model/registry/thread.yaml +++ b/model/registry/thread.yaml @@ -1,7 +1,7 @@ groups: - id: registry.thread prefix: thread - type: span + type: attribute_group brief: > These attributes may be used for any operation to store information about a thread that started a span. attributes: From 7a4a7d70ac0f28711cd1deb2fe02a596010ec461 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:07:31 +0200 Subject: [PATCH 413/482] [chore] Move Session to registry (#843) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/session.md | 13 +++++++++++ docs/general/session.md | 4 ++-- model/registry/session.yaml | 26 +++++++++++++++++++++ model/session.yaml | 12 ++-------- 8 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 docs/attributes-registry/session.md create mode 100644 model/registry/session.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index fdb256bcf2..127f81c39b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -53,6 +53,7 @@ body: - area:rpc - area:server - area:service + - area:session - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index f8f8e1aa55..fd5350e62c 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -46,6 +46,7 @@ body: - area:rpc - area:server - area:service + - area:session - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 60cc97b2b5..ad136536cc 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -55,6 +55,7 @@ body: - area:rpc - area:server - area:service + - area:session - area:source - area:thread - area:tls diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 343b0702c0..97f3a63985 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -59,6 +59,7 @@ Currently, the following namespaces exist: * [RPC](rpc.md) * [Server](server.md) * [Service](service.md) +* [Session](session.md) * [Source](source.md) * [Thread](thread.md) * [TLS](tls.md) diff --git a/docs/attributes-registry/session.md b/docs/attributes-registry/session.md new file mode 100644 index 0000000000..cd166d5a70 --- /dev/null +++ b/docs/attributes-registry/session.md @@ -0,0 +1,13 @@ + + +# Session + +## Session Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/general/session.md b/docs/general/session.md index 8b0fa3d2f0..93a2b9d65c 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -20,8 +20,8 @@ backends can link the two sessions. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`session.id`](../attributes-registry/session.md) | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`session.previous_id`](../attributes-registry/session.md) | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/session.yaml b/model/registry/session.yaml new file mode 100644 index 0000000000..3f53c9c6cd --- /dev/null +++ b/model/registry/session.yaml @@ -0,0 +1,26 @@ +groups: + - id: registry.session + prefix: session + type: attribute_group + brief: > + Session is defined as the period of time encompassing all activities performed by the application and the actions + executed by the end user. + + Consequently, a Session is represented as a collection of Logs, Events, and Spans emitted by the Client Application + throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in + the Logs, Events, and Spans generated during the Session's lifecycle. + + When a session reaches end of life, typically due to user inactivity or session timeout, a new session identifier + will be assigned. The previous session identifier may be provided by the instrumentation so that telemetry + backends can link the two sessions. + attributes: + - id: id + type: string + stability: experimental + brief: "A unique id to identify a session." + examples: "00112233-4455-6677-8899-aabbccddeeff" + - id: previous_id + type: string + stability: experimental + brief: "The previous `session.id` for this user, when known." + examples: "00112233-4455-6677-8899-aabbccddeeff" diff --git a/model/session.yaml b/model/session.yaml index ee09ffe1f3..a0efc150e2 100644 --- a/model/session.yaml +++ b/model/session.yaml @@ -14,15 +14,7 @@ groups: will be assigned. The previous session identifier may be provided by the instrumentation so that telemetry backends can link the two sessions. attributes: - - id: id - type: string - stability: experimental - brief: "A unique id to identify a session." - examples: "00112233-4455-6677-8899-aabbccddeeff" + - ref: session.id requirement_level: opt_in - - id: previous_id - type: string - stability: experimental - brief: "The previous `session.id` for this user, when known." - examples: "00112233-4455-6677-8899-aabbccddeeff" + - ref: session.previous_id requirement_level: opt_in From 1d592b44a77311c1d66b8be0e12e5ac6feaec33a Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:16:14 +0200 Subject: [PATCH 414/482] [chore] Move telemetry sdk to the registry (#873) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/telemetry.md | 43 ++++++++++ docs/resource/README.md | 12 +-- model/registry/telemetry.yaml | 87 +++++++++++++++++++++ model/resource/telemetry.yaml | 66 +--------------- model/resource/telemetry_experimental.yaml | 20 +---- 9 files changed, 147 insertions(+), 85 deletions(-) create mode 100644 docs/attributes-registry/telemetry.md create mode 100644 model/registry/telemetry.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 127f81c39b..42b552f8d0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -55,6 +55,7 @@ body: - area:service - area:session - area:source + - area:telemetry - area:thread - area:tls - area:url diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index fd5350e62c..f44b30f260 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -48,6 +48,7 @@ body: - area:service - area:session - area:source + - area:telemetry - area:thread - area:tls - area:url diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index ad136536cc..e0d54225ca 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -57,6 +57,7 @@ body: - area:service - area:session - area:source + - area:telemetry - area:thread - area:tls - area:url diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 97f3a63985..e2f068fc5a 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -61,6 +61,7 @@ Currently, the following namespaces exist: * [Service](service.md) * [Session](session.md) * [Source](source.md) +* [Telemetry](telemetry.md) * [Thread](thread.md) * [TLS](tls.md) * [URL](url.md) diff --git a/docs/attributes-registry/telemetry.md b/docs/attributes-registry/telemetry.md new file mode 100644 index 0000000000..1df6c8d1ff --- /dev/null +++ b/docs/attributes-registry/telemetry.md @@ -0,0 +1,43 @@ + + +# Telemetry SDK + +## Telemetry SDK Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [2] | `parts-unlimited-java` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. +If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the +`telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point +or another suitable identifier depending on the language. +The identifier `opentelemetry` is reserved and MUST NOT be used in this case. +All custom identifiers SHOULD be stable across different versions of an implementation. + +**[2]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to +a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. + +`telemetry.sdk.language` 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 | Stability | +|---|---|---| +| `cpp` | cpp | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `dotnet` | dotnet | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `erlang` | erlang | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `go` | go | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `java` | java | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `nodejs` | nodejs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `php` | php | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `python` | python | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ruby` | ruby | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `rust` | rust | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `swift` | swift | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `webjs` | webjs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + diff --git a/docs/resource/README.md b/docs/resource/README.md index bcbaf2ed41..8dbdf78fbb 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -154,12 +154,12 @@ service.name = Shop.shoppingcart **Description:** The telemetry SDK used to capture data recorded by the instrumentation libraries. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.language`](../attributes-registry/telemetry.md) | string | The language of the telemetry SDK. | `cpp` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.name`](../attributes-registry/telemetry.md) | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.version`](../attributes-registry/telemetry.md) | string | The version string of the telemetry SDK. | `1.2.3` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the @@ -197,8 +197,8 @@ All custom identifiers SHOULD be stable across different versions of an implemen | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`telemetry.distro.name`](../attributes-registry/telemetry.md) | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`telemetry.distro.version`](../attributes-registry/telemetry.md) | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. diff --git a/model/registry/telemetry.yaml b/model/registry/telemetry.yaml new file mode 100644 index 0000000000..2179330323 --- /dev/null +++ b/model/registry/telemetry.yaml @@ -0,0 +1,87 @@ +groups: + - id: registry.telemetry + prefix: telemetry + type: attribute_group + brief: > + This document defines attributes for telemetry SDK. + attributes: + - id: sdk.name + type: string + stability: stable + requirement_level: required + brief: > + The name of the telemetry SDK as defined above. + note: | + The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. + If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the + `telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point + or another suitable identifier depending on the language. + The identifier `opentelemetry` is reserved and MUST NOT be used in this case. + All custom identifiers SHOULD be stable across different versions of an implementation. + examples: ["opentelemetry"] + - id: sdk.language + type: + allow_custom_values: true + members: + - id: cpp + value: "cpp" + stability: stable + - id: dotnet + value: "dotnet" + stability: stable + - id: erlang + value: "erlang" + stability: stable + - id: go + value: "go" + stability: stable + - id: java + value: "java" + stability: stable + - id: nodejs + value: "nodejs" + stability: stable + - id: php + value: "php" + stability: stable + - id: python + value: "python" + stability: stable + - id: ruby + value: "ruby" + stability: stable + - id: rust + value: "rust" + stability: stable + - id: swift + value: "swift" + stability: stable + - id: webjs + value: "webjs" + stability: stable + stability: stable + requirement_level: required + brief: > + The language of the telemetry SDK. + - id: sdk.version + type: string + stability: stable + requirement_level: required + brief: > + The version string of the telemetry SDK. + examples: ["1.2.3"] + - id: distro.name + type: string + stability: experimental + brief: > + The name of the auto instrumentation agent or distribution, if used. + note: | + Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to + a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. + examples: ["parts-unlimited-java"] + - id: distro.version + type: string + stability: experimental + brief: > + The version string of the auto instrumentation agent or distribution, if used. + examples: ["1.2.3"] diff --git a/model/resource/telemetry.yaml b/model/resource/telemetry.yaml index be016372b7..cbc82ce566 100644 --- a/model/resource/telemetry.yaml +++ b/model/resource/telemetry.yaml @@ -1,72 +1,12 @@ groups: - id: telemetry - prefix: telemetry type: resource brief: > The telemetry SDK used to capture data recorded by the instrumentation libraries. attributes: - - id: sdk.name - type: string - stability: stable + - ref: telemetry.sdk.name requirement_level: required - brief: > - The name of the telemetry SDK as defined above. - note: | - The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. - If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the - `telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point - or another suitable identifier depending on the language. - The identifier `opentelemetry` is reserved and MUST NOT be used in this case. - All custom identifiers SHOULD be stable across different versions of an implementation. - examples: ["opentelemetry"] - - id: sdk.language - type: - allow_custom_values: true - members: - - id: cpp - value: "cpp" - stability: stable - - id: dotnet - value: "dotnet" - stability: stable - - id: erlang - value: "erlang" - stability: stable - - id: go - value: "go" - stability: stable - - id: java - value: "java" - stability: stable - - id: nodejs - value: "nodejs" - stability: stable - - id: php - value: "php" - stability: stable - - id: python - value: "python" - stability: stable - - id: ruby - value: "ruby" - stability: stable - - id: rust - value: "rust" - stability: stable - - id: swift - value: "swift" - stability: stable - - id: webjs - value: "webjs" - stability: stable - stability: stable + - ref: telemetry.sdk.language requirement_level: required - brief: > - The language of the telemetry SDK. - - id: sdk.version - type: string - stability: stable + - ref: telemetry.sdk.version requirement_level: required - brief: > - The version string of the telemetry SDK. - examples: ["1.2.3"] diff --git a/model/resource/telemetry_experimental.yaml b/model/resource/telemetry_experimental.yaml index 6569c8ff87..eb2c508b3a 100644 --- a/model/resource/telemetry_experimental.yaml +++ b/model/resource/telemetry_experimental.yaml @@ -1,22 +1,10 @@ groups: - id: telemetry_experimental - prefix: telemetry type: resource brief: > The telemetry SDK used to capture data recorded by the instrumentation libraries. attributes: - - id: distro.name - type: string - stability: experimental - brief: > - The name of the auto instrumentation agent or distribution, if used. - note: | - Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to - a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. - examples: ["parts-unlimited-java"] - - id: distro.version - type: string - stability: experimental - brief: > - The version string of the auto instrumentation agent or distribution, if used. - examples: ["1.2.3"] + - ref: telemetry.distro.name + requirement_level: recommended + - ref: telemetry.distro.version + requirement_level: recommended From d186de6b39829646d28149eae96763ddcc79101c Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 3 Apr 2024 11:49:44 -0400 Subject: [PATCH 415/482] Move Johannes to maintainer. (#874) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c200f36972..80a69eb1b9 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ Approvers ([@open-telemetry/specs-semconv-approvers](https://github.com/orgs/ope - [Alexandra Konrad](https://github.com/trisch-me), Elastic - [Christian Neumüller](https://github.com/Oberon00), Dynatrace - [James Moessis](https://github.com/jamesmoessis), Atlassian -- [Johannes Tax](https://github.com/pyohannes), Grafana Labs - [Sean Marciniak](https://github.com/MovieStoreGuy), Atlassian - [Ted Young](https://github.com/tedsuo), Lightstep @@ -32,6 +31,7 @@ Maintainers ([@open-telemetry/specs-semconv-maintainers](https://github.com/orgs - [Alexander Wert](https://github.com/AlexanderWert), Elastic - [Armin Ruech](https://github.com/arminru), Dynatrace - [Joao Grassi](https://github.com/joaopgrassi), Dynatrace +- [Johannes Tax](https://github.com/pyohannes), Grafana Labs - [Josh Suereth](https://github.com/jsuereth), Google - [Liudmila Molkova](https://github.com/lmolkova), Microsoft - [Reiley Yang](https://github.com/reyang), Microsoft From d8d0fb113f9cb986e4004395a30eb29c648a5376 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 4 Apr 2024 01:53:16 -0700 Subject: [PATCH 416/482] [chore] fix minor issues in release section of contributing.md (#879) --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc9b273e9f..1435db2e45 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -321,8 +321,8 @@ make markdown-link-check - Run `make chlog-update VERSION=v{version}` - `make chlog-update` will clean up all the current `.yaml` files inside the `.chloggen` folder automatically - - Double check that `CONTRIBUTING.md` is updated with the proper `v{version}` - - Send staging tag as PR for review. + - Double check that `CHANGELOG.md` is updated with the proper `v{version}` + - Send staging branch as PR for review. - Create a tag `v{version}` on the merged PR and push remote. ## Merging existing ECS conventions From f1be1511d91743a457974ed9a21b9193b2fe0e51 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 4 Apr 2024 09:45:17 -0700 Subject: [PATCH 417/482] [chore] Prepare v1.25.0 release (#878) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/433.yaml | 4 - .chloggen/509.yaml | 22 -- .chloggen/627.yaml | 22 -- .chloggen/661.yaml | 22 -- .chloggen/697.yaml | 7 - .chloggen/698.yaml | 7 - .chloggen/700.yaml | 22 -- .chloggen/738.yaml | 22 -- .chloggen/768.yaml | 7 - .chloggen/769.yaml | 4 - .chloggen/778.yaml | 22 -- .chloggen/780.yaml | 4 - .chloggen/785.yaml | 4 - .chloggen/796.yaml | 4 - .chloggen/798.yaml | 4 - .chloggen/804.yaml | 22 -- .chloggen/817.yaml | 4 - .chloggen/820.yaml | 4 - .chloggen/add_cpu_state_constraint.yaml | 22 -- .chloggen/add_new_container_metrics.yaml | 21 - .chloggen/allow-sanitizing-url-path.yaml | 22 -- .chloggen/clarify-metric-namespace.yaml | 5 - .chloggen/event_payload_in_body.yaml | 21 - .chloggen/file.yaml | 22 -- .chloggen/fix_cpu_step.yaml | 22 -- .chloggen/http-request-response-size.yaml | 22 -- .../move-dotnet-metrics-experimental.yaml | 4 - .chloggen/service-instance-id.yaml | 4 - .chloggen/ua_wording.yaml | 22 -- .chloggen/url-ecs.yaml | 22 -- CHANGELOG.md | 84 ++-- README.md | 2 +- docs/cloud-providers/README.md | 2 +- docs/cloud-providers/aws-sdk.md | 2 +- docs/cloudevents/README.md | 2 +- docs/cloudevents/cloudevents-spans.md | 2 +- docs/database/README.md | 2 +- docs/database/cassandra.md | 2 +- docs/database/cosmosdb.md | 2 +- docs/database/couchdb.md | 2 +- docs/database/database-metrics.md | 2 +- docs/database/database-spans.md | 2 +- docs/database/dynamodb.md | 2 +- docs/database/elasticsearch.md | 2 +- docs/database/hbase.md | 2 +- docs/database/mongodb.md | 2 +- docs/database/mssql.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- docs/dns/dns-metrics.md | 4 +- docs/dotnet/README.md | 2 +- docs/dotnet/dotnet-aspnetcore-metrics.md | 6 +- docs/dotnet/dotnet-dns-metrics.md | 4 +- docs/dotnet/dotnet-http-metrics.md | 6 +- docs/dotnet/dotnet-kestrel-metrics.md | 6 +- docs/dotnet/dotnet-signalr-metrics.md | 4 +- docs/exceptions/README.md | 2 +- docs/exceptions/exceptions-logs.md | 10 +- docs/exceptions/exceptions-spans.md | 4 +- docs/faas/README.md | 2 +- docs/faas/aws-lambda.md | 6 +- docs/faas/faas-metrics.md | 8 +- docs/faas/faas-spans.md | 2 +- docs/feature-flags/README.md | 2 +- docs/feature-flags/feature-flags-logs.md | 10 +- docs/feature-flags/feature-flags-spans.md | 2 +- docs/general/attribute-naming.md | 2 +- docs/general/attribute-requirement-level.md | 4 +- docs/general/attributes.md | 2 +- docs/general/events.md | 4 +- docs/general/logs.md | 6 +- docs/general/metric-requirement-level.md | 2 +- docs/general/metrics.md | 6 +- docs/general/session.md | 2 +- docs/general/trace-compatibility.md | 2 +- docs/general/trace.md | 4 +- docs/graphql/graphql-spans.md | 2 +- docs/http/README.md | 2 +- docs/http/http-metrics.md | 8 +- docs/http/http-spans.md | 8 +- docs/messaging/README.md | 2 +- docs/messaging/azure-messaging.md | 2 +- docs/messaging/gcp-pubsub.md | 2 +- docs/messaging/kafka.md | 2 +- docs/messaging/messaging-metrics.md | 6 +- docs/messaging/messaging-spans.md | 8 +- docs/messaging/rabbitmq.md | 2 +- docs/messaging/rocketmq.md | 2 +- docs/object-stores/README.md | 2 +- docs/object-stores/s3.md | 2 +- docs/resource/README.md | 8 +- docs/resource/android.md | 2 +- docs/resource/browser.md | 2 +- docs/resource/cloud-provider/README.md | 2 +- docs/resource/cloud-provider/aws/README.md | 2 +- docs/resource/cloud-provider/aws/ecs.md | 2 +- docs/resource/cloud-provider/aws/eks.md | 2 +- docs/resource/cloud-provider/aws/logs.md | 2 +- docs/resource/cloud-provider/gcp/README.md | 2 +- docs/resource/cloud-provider/gcp/cloud-run.md | 2 +- docs/resource/cloud-provider/heroku.md | 2 +- docs/resource/cloud.md | 2 +- docs/resource/container.md | 2 +- docs/resource/deployment-environment.md | 2 +- docs/resource/device.md | 2 +- docs/resource/faas.md | 2 +- docs/resource/host.md | 2 +- docs/resource/k8s.md | 2 +- docs/resource/os.md | 2 +- docs/resource/process.md | 2 +- docs/resource/webengine.md | 2 +- docs/rpc/README.md | 2 +- docs/rpc/connect-rpc.md | 4 +- docs/rpc/grpc.md | 6 +- docs/rpc/json-rpc.md | 2 +- docs/rpc/rpc-metrics.md | 2 +- docs/rpc/rpc-spans.md | 2 +- docs/runtime/README.md | 2 +- docs/runtime/jvm-metrics.md | 4 +- docs/system/README.md | 2 +- docs/system/container-metrics.md | 2 +- docs/system/hardware-metrics.md | 2 +- docs/system/process-metrics.md | 2 +- docs/system/system-metrics.md | 2 +- docs/url/README.md | 2 +- docs/url/url.md | 2 +- .../tools/update_specification_version.sh | 4 +- model/logs/events.yaml | 2 +- schema-next.yaml | 2 + schemas/1.25.0 | 360 ++++++++++++++++++ 130 files changed, 567 insertions(+), 587 deletions(-) delete mode 100644 .chloggen/433.yaml delete mode 100644 .chloggen/509.yaml delete mode 100755 .chloggen/627.yaml delete mode 100644 .chloggen/661.yaml delete mode 100644 .chloggen/697.yaml delete mode 100644 .chloggen/698.yaml delete mode 100644 .chloggen/700.yaml delete mode 100644 .chloggen/738.yaml delete mode 100644 .chloggen/768.yaml delete mode 100644 .chloggen/769.yaml delete mode 100644 .chloggen/778.yaml delete mode 100644 .chloggen/780.yaml delete mode 100644 .chloggen/785.yaml delete mode 100644 .chloggen/796.yaml delete mode 100644 .chloggen/798.yaml delete mode 100644 .chloggen/804.yaml delete mode 100644 .chloggen/817.yaml delete mode 100644 .chloggen/820.yaml delete mode 100755 .chloggen/add_cpu_state_constraint.yaml delete mode 100644 .chloggen/add_new_container_metrics.yaml delete mode 100644 .chloggen/allow-sanitizing-url-path.yaml delete mode 100755 .chloggen/clarify-metric-namespace.yaml delete mode 100644 .chloggen/event_payload_in_body.yaml delete mode 100755 .chloggen/file.yaml delete mode 100755 .chloggen/fix_cpu_step.yaml delete mode 100755 .chloggen/http-request-response-size.yaml delete mode 100755 .chloggen/move-dotnet-metrics-experimental.yaml delete mode 100644 .chloggen/service-instance-id.yaml delete mode 100755 .chloggen/ua_wording.yaml delete mode 100755 .chloggen/url-ecs.yaml create mode 100644 schemas/1.25.0 diff --git a/.chloggen/433.yaml b/.chloggen/433.yaml deleted file mode 100644 index 0ca14de923..0000000000 --- a/.chloggen/433.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: enhancement -component: messaging -note: Add `messaging.rabbitmq.message.delivery_tag`` to the list of RabbitMQ specific tags -issues: [433] diff --git a/.chloggen/509.yaml b/.chloggen/509.yaml deleted file mode 100644 index 620f8e134f..0000000000 --- a/.chloggen/509.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: messaging - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Clarify producer span relationships for messaging semantic conventions - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [509] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/627.yaml b/.chloggen/627.yaml deleted file mode 100755 index 1e96d83745..0000000000 --- a/.chloggen/627.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: rpc - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add link to specification for metrics defined by gRPC community. - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [627] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/661.yaml b/.chloggen/661.yaml deleted file mode 100644 index dde1142c34..0000000000 --- a/.chloggen/661.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: messaging - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add messaging semantic conventions for settlement spans - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [621] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/697.yaml b/.chloggen/697.yaml deleted file mode 100644 index e6bb861718..0000000000 --- a/.chloggen/697.yaml +++ /dev/null @@ -1,7 +0,0 @@ -change_type: enhancement - -component: messaging - -note: Clarifies span names for Azure messaging systems and adds `messaging.servicebus.disposition_status attribute`. - -issues: [697] diff --git a/.chloggen/698.yaml b/.chloggen/698.yaml deleted file mode 100644 index c12d9d9f2d..0000000000 --- a/.chloggen/698.yaml +++ /dev/null @@ -1,7 +0,0 @@ -change_type: breaking - -component: messaging - -note: Remove `network.transport` and `network.type` attributes from messaging semantic conventions, clarify when `network.peer.address|port` should be populated. - -issues: [690, 698] diff --git a/.chloggen/700.yaml b/.chloggen/700.yaml deleted file mode 100644 index 5272119136..0000000000 --- a/.chloggen/700.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: messaging - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add a "Process" spans and metrics for messaging - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [657] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/738.yaml b/.chloggen/738.yaml deleted file mode 100644 index 1d09182d8a..0000000000 --- a/.chloggen/738.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: db - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Update Elasticsearch attributes to use db.instance.id instead of db.elasticsearch.node.name - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [725] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/768.yaml b/.chloggen/768.yaml deleted file mode 100644 index 7cceacd08b..0000000000 --- a/.chloggen/768.yaml +++ /dev/null @@ -1,7 +0,0 @@ -change_type: breaking - -component: db - -note: Remove `network.transport` and `network.type` attributes from database semantic conventions, clarify when `network.peer.address|port` should be populated. - -issues: [690, 768] diff --git a/.chloggen/769.yaml b/.chloggen/769.yaml deleted file mode 100644 index 8789e89f94..0000000000 --- a/.chloggen/769.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: deprecation -component: db -note: Deprecate `db.connection_string` attribute in favor of `server.address` and `server.port` -issues: [724, 769] diff --git a/.chloggen/778.yaml b/.chloggen/778.yaml deleted file mode 100644 index 03c1db8225..0000000000 --- a/.chloggen/778.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: bug_fix - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: aws-lambda - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Fix problem in `xray-lambda` propagator definition - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [778] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/780.yaml b/.chloggen/780.yaml deleted file mode 100644 index 626e967153..0000000000 --- a/.chloggen/780.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: enhancement -component: db -note: Merge DB connection-level and call-level attributes tables -issues: [780] diff --git a/.chloggen/785.yaml b/.chloggen/785.yaml deleted file mode 100644 index f00ba848ef..0000000000 --- a/.chloggen/785.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: enhancement -component: dns -note: Introduces common DNS lookup duration metric and attributes. -issues: [404] diff --git a/.chloggen/796.yaml b/.chloggen/796.yaml deleted file mode 100644 index 725dc48513..0000000000 --- a/.chloggen/796.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: deprecation -component: db -note: Deprecate `db.jdbc.driver_classname` attribute -issues: [796] diff --git a/.chloggen/798.yaml b/.chloggen/798.yaml deleted file mode 100644 index 95e89a8b1f..0000000000 --- a/.chloggen/798.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: breaking -component: messaging -note: Introduce common `messaging.destination.partition.id` instead of `messaging.kafka.destination.partition` -issues: [798] diff --git a/.chloggen/804.yaml b/.chloggen/804.yaml deleted file mode 100644 index 81b0ce5a1d..0000000000 --- a/.chloggen/804.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: bug_fix - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: http - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Two fixes to the HTTP semconv migration guide - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [ 802 ] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/817.yaml b/.chloggen/817.yaml deleted file mode 100644 index bf56ad5daa..0000000000 --- a/.chloggen/817.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: bug_fix -component: network -note: Clarifies that network.protocol.version represents negotiated version -issues: [ 686 ] diff --git a/.chloggen/820.yaml b/.chloggen/820.yaml deleted file mode 100644 index 85ac249f44..0000000000 --- a/.chloggen/820.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: enhancement -component: other -note: Update build-tools version to 0.24.0 and make semantic conventions compatible with this version (add stability on enum members and deprecated attributes). -issues: [ 807 ] diff --git a/.chloggen/add_cpu_state_constraint.yaml b/.chloggen/add_cpu_state_constraint.yaml deleted file mode 100755 index 87edf707f1..0000000000 --- a/.chloggen/add_cpu_state_constraint.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: 'enhancement' - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: 'system' - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Align `system.cpu.state`'s definition with this of `process.cpu.state`. - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [563] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/add_new_container_metrics.yaml b/.chloggen/add_new_container_metrics.yaml deleted file mode 100644 index 4e6c71bb49..0000000000 --- a/.chloggen/add_new_container_metrics.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: "enhancement" - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: "container" - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "Add new container metrics for `cpu`, `memory`, `disk` and `network`" - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -issues: [282, 72] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/allow-sanitizing-url-path.yaml b/.chloggen/allow-sanitizing-url-path.yaml deleted file mode 100644 index 29d4311168..0000000000 --- a/.chloggen/allow-sanitizing-url-path.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: url - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Sensitive content provided in `url.full`, `url.path`, and `url.query` SHOULD be scrubbed when instrumentations can identify it. - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [676] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/clarify-metric-namespace.yaml b/.chloggen/clarify-metric-namespace.yaml deleted file mode 100755 index 7fffee1683..0000000000 --- a/.chloggen/clarify-metric-namespace.yaml +++ /dev/null @@ -1,5 +0,0 @@ -change_type: 'enhancement' -component: metrics -note: Clarify metric attributes should be namespaced. -issues: [394] -subtext: diff --git a/.chloggen/event_payload_in_body.yaml b/.chloggen/event_payload_in_body.yaml deleted file mode 100644 index 8ac0c36291..0000000000 --- a/.chloggen/event_payload_in_body.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: events - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add clarification that the body of an Event will live in the LogRecord body field. - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -issues: [ 566] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/file.yaml b/.chloggen/file.yaml deleted file mode 100755 index 20bcdca15b..0000000000 --- a/.chloggen/file.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: new_component - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: file - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add new file namespace - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [732] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/fix_cpu_step.yaml b/.chloggen/fix_cpu_step.yaml deleted file mode 100755 index 9633748d8c..0000000000 --- a/.chloggen/fix_cpu_step.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: "breaking" - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: 'host' - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "[resource/host] Change type of host.cpu.stepping to string" - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [664, 665] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/http-request-response-size.yaml b/.chloggen/http-request-response-size.yaml deleted file mode 100755 index c823b94a91..0000000000 --- a/.chloggen/http-request-response-size.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: http - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add `http.request.size` and `http.response.size` attributes for the total number of bytes in http messages - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [38, 84] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/move-dotnet-metrics-experimental.yaml b/.chloggen/move-dotnet-metrics-experimental.yaml deleted file mode 100755 index f2812b3aa1..0000000000 --- a/.chloggen/move-dotnet-metrics-experimental.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: enhancement -component: http -note: Extracts common HTTP client metrics from .NET conventions. -issues: [800] diff --git a/.chloggen/service-instance-id.yaml b/.chloggen/service-instance-id.yaml deleted file mode 100644 index 34acc9cf03..0000000000 --- a/.chloggen/service-instance-id.yaml +++ /dev/null @@ -1,4 +0,0 @@ -change_type: 'enhancement' -component: resource -note: Define a common algorithm for `service.instance.id`. -issues: [312] diff --git a/.chloggen/ua_wording.yaml b/.chloggen/ua_wording.yaml deleted file mode 100755 index b8be0677f0..0000000000 --- a/.chloggen/ua_wording.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: user-agent - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Update user_agent subfields wording to support it's usage for non-browser products with multiple names/versions - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [680] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/.chloggen/url-ecs.yaml b/.chloggen/url-ecs.yaml deleted file mode 100755 index 1c61cb40c3..0000000000 --- a/.chloggen/url-ecs.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Use this changelog template to create an entry for release notes. -# -# If your change doesn't affect end users you should instead start -# your pull request title with [chore] or use the "Skip Changelog" label. - -# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' -change_type: enhancement - -# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) -component: url - -# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add remaining ECS fields to the url namespace - -# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. -# The values here must be integers. -issues: [496] - -# (Optional) One or more lines of additional information to render under the primary note. -# These lines will be padded with 2 spaces and then inserted directly into the document. -# Use pipe (|) for multiline entries. -subtext: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7537d61028..7e1071d8e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,19 +6,25 @@ # Changelog - ## Unreleased ### Breaking -- Rename `system.processes.*` namespace to `system.process.*` - ([#484](https://github.com/open-telemetry/semantic-conventions/pull/484)) -- Depluralize labels for pod (`k8s.pod.labels.*`) and container (`container.labels.*`) resources - ([#625](https://github.com/open-telemetry/semantic-conventions/pull/625)) -- Make `network.protocol.name` conditionally required for messaging - ([#644](https://github.com/open-telemetry/semantic-conventions/pull/644)) -- BREAKING: Generate process metrics from YAML - ([#330](https://github.com/open-telemetry/semantic-conventions/pull/330)) +### Features + +### Fixes + +## v1.25.0 + +### 🛑 Breaking changes 🛑 + +- `messaging`: Remove `network.transport` and `network.type` attributes from messaging semantic conventions, clarify when `network.peer.address|port` should be populated. (#690, #698) +- `db`: Remove `network.transport` and `network.type` attributes from database semantic conventions, clarify when `network.peer.address|port` should be populated. (#690, #768) +- `messaging`: Introduce common `messaging.destination.partition.id` instead of `messaging.kafka.destination.partition` (#798) +- `host`: [resource/host] Change type of host.cpu.stepping to string (#664, #665) +- `system`: Rename `system.processes.*` namespace to `system.process.*`(#484) +- `k8s`, `container`: Depluralize labels for pod (`k8s.pod.labels.*`) and container (`container.labels.*`) resources (#625) +- `process`: Generate process metrics from YAML (#330): - Rename `process.threads` to `process.thread.count` - Rename `process.open_file_descriptors` to `process.open_file_descriptor.count` - Rename attributes for `process.cpu.*` @@ -31,23 +37,51 @@ - `type` to `process.context_switch_type` - Rename attributes for `process.paging.faults` - `type` to `process.paging.fault_type` -- Fix JVM buffer metric schema translations - ([#683](https://github.com/open-telemetry/semantic-conventions/pull/683)) - -### Features -- Add `azure_container_apps` to `cloud.platform` semantic conventions - ([#615](https://github.com/open-telemetry/semantic-conventions/pull/615)) -- Add `user_agent.name` and `user_agent.version` attributes - ([#452](https://github.com/open-telemetry/semantic-conventions/pull/452/)) -- Add an example for gcp_pubsub asynchronous batch publish - ([#545](https://github.com/open-telemetry/semantic-conventions/pull/545)) -- Add `aws.ecs.task.id` attribute, corrected description for `aws.ecs.task.arn`. - ([#597](https://github.com/open-telemetry/semantic-conventions/pull/597)) -- Add Azure Service Bus and Event Hubs messaging attributes - ([#572](https://github.com/open-telemetry/semantic-conventions/pull/572)) - -### Fixes +### 🚩 Deprecations 🚩 + +- `db`: Deprecate `db.connection_string` attribute in favor of `server.address` and `server.port` (#724, #769) +- `db`: Deprecate `db.jdbc.driver_classname` attribute (#796) + +### 🚀 New components 🚀 + +- `file`: Add new file namespace (#732) + +### 💡 Enhancements 💡 + +- `messaging`: Add `messaging.rabbitmq.message.delivery_tag`` to the list of RabbitMQ specific tags (#433) +- `messaging`: Clarify producer span relationships for messaging semantic conventions (#509) +- `rpc`: Add link to specification for metrics defined by gRPC community. (#627) +- `messaging`: Add messaging semantic conventions for settlement spans (#621) +- `messaging`: Clarifies span names for Azure messaging systems and adds `messaging.servicebus.disposition_status attribute`. (#697) +- `messaging`: Add a "Process" spans and metrics for messaging (#657) +- `db`: Update Elasticsearch attributes to use db.instance.id instead of db.elasticsearch.node.name (#725) +- `db`: Merge DB connection-level and call-level attributes tables (#780) +- `dns`: Introduces common DNS lookup duration metric and attributes. (#404) +- `other`: Update build-tools version to 0.24.0 and make semantic conventions compatible with this version (add stability on enum members and deprecated attributes). (#807) +- `system`: Align `system.cpu.state`'s definition with this of `process.cpu.state`. (#563) +- `container`: Add new container metrics for `cpu`, `memory`, `disk` and `network` (#282, #72) +- `url`: Sensitive content provided in `url.full`, `url.path`, and `url.query` SHOULD be scrubbed when instrumentations can identify it. (#676) +- `metrics`: Clarify metric attributes should be namespaced. (#394) +- `events`: Add clarification that the body of an Event will live in the LogRecord body field. (#566) +- `http`: Add `http.request.size` and `http.response.size` attributes for the total number of bytes in http messages (#38, #84) +- `http`: Extracts common HTTP client metrics from .NET conventions. (#800) +- `resource`: Define a common algorithm for `service.instance.id`. (#312) +- `user-agent`: Update user_agent subfields wording to support it's usage for non-browser products with multiple names/versions (#680) +- `url`: Add remaining ECS fields to the url namespace (#496) +- `messaging`: Make `network.protocol.name` conditionally required for messaging (#644) +- `cloud`: Add `azure_container_apps` to `cloud.platform` semantic conventions (#615) +- `user_agent`: Add `user_agent.name` and `user_agent.version` attributes (#452) +- `messaging`: Add an example for gcp_pubsub asynchronous batch publish (#545) +- `aws`: Add `aws.ecs.task.id` attribute, corrected description for `aws.ecs.task.arn` (#597) +- `messaging`: Add Azure Service Bus and Event Hubs messaging attributes (#572) + +### 🧰 Bug fixes 🧰 + +- `aws-lambda`: Fix problem in `xray-lambda` propagator definition (#778) +- `http`: Two fixes to the HTTP semconv migration guide (#802) +- `network`: Clarifies that network.protocol.version represents negotiated version (#686) +- `jvm`: Fix JVM buffer metric schema translations (#683) ## v1.24.0 (2023-12-15) diff --git a/README.md b/README.md index 80a69eb1b9..0dad278343 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Checks](https://github.com/open-telemetry/semantic-conventions/workflows/Checks/badge.svg?branch=main)](https://github.com/open-telemetry/semantic-conventions/actions?query=workflow%3A%22Checks%22+branch%3Amain) [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/open-telemetry/semantic-conventions.svg?logo=opentelemetry&&color=f5a800&label=Latest%20release)](https://github.com/open-telemetry/semantic-conventions/releases/latest) -[![Specification Version](https://img.shields.io/badge/OTel_specification_version-v1.26.0-blue?logo=opentelemetry&color=f5a800)](https://github.com/open-telemetry/opentelemetry-specification/releases/tag/v1.26.0) +[![Specification Version](https://img.shields.io/badge/OTel_specification_version-v1.31.0-blue?logo=opentelemetry&color=f5a800)](https://github.com/open-telemetry/opentelemetry-specification/releases/tag/v1.31.0) Semantic Conventions define a common set of (semantic) attributes which provide meaning to data when collecting, producing and consuming it. diff --git a/docs/cloud-providers/README.md b/docs/cloud-providers/README.md index 8e88f408fc..863836b98d 100644 --- a/docs/cloud-providers/README.md +++ b/docs/cloud-providers/README.md @@ -15,4 +15,4 @@ Semantic conventions exist for the following cloud provider SDKs: - [AWS SDK](aws-sdk.md): Semantic Conventions for the _AWS SDK_. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/cloud-providers/aws-sdk.md b/docs/cloud-providers/aws-sdk.md index a23c543d33..3ebbf26a9b 100644 --- a/docs/cloud-providers/aws-sdk.md +++ b/docs/cloud-providers/aws-sdk.md @@ -45,4 +45,4 @@ The following Semantic Conventions extend the general AWS SDK attributes for spe - [AWS DynamoDB](/docs/database/dynamodb.md): Semantic Conventions for _AWS DynamoDB_. - [AWS S3](/docs/object-stores/s3.md): Semantic Conventions for _AWS S3_. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/cloudevents/README.md b/docs/cloudevents/README.md index beb6527e62..e97a44c391 100644 --- a/docs/cloudevents/README.md +++ b/docs/cloudevents/README.md @@ -15,4 +15,4 @@ Semantic conventions for CloudEvents are defined for the following signals: - [CloudEvents Spans](cloudevents-spans.md): Semantic Conventions for modeling CloudEvents as _spans_. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 7587bad336..4e75370331 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -210,4 +210,4 @@ The following attributes are applicable to creation and processing Spans. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/README.md b/docs/database/README.md index ff0b546d8b..6222376394 100644 --- a/docs/database/README.md +++ b/docs/database/README.md @@ -37,4 +37,4 @@ Technology specific semantic conventions are defined for the following databases * [Redis](redis.md): Semantic Conventions for *Redis*. * [SQL](sql.md): Semantic Conventions for *SQL* databases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 96ff729430..342fdc4053 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -51,4 +51,4 @@ described on this page. | `local_serial` | local_serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 822ddeccc7..5ec6dd24dc 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -90,4 +90,4 @@ In addition to Cosmos DB attributes, all spans include | `db.cosmosdb.sub_status_code` | `0` | | `db.cosmosdb.request_charge` | `7.43` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index a7ba93e347..ebd42dd9b4 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -22,4 +22,4 @@ described on this page. **[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 03c69cb6e2..cff733d139 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -190,6 +190,6 @@ This metric is [recommended][MetricRecommended]. | `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricRequired]: /docs/general/metric-requirement-level.md#required [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 7f9d792e34..972635b38d 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -190,4 +190,4 @@ More specific Semantic Conventions are defined for the following database techno * [Redis](redis.md): Semantic Conventions for *Redis*. * [SQL](sql.md): Semantic Conventions for *SQL* databases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index 09f1a98082..a7b6f048a3 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -170,4 +170,4 @@ These attributes are filled in for all DynamoDB request types. | [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 2b85f275b8..50cbc3c273 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -107,4 +107,4 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `db.elasticsearch.cluster.name` | `"e9106fc68e3044f0b1475b04bf4ffd5f"` | | `db.instance.id` | `"instance-0000000001"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 45a665eef1..290525590d 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -22,4 +22,4 @@ described on this page. **[1]:** For HBase the `db.name` should be set to the HBase namespace. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 2bd73c8df3..c733f4ffb0 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -37,4 +37,4 @@ described on this page. | `db.operation` | `"findAndModify"` | | `db.mongodb.collection` | `"products"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 90c80af32d..20829283c2 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -25,4 +25,4 @@ described on this page. **[2]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index be0897ba42..da70edf142 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -46,4 +46,4 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.operation` | not set | | `db.redis.database_index` | `15` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index 32aeaa31cb..1357ac2003 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -39,4 +39,4 @@ This is an example of attributes for a MySQL database span: | `db.operation` | `"SELECT"` | | `db.sql.table` | `"orders"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dns/dns-metrics.md b/docs/dns/dns-metrics.md index 7c67b1f9e6..292e351749 100644 --- a/docs/dns/dns-metrics.md +++ b/docs/dns/dns-metrics.md @@ -24,7 +24,7 @@ This document defines semantic conventions to apply when instrumenting DNS queri This metric is optional. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -50,4 +50,4 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/README.md b/docs/dotnet/README.md index a8b5f7bbd2..e2c09609d8 100644 --- a/docs/dotnet/README.md +++ b/docs/dotnet/README.md @@ -19,4 +19,4 @@ The following metrics are currently supported: * [Kestrel](dotnet-kestrel-metrics.md): Semantic Conventions for Kestrel web server *metrics*. * [SignalR](dotnet-signalr-metrics.md): Semantic Conventions for SignalR server *metrics*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index 95617251d4..d2b8491d18 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -138,7 +138,7 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting ### Metric: `aspnetcore.rate_limiting.request_lease.duration` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -178,7 +178,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ### Metric: `aspnetcore.rate_limiting.request.time_in_queue` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -240,4 +240,4 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-dns-metrics.md b/docs/dotnet/dotnet-dns-metrics.md index 6df6fb85d3..6b10c7e575 100644 --- a/docs/dotnet/dotnet-dns-metrics.md +++ b/docs/dotnet/dotnet-dns-metrics.md @@ -20,7 +20,7 @@ This article defines semantic conventions for DNS metrics emitted by .NET. ### Metric: `dns.lookup.duration` This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -54,4 +54,4 @@ for more details. |---|---| | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-http-metrics.md b/docs/dotnet/dotnet-http-metrics.md index e59166dd01..a203d433a6 100644 --- a/docs/dotnet/dotnet-http-metrics.md +++ b/docs/dotnet/dotnet-http-metrics.md @@ -77,7 +77,7 @@ Notes: ### Metric: `http.client.connection.duration` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. @@ -106,7 +106,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. ### Metric: `http.client.request.time_in_queue` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -217,4 +217,4 @@ Notes: - Opt-in `server.address` and `server.port` attributes are not reported - Metric added in ASP.NET Core 8.0 -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md index 34727f84e2..c25638eb7b 100644 --- a/docs/dotnet/dotnet-kestrel-metrics.md +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -80,7 +80,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. ## Metric: `kestrel.connection.duration` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. @@ -344,7 +344,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. ## Metric: `kestrel.tls_handshake.duration` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -449,4 +449,4 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index 73471c645b..f2c5b73257 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -18,7 +18,7 @@ This article defines semantic conventions for SignalR metrics emitted by .NET co ## Metric: `signalr.server.connection.duration` this metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. @@ -85,4 +85,4 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/exceptions/README.md b/docs/exceptions/README.md index 4632585126..5791b59882 100644 --- a/docs/exceptions/README.md +++ b/docs/exceptions/README.md @@ -16,4 +16,4 @@ Semantic conventions for Exceptions are defined for the following signals: * [Exceptions on spans](exceptions-spans.md): Semantic Conventions for Exceptions associated with *spans*. * [Exceptions in logs](exceptions-logs.md): Semantic Conventions for Exceptions recorded in *logs*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 1365a02753..e19e35330c 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -7,8 +7,8 @@ linkTitle: Logs **Status**: [Stable][DocumentStatus] This document defines semantic conventions for recording exceptions on -[logs](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#emit-a-logrecord) and [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/event-api.md#emit-event) -emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger). +[logs](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/bridge-api.md#emit-a-logrecord) and [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/event-api.md#emit-event) +emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/bridge-api.md#logger). @@ -21,7 +21,7 @@ emitted through the [Logger API](https://github.com/open-telemetry/opentelemetry ## Recording an Exception Exceptions SHOULD be recorded as attributes on the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger) emit +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/bridge-api.md#logger) emit operations. Exceptions MAY be recorded on "logs" or "events" depending on the context. @@ -33,7 +33,7 @@ the language runtime. ## Attributes The table below indicates which attributes should be added to the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | @@ -53,4 +53,4 @@ The table below indicates which attributes should be added to the Same as [Trace Semantic Conventions for Exceptions - Stacktrace Representation](exceptions-spans.md#stacktrace-representation). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index 66ff658c1a..c438e9951b 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -23,7 +23,7 @@ An exception SHOULD be recorded as an `Event` on the span during which it occurr The name of the event MUST be `"exception"`. A typical template for an auto-instrumentation implementing this semantic convention -using an [API-provided `recordException` method](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#record-exception) +using an [API-provided `recordException` method](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#record-exception) could look like this (pseudo-Java): ```java @@ -109,4 +109,4 @@ grained information from a stacktrace, if necessary. [telemetry-sdk-resource]: ../resource/README.md#telemetry-sdk [erlang-stacktrace]: https://www.erlang.org/doc/man/erl_error.html#format_exception-3 [elixir-stacktrace]: https://hexdocs.pm/elixir/1.14.3/Exception.html#format/3 -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/faas/README.md b/docs/faas/README.md index 19ab9d3131..760672a0f6 100644 --- a/docs/faas/README.md +++ b/docs/faas/README.md @@ -20,4 +20,4 @@ Technology specific semantic conventions are defined for the following FaaS serv * [AWS Lambda](aws-lambda.md): Semantic Conventions for *AWS Lambda*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index f980a2b2f1..82c0a4c332 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -153,7 +153,7 @@ be ` process`. If there are multiple sources in the batch, the nam For every message in the event, the [message system attributes][] (not message attributes, which are provided by the user) SHOULD be checked for the key `AWSTraceHeader`. If it is present, an OpenTelemetry `Context` SHOULD be -parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) and +parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/context/api-propagators.md) and added as a link to the span. This means the span may have as many links as messages in the batch. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. @@ -166,7 +166,7 @@ See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context- For the SQS message span, the name MUST be ` process`. The parent MUST be the `CONSUMER` span corresponding to the SQS event. The [message system attributes][] (not message attributes, which are provided by the user) SHOULD be checked for the key `AWSTraceHeader`. If it is present, an OpenTelemetry `Context` SHOULD be -parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/context/api-propagators.md) and +parsed from the value of the attribute using the [AWS X-Ray Propagator](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/context/api-propagators.md) and added as a link to the span. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. @@ -290,4 +290,4 @@ because it is not available until function invocation. [environment variables]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index e7211edf2c..8e0d1adf69 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -46,7 +46,7 @@ The following metrics are recorded by the FaaS instance. This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -76,7 +76,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -236,7 +236,7 @@ This metric is [recommended][MetricRecommended]. This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -300,5 +300,5 @@ FaaS providers. This list is not exhaustive. * [Google CloudFunctions Metrics](https://cloud.google.com/monitoring/api/metrics_gcp#gcp-cloudfunctions) * [OpenFaas Metrics](https://docs.openfaas.com/architecture/metrics/) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 3b49cc5bca..8c39ede149 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -261,4 +261,4 @@ This example shows the FaaS attributes for a (non-FaaS) process hosted on Google | Resource | `faas.instance` | n/a | `"my-lambda-function:instance-0001"` | | Resource | `cloud.resource_id` | n/a | `"arn:aws:lambda:us-west-2:123456789012:function:my-lambda-function"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/feature-flags/README.md b/docs/feature-flags/README.md index a55b42b7d9..38acc00d52 100644 --- a/docs/feature-flags/README.md +++ b/docs/feature-flags/README.md @@ -17,4 +17,4 @@ Semantic conventions for feature flags are defined for the following signals: * [Feature Flags in Spans](feature-flags-spans.md): Semantic Conventions for recording feature flags in *spans*. * [Feature Flags in Logs](feature-flags-logs.md): Semantic Conventions for recording feature flags in *logs*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/feature-flags/feature-flags-logs.md b/docs/feature-flags/feature-flags-logs.md index e9db9d3a2d..02624c257c 100644 --- a/docs/feature-flags/feature-flags-logs.md +++ b/docs/feature-flags/feature-flags-logs.md @@ -7,8 +7,8 @@ linkTitle: Logs **Status**: [Experimental][DocumentStatus] This document defines semantic conventions for recording feature flag evaluations as -a [log record](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) emitted through the -[Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#emit-a-logrecord). +a [log record](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) emitted through the +[Logger API](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/bridge-api.md#emit-a-logrecord). This is useful when a flag is evaluated outside of a transaction context such as when the application loads or on a timer. To record a flag evaluation as a part of a transaction context, @@ -28,14 +28,14 @@ section of the trace semantic convention for feature flag evaluations. ## Recording an Evaluation Feature flag evaluations SHOULD be recorded as attributes on the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/bridge-api.md#logger) emit +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) passed to the [Logger](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/bridge-api.md#logger) emit operations. Evaluations MAY be recorded on "logs" or "events" depending on the context. ## Attributes The table below indicates which attributes should be added to the -[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. +[LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. The event name MUST be `feature_flag`. @@ -56,4 +56,4 @@ semantic identifier is unavailable. String representation of the value should be determined by the implementer. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/feature-flags/feature-flags-spans.md b/docs/feature-flags/feature-flags-spans.md index 8a6548338e..6dd85fa18a 100644 --- a/docs/feature-flags/feature-flags-spans.md +++ b/docs/feature-flags/feature-flags-spans.md @@ -60,4 +60,4 @@ semantic identifier is unavailable. String representation of the value should be determined by the implementer. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index f0eec71dbb..9f4e93dd45 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -157,4 +157,4 @@ Any additions to the `otel.*` namespace MUST be approved as part of OpenTelemetry specification. [DocumentStatus]: - https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/attribute-requirement-level.md b/docs/general/attribute-requirement-level.md index 4fe6ddb9dd..d16d073372 100644 --- a/docs/general/attribute-requirement-level.md +++ b/docs/general/attribute-requirement-level.md @@ -21,7 +21,7 @@ _This section applies to Log, Metric, Resource, and Span, and describes requirement levels for attributes defined in semantic conventions._ Attribute requirement levels apply to the -[instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/glossary.md#instrumentation-library). +[instrumentation library](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/glossary.md#instrumentation-library). The following attribute requirement levels are specified: @@ -124,4 +124,4 @@ Here are several examples of expensive operations to be avoided by default: `Content-Length` header is not available [DocumentStatus]: - https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/attributes.md b/docs/general/attributes.md index f0df39d9c8..9ef3ec0b6c 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -392,4 +392,4 @@ about the span. | [`code.stacktrace`](../attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/events.md b/docs/general/events.md index 8f3e51c2f8..73668bb423 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -57,7 +57,7 @@ that identify the class of Events but not the instance of the Event. |---|---|---|---|---|---| | `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. +**[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/logs.md b/docs/general/logs.md index 2debe8fc08..748c2e61fc 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -28,7 +28,7 @@ The following semantic conventions for logs are defined: * [Feature Flags](/docs/feature-flags/feature-flags-logs.md): Semantic attributes that may be used in describing feature flag evaluations in logs. Apart from semantic conventions for logs, [events](events.md), [traces](trace.md), and [metrics](metrics.md), -OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with their own +OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). ## General log identification attributes @@ -48,7 +48,7 @@ The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID This section describes attributes for log media in OpenTelemetry. Log media are mechanisms by which logs are transmitted. Types of media include files, streams, network protocols, and os-specific logging services such as journald and Windows Event Log. -**Note:** The OpenTelemetry specification defines a [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md#resource-sdk) as `an immutable representation of the entity producing telemetry`. +**Note:** The OpenTelemetry specification defines a [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md#resource-sdk) as `an immutable representation of the entity producing telemetry`. The following attributes do not describe entities that produce telemetry. Rather, they describe mechanisms of log transmission. As such, these should be recorded as Log Record attributes when applicable. They should not be recorded as Resource attributes. @@ -82,4 +82,4 @@ As such, these should be recorded as Log Record attributes when applicable. They | `stderr` | Events from stderr stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/metric-requirement-level.md b/docs/general/metric-requirement-level.md index e9de297124..8372acdbca 100644 --- a/docs/general/metric-requirement-level.md +++ b/docs/general/metric-requirement-level.md @@ -40,4 +40,4 @@ Instrumentation that doesn't support configuration MUST NOT emit `Opt-In` metric This attribute requirement level is recommended for metrics that are particularly expensive to retrieve or might pose a security or privacy risk. These should therefore only be enabled deliberately by a user making an informed decision. [DocumentStatus]: - https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md + https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/metrics.md b/docs/general/metrics.md index d76440f253..0e8e656c8c 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -39,7 +39,7 @@ The following semantic conventions surrounding metrics are defined: * [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. Apart from semantic conventions for metrics, [traces](trace.md), [logs](logs.md), and [events](events.md), OpenTelemetry also -defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with +defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). ## General Guidelines @@ -120,7 +120,7 @@ usable. When building components that interoperate between OpenTelemetry and a system using the OpenMetrics exposition format, use the -[OpenMetrics Guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/compatibility/prometheus_and_openmetrics.md). +[OpenMetrics Guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/compatibility/prometheus_and_openmetrics.md). ### Naming rules for Counters and UpDownCounters @@ -259,4 +259,4 @@ For example, if you are tracking `active_requests` with an `UpDownCounter`, and request starts and decrementing it each time a request ends, then any attributes which are not yet available when incrementing the counter at request start should not be used when decrementing the counter at request end. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/session.md b/docs/general/session.md index 93a2b9d65c..876d74d403 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -24,4 +24,4 @@ backends can link the two sessions. | [`session.previous_id`](../attributes-registry/session.md) | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index abdc34d4f8..28d142cdf3 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -39,4 +39,4 @@ between a child Span and a parent Span, as defined by | `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/trace.md b/docs/general/trace.md index 4dd8f79411..ca9d88fa88 100644 --- a/docs/general/trace.md +++ b/docs/general/trace.md @@ -34,7 +34,7 @@ The following semantic conventions for spans are defined: * [RPC/RMI](/docs/rpc/rpc-spans.md): For remote procedure call (e.g., gRPC) spans. Apart from semantic conventions for traces, [metrics](metrics.md), [logs](logs.md), and [events](events.md), -OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) with their own +OpenTelemetry also defines the concept of overarching [Resources](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md) with their own [Resource Semantic Conventions](/docs/resource/README.md). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/graphql/graphql-spans.md b/docs/graphql/graphql-spans.md index 98d62a4b61..e0d30aaa9b 100644 --- a/docs/graphql/graphql-spans.md +++ b/docs/graphql/graphql-spans.md @@ -32,4 +32,4 @@ MAY be used as span name. | `subscription` | GraphQL subscription | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/http/README.md b/docs/http/README.md index 4bd1e41f73..e6b4bb4f20 100644 --- a/docs/http/README.md +++ b/docs/http/README.md @@ -44,4 +44,4 @@ Semantic conventions for HTTP are defined for the following signals: * [HTTP Spans](http-spans.md): Semantic Conventions for HTTP client and server *spans*. * [HTTP Metrics](http-metrics.md): Semantic Conventions for HTTP client and server *metrics*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index f61c862e63..7aaa901f9f 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -64,7 +64,7 @@ This metric is required. When this metric is reported alongside an HTTP server span, the metric value SHOULD be the same as the HTTP server span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -429,7 +429,7 @@ This metric is required. When this metric is reported alongside an HTTP client span, the metric value SHOULD be the same as the HTTP client span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -727,7 +727,7 @@ This metric is optional. ### Metric: `http.client.connection.duration` This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. This metric is optional. @@ -809,4 +809,4 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 07309707c9..6a350d5876 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -65,7 +65,7 @@ and various HTTP versions like 1.1, 2 and SPDY. ## Name -HTTP spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#span). +HTTP spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#span). @@ -89,7 +89,7 @@ default span name. ## Status -[Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be left unset if HTTP status code was in the +[Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#set-status) MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, unless there was another error (e.g., network error receiving the response body; or 3xx codes with max redirects exceeded), in which case status MUST be set to `Error`. @@ -556,5 +556,5 @@ Span name: `POST /uploads/:document_id`. | `http.response.status_code` | `201` | | `error.type` | `WebSocketDisconnect` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md -[SpanProcessor]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/sdk.md#span-processor +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md +[SpanProcessor]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/sdk.md#span-processor diff --git a/docs/messaging/README.md b/docs/messaging/README.md index 2ba98b5977..0d9e3b929c 100644 --- a/docs/messaging/README.md +++ b/docs/messaging/README.md @@ -23,4 +23,4 @@ Technology specific semantic conventions are defined for the following messaging * [RocketMQ](rocketmq.md): Semantic Conventions for *Apache RocketMQ*. * [Google Cloud Pub/Sub](gcp-pubsub.md): Semantic Conventions for *Google Cloud Pub/Sub*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 69318fa60c..ad68bdf0c5 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -59,4 +59,4 @@ The following additional attributes are defined: | [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 4729aab9bf..d1a7274b1b 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -58,4 +58,4 @@ flowchart LR; | `messaging.message.envelope.size` | `1` | `1` | | | `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 9fefba9f85..88beccf2d4 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -84,4 +84,4 @@ Process CB: | Span Rcv2 | | `messaging.kafka.destination.partition` | `"1"` | `"1"` | `"1"` | `"3"` | `"3"` | | `messaging.kafka.message.offset` | `"12"` | `"12"` | `"12"` | `"32"` | `"32"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 63caaf8e14..a49243c921 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -99,7 +99,7 @@ This metric is [required][MetricRequired]. When this metric is reported alongside a messaging publish span, the metric value SHOULD be the same as the corresponding span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. @@ -127,7 +127,7 @@ This metric is [required][MetricRequired] when the messaging system supports bat This metric is [required][MetricRequired] for operations that are initiated by the application code (pull-based). This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. When this metric is reported alongside a messaging receive span, the metric value SHOULD be the same as the corresponding span duration. @@ -157,7 +157,7 @@ This metric is [required][MetricRequired] for operations that are not initiated When this metric is reported alongside a messaging process span, the metric value SHOULD be the same as the corresponding span duration. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advice) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advice) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 12bb3cdc56..cfae7e750b 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -159,7 +159,7 @@ The span name SHOULD be set to the message destination name and the operation be ``` -The destination name SHOULD only be used for the span name if it is known to be of low cardinality (cf. [general span name guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#span)). +The destination name SHOULD only be used for the span name if it is known to be of low cardinality (cf. [general span name guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#span)). This can be assumed if it is statically derived from application code or configuration. Wherever possible, the real destination names after resolving logical or aliased names SHOULD be used. If the destination name is dynamic, such as a [conversation ID](#conversations) or a value obtained from a `Reply-To` header, it SHOULD NOT be used for the span name. @@ -193,7 +193,7 @@ The following operations related to messages are defined for these semantic conv ### Span kind -[Span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind) +[Span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#spankind) SHOULD be set according to the following table, based on the operation a span describes. | Operation name | Span kind| @@ -204,7 +204,7 @@ SHOULD be set according to the following table, based on the operation a span de | `process` | `CONSUMER` for push-based scenarios where no `receive` span exists. | For cases not covered by the table above, the span kind should be set according -to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind), +to the [generic specification about span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#spankind), e. g. it should be set to CLIENT for the "Publish" span if its context is not used as creation context and if the "Publish" span models a synchronous call to the intermediary. @@ -564,4 +564,4 @@ More specific Semantic Conventions are defined for the following messaging techn * [RabbitMQ](rabbitmq.md): Semantic Conventions for *RabbitMQ*. * [RocketMQ](rocketmq.md): Semantic Conventions for *Apache RocketMQ*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index c46a42a9ee..7bfac42160 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -28,4 +28,4 @@ In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. **[1]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index da940b4e89..c37538f903 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -52,4 +52,4 @@ Specific attributes for Apache RocketMQ are defined below. `messaging.client_id` SHOULD be set to the client ID that is automatically generated by the Apache RocketMQ SDK. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/object-stores/README.md b/docs/object-stores/README.md index 67637442ee..21189287ba 100644 --- a/docs/object-stores/README.md +++ b/docs/object-stores/README.md @@ -15,4 +15,4 @@ The following technology specific semantic conventions are defined for object st * [AWS S3](s3.md): Semantic Conventions for *AWS S3*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index 9f157352f1..cde1a48f32 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -68,4 +68,4 @@ This applies in particular to the following operations: - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/README.md b/docs/resource/README.md index 8dbdf78fbb..c00b0cbed8 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -9,7 +9,7 @@ path_base_for_github_subdir: **Status**: [Mixed][DocumentStatus] -This document defines standard attributes for resources. These attributes are typically used in the [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md) and are also recommended to be used anywhere else where there is a need to describe a resource in a consistent manner. The majority of these attributes are inherited from +This document defines standard attributes for resources. These attributes are typically used in the [Resource](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md) and are also recommended to be used anywhere else where there is a need to describe a resource in a consistent manner. The majority of these attributes are inherited from [OpenCensus Resource standard](https://github.com/census-instrumentation/opencensus-specs/blob/master/resource/StandardResources.md). @@ -59,14 +59,14 @@ Given their significance some resource attributes are treated specifically as de ### Semantic Attributes with Dedicated Environment Variable These are the attributes which MAY be configurable via a dedicated environment variable -as specified in [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/configuration/sdk-environment-variables.md): +as specified in [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/configuration/sdk-environment-variables.md): - [`service.name`](#service) ### Semantic Attributes with SDK-provided Default Value These are the attributes which MUST be provided by the SDK -as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/resource/sdk.md#sdk-provided-resource-attributes): +as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/resource/sdk.md#sdk-provided-resource-attributes): - [`service.name`](#service) - [`telemetry.sdk` group](#telemetry-sdk) @@ -261,4 +261,4 @@ Valid cloud providers are: - [Tencent Cloud](https://www.tencentcloud.com/) (`tencent_cloud`) - [Heroku dyno](./cloud-provider/heroku.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/android.md b/docs/resource/android.md index ab94f1cc98..bcb1317d10 100644 --- a/docs/resource/android.md +++ b/docs/resource/android.md @@ -12,4 +12,4 @@ | [`android.os.api_level`](../attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/browser.md b/docs/resource/browser.md index 4ab2541c1c..cc11276d76 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -29,4 +29,4 @@ The list of possible values is defined in the [W3C User-Agent Client Hints speci **[5]:** The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/README.md b/docs/resource/cloud-provider/README.md index 1be2cbd21c..074f5d473f 100644 --- a/docs/resource/cloud-provider/README.md +++ b/docs/resource/cloud-provider/README.md @@ -15,4 +15,4 @@ This document defines semantic conventions for resource cloud providers. * [GCP](gcp/README.md): Semantic Conventions for Google Cloud Platform. * [Heroku](heroku.md): Semantic Conventions for Heroku. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/README.md b/docs/resource/cloud-provider/aws/README.md index 1409a89b5f..1cf7113b3d 100644 --- a/docs/resource/cloud-provider/aws/README.md +++ b/docs/resource/cloud-provider/aws/README.md @@ -28,4 +28,4 @@ Attributes that relate to an individual AWS service: - [Elastic Container Service (ECS)](./ecs.md) - [Elastic Kubernetes Service (EKS)](./eks.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index a8fe3942bc..a682c75c22 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -25,4 +25,4 @@ | `fargate` | fargate | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/eks.md b/docs/resource/cloud-provider/aws/eks.md index a52ac56557..1d6531289d 100644 --- a/docs/resource/cloud-provider/aws/eks.md +++ b/docs/resource/cloud-provider/aws/eks.md @@ -12,4 +12,4 @@ | `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index 95558b7b77..d35c994d83 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -21,4 +21,4 @@ **[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/README.md b/docs/resource/cloud-provider/gcp/README.md index 6b115235ea..18e17e81f9 100644 --- a/docs/resource/cloud-provider/gcp/README.md +++ b/docs/resource/cloud-provider/gcp/README.md @@ -19,4 +19,4 @@ provider (like account ID, operating system, etc), it belongs in the parent - [Cloud Run](./cloud-run.md) - [Compute Engine](./gce.md) -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index e188ddf688..161d79237a 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -15,4 +15,4 @@ These conventions are recommended for resources running on Cloud Run. | [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp-cloud-run.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index 244133673e..b16a2b620d 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -29,4 +29,4 @@ Additionally, [the `cloud.provider` resource attribute MUST be set to `heroku`]( [Heroku dyno metadata]: https://devcenter.heroku.com/articles/dyno-metadata -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index b112f948d5..65ed76d78e 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -86,4 +86,4 @@ The following well-known definitions MUST be used if you set this attribute and | `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/container.md b/docs/resource/container.md index 4f5ddb2211..b33f646058 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -34,4 +34,4 @@ An example can be found in [Example Image Manifest](https://docs.docker.com/regi **[4]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index 7957a9a3ff..7c00e968d8 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -20,4 +20,4 @@ considered to be identifying the same service: * `service.name=frontend`, `deployment.environment=staging`. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/device.md b/docs/resource/device.md index 603ef93c51..6d76dd4ff5 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -23,4 +23,4 @@ **[4]:** It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/faas.md b/docs/resource/faas.md index c7c3bc76d5..4f98555d38 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -80,4 +80,4 @@ There are cases where a FaaS resource attribute is better applied as a span attribute instead. See the [FaaS trace conventions](/docs/faas/faas-spans.md) for more. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/host.md b/docs/resource/host.md index 7eb33feb17..0c5c08daa2 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -81,4 +81,4 @@ detector implementations MUST not collect `host.id` from privileged sources. If privileged lookup of `host.id` is required, the value should be injected via the `OTEL_RESOURCE_ATTRIBUTES` environment variable. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index f67ad0957b..c26e90b3ee 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -212,4 +212,4 @@ A CronJob creates Jobs on a repeating schedule. | [`k8s.cronjob.uid`](../attributes-registry/k8s.md) | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/os.md b/docs/resource/os.md index 02fb418bea..7eb0454c94 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -34,4 +34,4 @@ In case of virtualized environments, this is the operating system as it is obser | `z_os` | IBM z/OS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/process.md b/docs/resource/process.md index f52861ee86..aa9ccea63f 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -234,4 +234,4 @@ Examples for some Ruby runtimes | MRI | ruby | 2.7.1 | ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19] | | TruffleRuby | truffleruby | 2.6.2 | truffleruby (Shopify) 20.0.0-dev-92ed3059, like ruby 2.6.2, GraalVM CE Native [x86_64-darwin] | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 6589e85faf..0f136433ef 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -23,4 +23,4 @@ The situations where there are multiple candidates, it is up to instrumentation * Either Apache HTTP Server or `mod_wsgi` MAY be chosen as `webengine`, depending on the decision made by the instrumentation authors. * Django SHOULD NOT be set as an `webengine` as the required information is already available in instrumentation library and setting this into `webengine` would duplicate the information. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/rpc/README.md b/docs/rpc/README.md index f028fd910a..685e73c9b3 100644 --- a/docs/rpc/README.md +++ b/docs/rpc/README.md @@ -27,4 +27,4 @@ Specifications defined by maintainers of RPC systems: * [gRPC](https://github.com/grpc/proposal/blob/master/A66-otel-stats.md): Semantic Conventions for *gRPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index 8cebaabebf..c0b17cbffc 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -53,6 +53,6 @@ Below is a table of attributes that SHOULD be included on client and server Conn ## Connect RPC Status -If `rpc.connect_rpc.error_code` is set, [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be set to `Error` and left unset in all other cases. +If `rpc.connect_rpc.error_code` is set, [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#set-status) MUST be set to `Error` and left unset in all other cases. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 32ce3d5f7a..08b556c080 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -53,10 +53,10 @@ Below is a table of attributes that SHOULD be included on client and server gRPC ## gRPC Status The table below describes when -the [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#set-status) MUST be set +the [Span Status](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#set-status) MUST be set to `Error` or remain unset depending on the [gRPC status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) -and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/trace/api.md#spankind). +and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#spankind). | gRPC Status Code | `SpanKind.SERVER` Span Status | `SpanKind.CLIENT` Span Status | |---|---|---| @@ -78,4 +78,4 @@ and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/tr | DATA_LOSS | `Error` | `Error` | | UNAUTHENTICATED | unset | `Error` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index e0978e3e06..2fd56eabe1 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -26,4 +26,4 @@ described on this page. **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 4c8e433fff..7c2c5fbe32 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -292,5 +292,5 @@ Specifications defined by maintainers of RPC systems: * [gRPC](https://github.com/grpc/proposal/blob/master/A66-otel-stats.md): Semantic Conventions for *gRPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index b91d7cbd21..20f1d09808 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -225,4 +225,4 @@ More specific Semantic Conventions are defined for the following RPC technologie * [gRPC](grpc.md): Semantic Conventions for *gRPC*. * [JSON-RPC](json-rpc.md): Semantic Conventions for *JSON-RPC*. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/runtime/README.md b/docs/runtime/README.md index 8b8b2ebb1b..9a7fcaf3ad 100644 --- a/docs/runtime/README.md +++ b/docs/runtime/README.md @@ -54,4 +54,4 @@ semantic conventions when instrumenting runtime environments. [`process.runtime`](/docs/resource/process.md#process-runtimes) resource attributes SHOULD be included on runtime metric events as appropriate. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 8128f8371c..7c658f95f8 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -166,7 +166,7 @@ This metric is obtained by subscribing to [`GarbageCollectionNotificationInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html) events provided by [`GarbageCollectorMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/GarbageCollectorMXBean.html). The duration value is obtained from [`GcInfo`](https://docs.oracle.com/javase/8/docs/jre/api/management/extension/com/sun/management/GcInfo.html#getDuration--) This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.01, 0.1, 1, 10 ]`. @@ -454,6 +454,6 @@ This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricOptIn]: /docs/general/metric-requirement-level.md#opt-in [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/system/README.md b/docs/system/README.md index a3422a342f..9b83a84a0e 100644 --- a/docs/system/README.md +++ b/docs/system/README.md @@ -18,4 +18,4 @@ System semantic conventions are defined for the following metrics: * [Process](process-metrics.md): For standard process metrics. * [Runtime Environment](/docs/runtime/README.md#metrics): For runtime environment metrics. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md index 4879ff95f0..7691f286a9 100644 --- a/docs/system/container-metrics.md +++ b/docs/system/container-metrics.md @@ -102,4 +102,4 @@ This metric is [opt-in][MetricOptIn]. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md -[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/metric-requirement-level.md#opt-in +[MetricOptIn]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/metric-requirement-level.md#opt-in diff --git a/docs/system/hardware-metrics.md b/docs/system/hardware-metrics.md index f109d5f240..9773606d91 100644 --- a/docs/system/hardware-metrics.md +++ b/docs/system/hardware-metrics.md @@ -399,4 +399,4 @@ Additional **Recommended** attributes: | ----------------- | ---------------------- | ---------- | | `sensor_location` | Location of the sensor | `PS0 V3_3` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index 6c28dde6a8..e91052222e 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -237,5 +237,5 @@ This metric is [recommended][MetricRecommended]. | `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index af298da177..ca1fddf56d 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -794,7 +794,7 @@ An instrument for load average over 1 minute on Linux could be named `system.linux.cpu.load_1m`, reusing the `cpu` name proposed above and having an `{os}` prefix to split this metric across OSes. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended [MetricOptIn]: /docs/general/metric-requirement-level.md#opt-in diff --git a/docs/url/README.md b/docs/url/README.md index 61c2398793..7618e189ae 100644 --- a/docs/url/README.md +++ b/docs/url/README.md @@ -15,4 +15,4 @@ URL semantic conventions are defined for the following: * [URL](url.md): For describing URL and its components. -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/url/url.md b/docs/url/url.md index 28db25cab4..a33c8f046b 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -48,4 +48,4 @@ Instrumentations that are aware of specific sensitive query string parameters MU _Note: Applications and telemetry consumers should scrub sensitive information from URL attributes on collected telemetry. In systems unable to identify sensitive information, certain attribute values may be redacted entirely._ -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/internal/tools/update_specification_version.sh b/internal/tools/update_specification_version.sh index 765c6c6f88..aef6f5f84e 100755 --- a/internal/tools/update_specification_version.sh +++ b/internal/tools/update_specification_version.sh @@ -6,9 +6,9 @@ # Set this to the version number you want to CHANGE in URLs in the repository. -PREVIOUS_SPECIFICATION_VERSION="v1.22.0" +PREVIOUS_SPECIFICATION_VERSION="v1.26.0" # Set this to the version number you want to KEEP in URLs in the repository. -LATEST_SPECIFICATION_VERSION="v1.26.0" +LATEST_SPECIFICATION_VERSION="v1.31.0" # The specific pattern we look for when replacing URLs SPECIFICATION_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/tree/" SPECIFICATION_BLOB_URL_PREFIX="https://github.com/open-telemetry/opentelemetry-specification/blob/" diff --git a/model/logs/events.yaml b/model/logs/events.yaml index a1ecf5f538..1576901054 100644 --- a/model/logs/events.yaml +++ b/model/logs/events.yaml @@ -12,7 +12,7 @@ groups: brief: > Identifies the class / type of event. note: > - Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/common/attribute-naming.md). + Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. diff --git a/schema-next.yaml b/schema-next.yaml index b6e3a405d9..594dff735d 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,8 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + + 1.25.0: spans: changes: # https://github.com/open-telemetry/semantic-conventions/pull/798 diff --git a/schemas/1.25.0 b/schemas/1.25.0 new file mode 100644 index 0000000000..774c245622 --- /dev/null +++ b/schemas/1.25.0 @@ -0,0 +1,360 @@ +file_format: 1.1.0 +schema_url: https://opentelemetry.io/schemas/1.25.0 +versions: + 1.25.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/798 + - rename_attributes: + attribute_map: + messaging.kafka.destination.partition: messaging.destination.partition.id + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/484 + - rename_attributes: + attribute_map: + system.processes.status: system.process.status + apply_to_metrics: + - system.processes.count + - rename_metrics: + system.processes.count: system.process.count + system.processes.created: system.process.created + # https://github.com/open-telemetry/semantic-conventions/pull/625 + - rename_attributes: + attribute_map: + container.labels: container.label + k8s.pod.labels: k8s.pod.label + # https://github.com/open-telemetry/semantic-conventions/pull/330 + - rename_metrics: + process.threads: process.thread.count + process.open_file_descriptors: process.open_file_descriptor.count + - rename_attributes: + attribute_map: + state: process.cpu.state + apply_to_metrics: + - process.cpu.time + - process.cpu.utilization + - rename_attributes: + attribute_map: + direction: disk.io.direction + apply_to_metrics: + - process.disk.io + - rename_attributes: + attribute_map: + type: process.context_switch_type + apply_to_metrics: + - process.context_switches + - rename_attributes: + attribute_map: + direction: network.io.direction + apply_to_metrics: + - process.network.io + - rename_attributes: + attribute_map: + type: process.paging.fault_type + apply_to_metrics: + - process.paging.faults + + 1.24.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/536 + - rename_metrics: + jvm.memory.usage: jvm.memory.used + jvm.memory.usage_after_last_gc: jvm.memory.used_after_last_gc + # https://github.com/open-telemetry/semantic-conventions/pull/530 + - rename_attributes: + attribute_map: + system.network.io.direction: network.io.direction + system.disk.io.direction: disk.io.direction + 1.23.1: + 1.23.0: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + thread.daemon: jvm.thread.daemon + apply_to_metrics: + - jvm.thread.count + 1.22.0: + spans: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/229 + - rename_attributes: + attribute_map: + messaging.message.payload_size_bytes: messaging.message.body.size + # https://github.com/open-telemetry/opentelemetry-specification/pull/374 + - rename_attributes: + attribute_map: + http.resend_count: http.request.resend_count + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/224 + - rename_metrics: + http.client.duration: http.client.request.duration + http.server.duration: http.server.request.duration + # https://github.com/open-telemetry/semantic-conventions/pull/241 + - rename_metrics: + process.runtime.jvm.memory.usage: jvm.memory.usage + process.runtime.jvm.memory.committed: jvm.memory.committed + process.runtime.jvm.memory.limit: jvm.memory.limit + process.runtime.jvm.memory.usage_after_last_gc: jvm.memory.usage_after_last_gc + process.runtime.jvm.gc.duration: jvm.gc.duration + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.threads.count: jvm.thread.count + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.loaded: jvm.class.loaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + process.runtime.jvm.classes.unloaded: jvm.class.unloaded + # also https://github.com/open-telemetry/semantic-conventions/pull/252 + # and https://github.com/open-telemetry/semantic-conventions/pull/60 + process.runtime.jvm.classes.current_loaded: jvm.class.count + process.runtime.jvm.cpu.time: jvm.cpu.time + process.runtime.jvm.cpu.recent_utilization: jvm.cpu.recent_utilization + process.runtime.jvm.memory.init: jvm.memory.init + process.runtime.jvm.system.cpu.utilization: jvm.system.cpu.utilization + process.runtime.jvm.system.cpu.load_1m: jvm.system.cpu.load_1m + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.usage: jvm.buffer.memory.usage + # https://github.com/open-telemetry/semantic-conventions/pull/253 + process.runtime.jvm.buffer.limit: jvm.buffer.memory.limit + process.runtime.jvm.buffer.count: jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/20 + - rename_attributes: + attribute_map: + type: jvm.memory.type + pool: jvm.memory.pool.name + apply_to_metrics: + - jvm.memory.usage + - jvm.memory.committed + - jvm.memory.limit + - jvm.memory.usage_after_last_gc + - jvm.memory.init + - rename_attributes: + attribute_map: + name: jvm.gc.name + action: jvm.gc.action + apply_to_metrics: + - jvm.gc.duration + - rename_attributes: + attribute_map: + daemon: thread.daemon + apply_to_metrics: + - jvm.threads.count + - rename_attributes: + attribute_map: + pool: jvm.buffer.pool.name + apply_to_metrics: + - jvm.buffer.memory.usage + - jvm.buffer.memory.limit + - jvm.buffer.count + # https://github.com/open-telemetry/semantic-conventions/pull/89 + - rename_attributes: + attribute_map: + state: system.cpu.state + cpu: system.cpu.logical_number + apply_to_metrics: + - system.cpu.time + - system.cpu.utilization + - rename_attributes: + attribute_map: + state: system.memory.state + apply_to_metrics: + - system.memory.usage + - system.memory.utilization + - rename_attributes: + attribute_map: + state: system.paging.state + apply_to_metrics: + - system.paging.usage + - system.paging.utilization + - rename_attributes: + attribute_map: + type: system.paging.type + direction: system.paging.direction + apply_to_metrics: + - system.paging.faults + - system.paging.operations + - rename_attributes: + attribute_map: + device: system.device + direction: system.disk.direction + apply_to_metrics: + - system.disk.io + - system.disk.operations + - system.disk.io_time + - system.disk.operation_time + - system.disk.merged + - rename_attributes: + attribute_map: + device: system.device + state: system.filesystem.state + type: system.filesystem.type + mode: system.filesystem.mode + mountpoint: system.filesystem.mountpoint + apply_to_metrics: + - system.filesystem.usage + - system.filesystem.utilization + - rename_attributes: + attribute_map: + device: system.device + direction: system.network.direction + protocol: network.protocol + state: system.network.state + apply_to_metrics: + - system.network.dropped + - system.network.packets + - system.network.errors + - system.network.io + - system.network.connections + - rename_attributes: + attribute_map: + status: system.processes.status + apply_to_metrics: + - system.processes.count + # https://github.com/open-telemetry/semantic-conventions/pull/247 + - rename_metrics: + http.server.request.size: http.server.request.body.size + http.server.response.size: http.server.response.body.size + resources: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/178 + - rename_attributes: + attribute_map: + telemetry.auto.version: telemetry.distro.version + 1.21.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3336 + - rename_attributes: + attribute_map: + messaging.kafka.client_id: messaging.client_id + messaging.rocketmq.client_id: messaging.client_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3402 + - rename_attributes: + attribute_map: + # net.peer.(name|port) attributes were usually populated on client side + # so they should be usually translated to server.(address|port) + # net.host.* attributes were only populated on server side + net.host.name: server.address + net.host.port: server.port + # was only populated on client side + net.sock.peer.name: server.socket.domain + # net.sock.peer.(addr|port) mapping is not possible + # since they applied to both client and server side + # were only populated on server side + net.sock.host.addr: server.socket.address + net.sock.host.port: server.socket.port + http.client_ip: client.address + # https://github.com/open-telemetry/opentelemetry-specification/pull/3426 + - rename_attributes: + attribute_map: + net.protocol.name: network.protocol.name + net.protocol.version: network.protocol.version + net.host.connection.type: network.connection.type + net.host.connection.subtype: network.connection.subtype + net.host.carrier.name: network.carrier.name + net.host.carrier.mcc: network.carrier.mcc + net.host.carrier.mnc: network.carrier.mnc + net.host.carrier.icc: network.carrier.icc + # https://github.com/open-telemetry/opentelemetry-specification/pull/3355 + - rename_attributes: + attribute_map: + http.method: http.request.method + http.status_code: http.response.status_code + http.scheme: url.scheme + http.url: url.full + http.request_content_length: http.request.body.size + http.response_content_length: http.response.body.size + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/53 + - rename_metrics: + process.runtime.jvm.cpu.utilization: process.runtime.jvm.cpu.recent_utilization + 1.20.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3272 + - rename_attributes: + attribute_map: + net.app.protocol.name: net.protocol.name + net.app.protocol.version: net.protocol.version + 1.19.0: + spans: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3209 + - rename_attributes: + attribute_map: + faas.execution: faas.invocation_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3188 + - rename_attributes: + attribute_map: + faas.id: cloud.resource_id + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + http.user_agent: user_agent.original + resources: + changes: + # https://github.com/open-telemetry/opentelemetry-specification/pull/3190 + - rename_attributes: + attribute_map: + browser.user_agent: user_agent.original + 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: From eb7495599e3e01243092ca72262664ba532416e8 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 4 Apr 2024 12:20:42 -0700 Subject: [PATCH 418/482] Add `messaging.destination.partition.id` to metric attributes (#814) --- .chloggen/814.yaml | 4 ++++ docs/messaging/messaging-metrics.md | 1 + model/messaging-common.yaml | 1 + 3 files changed, 6 insertions(+) create mode 100644 .chloggen/814.yaml diff --git a/.chloggen/814.yaml b/.chloggen/814.yaml new file mode 100644 index 0000000000..10dc2529f6 --- /dev/null +++ b/.chloggen/814.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: messaging +note: Adds `messaging.destination.partition.id`` to the messaging attributes +issues: [ 814 ] diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index a49243c921..a92f357914 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -37,6 +37,7 @@ All messaging metrics share the same set of attributes: | [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | `Conditionally Required` if available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. diff --git a/model/messaging-common.yaml b/model/messaging-common.yaml index 35d6a8eefb..4728e516fa 100644 --- a/model/messaging-common.yaml +++ b/model/messaging-common.yaml @@ -6,6 +6,7 @@ groups: attributes: - ref: messaging.system requirement_level: required + - ref: messaging.destination.partition.id - ref: error.type examples: ['amqp:decode-error', 'KAFKA_STORAGE_ERROR', 'channel-error'] requirement_level: From 1210132a1b7a368cf428eae1ce67f946a2d89490 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:32:20 +0200 Subject: [PATCH 419/482] [chore] update hint for running make command (#876) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index dd48bff2ce..a4e32cba18 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -105,4 +105,4 @@ jobs: - name: Components dropdown in issue templates run: | make generate-gh-issue-templates - git diff --exit-code '.github/ISSUE_TEMPLATE' || (echo 'Dropdowns in issue templates is out of date, please run "make generate-gh-issue-templates" and commit the changes in this PR.' && exit 1) + git diff --exit-code '.github/ISSUE_TEMPLATE' || (echo 'Dropdowns in issue templates is out of date, please run "make generate-gh-issue-templates" and commit the changes in this PR. Please note, if you are running it on Mac OS X, please make sure to use GNU version of sed instead of default "sed".' && exit 1) From 98bed07b8ecad48c185dfa0eb3803c7a6776bca7 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 5 Apr 2024 08:53:02 +0200 Subject: [PATCH 420/482] [chore] move graphql to registry (#882) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/graphql.md | 24 +++++++++++++ docs/graphql/graphql-spans.md | 8 ++--- model/registry/graphql.yaml | 36 ++++++++++++++++++++ model/trace/instrumentation/graphql.yml | 37 ++++----------------- 8 files changed, 74 insertions(+), 35 deletions(-) create mode 100644 docs/attributes-registry/graphql.md create mode 100644 model/registry/graphql.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 42b552f8d0..e61bae637c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -41,6 +41,7 @@ body: - area:file - area:gcp-cloud-run - area:gcp-gce + - area:graphql - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index f44b30f260..0ae9a6fb32 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -34,6 +34,7 @@ body: - area:file - area:gcp-cloud-run - area:gcp-gce + - area:graphql - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index e0d54225ca..4eeae1d515 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -43,6 +43,7 @@ body: - area:file - area:gcp-cloud-run - area:gcp-gce + - area:graphql - area:host - area:http - area:k8s diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index e2f068fc5a..13b3fd3777 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -48,6 +48,7 @@ Currently, the following namespaces exist: * [File](file.md) * [Google Cloud Run](gcp-cloud-run.md) * [Google Compute Engine](gcp-gce.md) +* [GraphQl](graphql.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/graphql.md b/docs/attributes-registry/graphql.md new file mode 100644 index 0000000000..4beae15f1d --- /dev/null +++ b/docs/attributes-registry/graphql.md @@ -0,0 +1,24 @@ + + +# GraphQL + +## GraphQL Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The value may be sanitized to exclude sensitive information. + +`graphql.operation.type` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `query` | GraphQL query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mutation` | GraphQL mutation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `subscription` | GraphQL subscription | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/graphql/graphql-spans.md b/docs/graphql/graphql-spans.md index e0d30aaa9b..a92d27275f 100644 --- a/docs/graphql/graphql-spans.md +++ b/docs/graphql/graphql-spans.md @@ -14,12 +14,12 @@ The **span name** MUST be of the format ` `. When `` is not available, `GraphQL Operation` MAY be used as span name. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.document`](../attributes-registry/graphql.md) | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.operation.name`](../attributes-registry/graphql.md) | string | The name of the operation being executed. | `findBookById` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.operation.type`](../attributes-registry/graphql.md) | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value may be sanitized to exclude sensitive information. diff --git a/model/registry/graphql.yaml b/model/registry/graphql.yaml new file mode 100644 index 0000000000..460444d891 --- /dev/null +++ b/model/registry/graphql.yaml @@ -0,0 +1,36 @@ +groups: + - id: registry.graphql + prefix: graphql + type: attribute_group + brief: 'This document defines attributes for GraphQL.' + attributes: + - id: operation.name + brief: "The name of the operation being executed." + type: string + stability: experimental + examples: 'findBookById' + - id: operation.type + brief: "The type of the operation being executed." + stability: experimental + type: + allow_custom_values: false + members: + - id: query + value: "query" + brief: "GraphQL query" + stability: experimental + - id: mutation + value: "mutation" + brief: "GraphQL mutation" + stability: experimental + - id: subscription + value: "subscription" + brief: "GraphQL subscription" + stability: experimental + examples: ['query', 'mutation', 'subscription'] + - id: document + brief: "The GraphQL document being executed." + type: string + stability: experimental + note: The value may be sanitized to exclude sensitive information. + examples: 'query findBookById { bookById(id: ?) { name } }' diff --git a/model/trace/instrumentation/graphql.yml b/model/trace/instrumentation/graphql.yml index 6e311afa69..a14948da0a 100644 --- a/model/trace/instrumentation/graphql.yml +++ b/model/trace/instrumentation/graphql.yml @@ -1,38 +1,13 @@ groups: - id: graphql - prefix: graphql type: span brief: > This document defines semantic conventions to apply when instrumenting the GraphQL implementation. They map GraphQL operations to attributes on a Span. attributes: - - id: operation.name - brief: "The name of the operation being executed." - type: string - stability: experimental - examples: 'findBookById' - - id: operation.type - brief: "The type of the operation being executed." - stability: experimental - type: - allow_custom_values: false - members: - - id: query - value: "query" - brief: "GraphQL query" - stability: experimental - - id: mutation - value: "mutation" - brief: "GraphQL mutation" - stability: experimental - - id: subscription - value: "subscription" - brief: "GraphQL subscription" - stability: experimental - examples: ['query', 'mutation', 'subscription'] - - id: document - brief: "The GraphQL document being executed." - type: string - stability: experimental - note: The value may be sanitized to exclude sensitive information. - examples: 'query findBookById { bookById(id: ?) { name } }' + - ref: graphql.operation.name + requirement_level: recommended + - ref: graphql.operation.type + requirement_level: recommended + - ref: graphql.document + requirement_level: recommended From 48892b80801803dbb332df8c16a4b82da76c6ad3 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:48:58 +0200 Subject: [PATCH 421/482] [chore] Move heroku attributes to the registry (#871) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/heroku.md | 14 ++++++++++++ docs/resource/cloud-provider/heroku.md | 6 ++--- model/registry/heroku.yaml | 25 +++++++++++++++++++++ model/resource/cloud_provider/heroku.yaml | 22 +++--------------- 8 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 docs/attributes-registry/heroku.md create mode 100644 model/registry/heroku.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index e61bae637c..0ffde5f0f0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -42,6 +42,7 @@ body: - area:gcp-cloud-run - area:gcp-gce - area:graphql + - area:heroku - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 0ae9a6fb32..23a3ecec3e 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -35,6 +35,7 @@ body: - area:gcp-cloud-run - area:gcp-gce - area:graphql + - area:heroku - area:host - area:http - area:k8s diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 4eeae1d515..b227df92e9 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -44,6 +44,7 @@ body: - area:gcp-cloud-run - area:gcp-gce - area:graphql + - area:heroku - area:host - area:http - area:k8s diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 13b3fd3777..fd1bc0cb60 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -49,6 +49,7 @@ Currently, the following namespaces exist: * [Google Cloud Run](gcp-cloud-run.md) * [Google Compute Engine](gcp-gce.md) * [GraphQl](graphql.md) +* [Heroku](heroku.md) * [Host](host.md) * [HTTP](http.md) * [K8s](k8s.md) diff --git a/docs/attributes-registry/heroku.md b/docs/attributes-registry/heroku.md new file mode 100644 index 0000000000..b84139462e --- /dev/null +++ b/docs/attributes-registry/heroku.md @@ -0,0 +1,14 @@ + + +# Heroku + +## Heroku Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index b16a2b620d..6776486eab 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.app.id`](../../attributes-registry/heroku.md) | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.release.commit`](../../attributes-registry/heroku.md) | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.release.creation_timestamp`](../../attributes-registry/heroku.md) | string | Time and date the release was created | `2022-10-23T18:00:42Z` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **Mapping:** diff --git a/model/registry/heroku.yaml b/model/registry/heroku.yaml new file mode 100644 index 0000000000..d9fe99a731 --- /dev/null +++ b/model/registry/heroku.yaml @@ -0,0 +1,25 @@ +groups: + - id: registry.heroku + prefix: heroku + type: attribute_group + brief: > + This document defines attributes for the Android platform on which the Android application is running. + attributes: + - id: release.creation_timestamp + type: string + stability: experimental + brief: > + Time and date the release was created + examples: [ '2022-10-23T18:00:42Z' ] + - id: release.commit + type: string + stability: experimental + brief: > + Commit hash for the current release + examples: [ 'e6134959463efd8966b20e75b913cafe3f5ec' ] + - id: app.id + type: string + stability: experimental + brief: > + Unique identifier for the application + examples: [ '2daa2797-e42b-4624-9322-ec3f968df4da' ] diff --git a/model/resource/cloud_provider/heroku.yaml b/model/resource/cloud_provider/heroku.yaml index c8f7e34143..f609f473e4 100644 --- a/model/resource/cloud_provider/heroku.yaml +++ b/model/resource/cloud_provider/heroku.yaml @@ -1,28 +1,12 @@ groups: - id: heroku - prefix: heroku type: resource brief: > Heroku dyno metadata attributes: - - id: release.creation_timestamp - type: string - stability: experimental - brief: > - Time and date the release was created - examples: [ '2022-10-23T18:00:42Z' ] + - ref: heroku.release.creation_timestamp requirement_level: opt_in - - id: release.commit - type: string - stability: experimental - brief: > - Commit hash for the current release - examples: [ 'e6134959463efd8966b20e75b913cafe3f5ec' ] + - ref: heroku.release.commit requirement_level: opt_in - - id: app.id - type: string - stability: experimental - brief: > - Unique identifier for the application - examples: [ '2daa2797-e42b-4624-9322-ec3f968df4da' ] + - ref: heroku.app.id requirement_level: opt_in From 8c4d6986e0c452f0c73a1d2c5f47e864904cb89b Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:25:19 +0200 Subject: [PATCH 422/482] [chore] Move mobile events to the registry (#872) Co-authored-by: Alexander Wert --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/android.md | 25 ++++++++ docs/attributes-registry/ios.md | 30 +++++++++ docs/mobile/events.md | 8 +-- model/logs/mobile-events.yaml | 69 +-------------------- model/registry/android.yaml | 34 ++++++++++ model/registry/ios.yaml | 44 +++++++++++++ 10 files changed, 143 insertions(+), 71 deletions(-) create mode 100644 docs/attributes-registry/ios.md create mode 100644 model/registry/ios.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 0ffde5f0f0..ee13d72fe0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -45,6 +45,7 @@ body: - area:heroku - area:host - area:http + - area:ios - area:k8s - area:messaging - area:network diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 23a3ecec3e..79948d15f1 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -38,6 +38,7 @@ body: - area:heroku - area:host - area:http + - area:ios - area:k8s - area:messaging - area:network diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index b227df92e9..710a297c9f 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -47,6 +47,7 @@ body: - area:heroku - area:host - area:http + - area:ios - area:k8s - area:messaging - area:network diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index fd1bc0cb60..7082033cbd 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -52,6 +52,7 @@ Currently, the following namespaces exist: * [Heroku](heroku.md) * [Host](host.md) * [HTTP](http.md) +* [iOS](ios.md) * [K8s](k8s.md) * [Network](network.md) * [OCI](oci.md) diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index 65072ef1aa..156f661dc5 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -1,8 +1,33 @@ # Android + + +- [Android Attributes](#android-attributes) +- [Android Lifecycle Event Attributes](#android-lifecycle-event-attributes) + + + ## Android Attributes | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Android Lifecycle Event Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. + +`android.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/attributes-registry/ios.md b/docs/attributes-registry/ios.md new file mode 100644 index 0000000000..e35fc82b73 --- /dev/null +++ b/docs/attributes-registry/ios.md @@ -0,0 +1,30 @@ + + +# iOS + + + +- [iOS Lifecycle Event Attributes](#ios-lifecycle-event-attributes) + + + +## iOS Lifecycle Event Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. + +`ios.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/mobile/events.md b/docs/mobile/events.md index dd33a06cdd..204a8020de 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -23,12 +23,12 @@ mobile operating system (e.g. Android, iOS). ### iOS - + The event name MUST be `device.app.lifecycle`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`ios.state`](../attributes-registry/ios.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. @@ -45,12 +45,12 @@ The event name MUST be `device.app.lifecycle`. ### Android - + The event name MUST be `device.app.lifecycle`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`android.state`](../attributes-registry/android.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index 7fee308596..6664bd1edb 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -1,82 +1,17 @@ groups: - id: ios.lifecycle.events type: event - prefix: ios name: device.app.lifecycle brief: > This event represents an occurrence of a lifecycle transition on the iOS platform. attributes: - - id: state - stability: experimental + - ref: ios.state requirement_level: "required" - note: > - The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), - and from which the `OS terminology` column values are derived. - brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. - type: - allow_custom_values: false - members: - - id: active - value: 'active' - brief: > - The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. - stability: experimental - - id: inactive - value: 'inactive' - brief: > - The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. - stability: experimental - - id: background - value: 'background' - brief: > - The app is now in the background. - This value is associated with UIKit notification `applicationDidEnterBackground`. - stability: experimental - - id: foreground - value: 'foreground' - brief: > - The app is now in the foreground. - This value is associated with UIKit notification `applicationWillEnterForeground`. - stability: experimental - - id: terminate - value: 'terminate' - brief: > - The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. - stability: experimental - id: android.lifecycle.events type: event - prefix: android name: device.app.lifecycle brief: > This event represents an occurrence of a lifecycle transition on the Android platform. attributes: - - id: state - stability: experimental + - ref: android.state requirement_level: required - brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. - note: > - The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), - and from which the `OS identifiers` are derived. - type: - allow_custom_values: false - members: - - id: created - value: 'created' - brief: > - Any time before Activity.onResume() or, if the app has no Activity, Context.startService() - has been called in the app for the first time. - stability: experimental - - id: background - value: 'background' - brief: > - Any time after Activity.onPause() or, if the app has no Activity, - Context.stopService() has been called when the app was in the foreground state. - stability: experimental - - id: foreground - value: 'foreground' - brief: > - Any time after Activity.onResume() or, if the app has no Activity, - Context.startService() has been called when the app was in either the created or background states. - stability: experimental diff --git a/model/registry/android.yaml b/model/registry/android.yaml index cfdcac8a46..267ad426b0 100644 --- a/model/registry/android.yaml +++ b/model/registry/android.yaml @@ -13,3 +13,37 @@ groups: (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). examples: ['33', '32'] + - id: registry.android.lifecycle.events + prefix: android + type: attribute_group + brief: > + This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. + attributes: + - id: state + stability: experimental + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + note: > + The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + and from which the `OS identifiers` are derived. + type: + allow_custom_values: false + members: + - id: created + value: 'created' + brief: > + Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + has been called in the app for the first time. + stability: experimental + - id: background + value: 'background' + brief: > + Any time after Activity.onPause() or, if the app has no Activity, + Context.stopService() has been called when the app was in the foreground state. + stability: experimental + - id: foreground + value: 'foreground' + brief: > + Any time after Activity.onResume() or, if the app has no Activity, + Context.startService() has been called when the app was in either the created or background states. + stability: experimental diff --git a/model/registry/ios.yaml b/model/registry/ios.yaml new file mode 100644 index 0000000000..3989b4e8e3 --- /dev/null +++ b/model/registry/ios.yaml @@ -0,0 +1,44 @@ +groups: + - id: registry.ios.lifecycle.events + prefix: ios + type: attribute_group + brief: > + The iOS platform on which the iOS application is running. + attributes: + - id: state + stability: experimental + note: > + The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), + and from which the `OS terminology` column values are derived. + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + type: + allow_custom_values: false + members: + - id: active + value: 'active' + brief: > + The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + stability: experimental + - id: inactive + value: 'inactive' + brief: > + The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + stability: experimental + - id: background + value: 'background' + brief: > + The app is now in the background. + This value is associated with UIKit notification `applicationDidEnterBackground`. + stability: experimental + - id: foreground + value: 'foreground' + brief: > + The app is now in the foreground. + This value is associated with UIKit notification `applicationWillEnterForeground`. + stability: experimental + - id: terminate + value: 'terminate' + brief: > + The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + stability: experimental From 94cf27bd8112dbd5646887bd126f9ea9e71d8511 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:42:59 +0200 Subject: [PATCH 423/482] [chore] Move AWS ECS, EKS and Log attributes to the registry (#848) --- docs/attributes-registry/android.md | 2 +- docs/attributes-registry/aws.md | 46 ++++++++ docs/attributes-registry/ios.md | 2 +- docs/mobile/events.md | 4 +- docs/resource/cloud-provider/aws/ecs.md | 18 ++-- docs/resource/cloud-provider/aws/eks.md | 2 +- docs/resource/cloud-provider/aws/logs.md | 8 +- model/registry/android.yaml | 2 +- model/registry/aws.yaml | 114 ++++++++++++++++++++ model/registry/ios.yaml | 2 +- model/resource/cloud_provider/aws/ecs.yaml | 65 +++-------- model/resource/cloud_provider/aws/eks.yaml | 9 +- model/resource/cloud_provider/aws/logs.yaml | 45 ++------ 13 files changed, 203 insertions(+), 116 deletions(-) diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index 156f661dc5..f2ca703769 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -23,7 +23,7 @@ **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. -`android.state` MUST be one of the following: +`android.state` 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 | Stability | |---|---|---| diff --git a/docs/attributes-registry/aws.md b/docs/attributes-registry/aws.md index 0cc9f4d0d8..b6fa59ac40 100644 --- a/docs/attributes-registry/aws.md +++ b/docs/attributes-registry/aws.md @@ -3,6 +3,9 @@ - [AWS DynamoDB Attributes](#aws-dynamodb-attributes) +- [AWS ECS Attributes](#aws-ecs-attributes) +- [AWS EKS Attributes](#aws-eks-attributes) +- [AWS Logs Attributes](#aws-logs-attributes) @@ -32,4 +35,47 @@ | `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## AWS ECS Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`aws.ecs.launchtype` 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 | Stability | +|---|---|---| +| `ec2` | ec2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fargate` | fargate | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## AWS EKS Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## AWS Logs Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + +**[2]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + +**[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. \ No newline at end of file diff --git a/docs/attributes-registry/ios.md b/docs/attributes-registry/ios.md index e35fc82b73..e8aea69f54 100644 --- a/docs/attributes-registry/ios.md +++ b/docs/attributes-registry/ios.md @@ -18,7 +18,7 @@ **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. -`ios.state` MUST be one of the following: +`ios.state` 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 | Stability | |---|---|---| diff --git a/docs/mobile/events.md b/docs/mobile/events.md index 204a8020de..b02760674b 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -32,7 +32,7 @@ The event name MUST be `device.app.lifecycle`. **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. -`ios.state` MUST be one of the following: +`ios.state` 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 | Stability | |---|---|---| @@ -54,7 +54,7 @@ The event name MUST be `device.app.lifecycle`. **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. -`android.state` MUST be one of the following: +`android.state` 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 | Stability | |---|---|---| diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index a682c75c22..c621699190 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -6,18 +6,18 @@ **Description:** Resources used by AWS Elastic Container Service (ECS). - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Conditionally Required` If and only if `task.arn` is populated. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.id`](../../../attributes-registry/aws.md) | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Conditionally Required` If and only if `task.arn` is populated. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.cluster.arn`](../../../attributes-registry/aws.md) | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.container.arn`](../../../attributes-registry/aws.md) | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.launchtype`](../../../attributes-registry/aws.md) | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.arn`](../../../attributes-registry/aws.md) | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.family`](../../../attributes-registry/aws.md) | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.revision`](../../../attributes-registry/aws.md) | string | The revision for the task definition used to create the ECS task. | `8`; `26` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`aws.ecs.launchtype` MUST be one of the following: +`aws.ecs.launchtype` 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 | Stability | |---|---|---| diff --git a/docs/resource/cloud-provider/aws/eks.md b/docs/resource/cloud-provider/aws/eks.md index 1d6531289d..3eb55321da 100644 --- a/docs/resource/cloud-provider/aws/eks.md +++ b/docs/resource/cloud-provider/aws/eks.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.eks.cluster.arn`](../../../attributes-registry/aws.md) | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index d35c994d83..9fc43b4831 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -9,10 +9,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.group.arns`](../../../attributes-registry/aws.md) | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.group.names`](../../../attributes-registry/aws.md) | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.stream.arns`](../../../attributes-registry/aws.md) | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.stream.names`](../../../attributes-registry/aws.md) | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). diff --git a/model/registry/android.yaml b/model/registry/android.yaml index 267ad426b0..bddc74a09a 100644 --- a/model/registry/android.yaml +++ b/model/registry/android.yaml @@ -27,7 +27,7 @@ groups: The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. type: - allow_custom_values: false + allow_custom_values: true members: - id: created value: 'created' diff --git a/model/registry/aws.yaml b/model/registry/aws.yaml index c0c0686089..149d82ad7f 100644 --- a/model/registry/aws.yaml +++ b/model/registry/aws.yaml @@ -240,3 +240,117 @@ groups: "WriteCapacityUnits": number } }' + - id: registry.aws.ecs + prefix: aws.ecs + type: attribute_group + brief: > + This document defines attributes for AWS Elastic Container Service (ECS). + attributes: + - id: container.arn + type: string + stability: experimental + brief: > + The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). + examples: ['arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'] + - id: cluster.arn + type: string + stability: experimental + brief: > + The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). + examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] + - id: launchtype + type: + allow_custom_values: true + members: + - id: ec2 + value: "ec2" + stability: experimental + - id: fargate + value: "fargate" + stability: experimental + stability: experimental + brief: > + The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. + - id: task.arn + type: string + stability: experimental + brief: > + The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). + examples: [ + 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b', + 'arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' + ] + - id: task.family + type: string + stability: experimental + brief: > + The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. + examples: ['opentelemetry-family'] + - id: task.id + type: string + stability: experimental + brief: > + The ID of a running ECS task. The ID MUST be extracted from `task.arn`. + requirement_level: + conditionally_required: If and only if `task.arn` is populated. + examples: [ '10838bed-421f-43ef-870a-f43feacbbb5b', '23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' ] + - id: task.revision + type: string + stability: experimental + brief: > + The revision for the task definition used to create the ECS task. + examples: ["8", "26"] + - id: registry.aws.eks + prefix: aws.eks + type: resource + brief: > + This document defines attributes for AWS Elastic Kubernetes Service (EKS). + attributes: + - id: cluster.arn + type: string + stability: experimental + brief: > + The ARN of an EKS cluster. + examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] + - id: registry.aws.log + prefix: aws.log + type: attribute_group + brief: > + This document defines attributes for AWS Logs. + attributes: + - id: group.names + type: string[] + stability: experimental + brief: > + The name(s) of the AWS log group(s) an application is writing to. + examples: ['/aws/lambda/my-function', 'opentelemetry-service'] + note: > + Multiple log groups must be supported for cases like multi-container applications, + where a single application has sidecar containers, and each write to their own log + group. + - id: group.arns + type: string[] + stability: experimental + brief: > + The Amazon Resource Name(s) (ARN) of the AWS log group(s). + examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'] + note: > + See the + [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + - id: stream.names + type: string[] + stability: experimental + brief: > + The name(s) of the AWS log stream(s) an application is writing to. + examples: ['logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] + - id: stream.arns + type: string[] + stability: experimental + brief: > + The ARN(s) of the AWS log stream(s). + examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] + note: > + See the + [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + One log group can contain several log streams, so these ARNs necessarily identify both a log + group and a log stream. diff --git a/model/registry/ios.yaml b/model/registry/ios.yaml index 3989b4e8e3..1bfe30f325 100644 --- a/model/registry/ios.yaml +++ b/model/registry/ios.yaml @@ -13,7 +13,7 @@ groups: brief: > This attribute represents the state the application has transitioned into at the occurrence of the event. type: - allow_custom_values: false + allow_custom_values: true members: - id: active value: 'active' diff --git a/model/resource/cloud_provider/aws/ecs.yaml b/model/resource/cloud_provider/aws/ecs.yaml index af24faf1ca..53c998c575 100644 --- a/model/resource/cloud_provider/aws/ecs.yaml +++ b/model/resource/cloud_provider/aws/ecs.yaml @@ -1,61 +1,22 @@ groups: - id: aws.ecs - prefix: aws.ecs type: resource brief: > Resources used by AWS Elastic Container Service (ECS). attributes: - - id: container.arn - type: string - stability: experimental - brief: > - The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). - examples: ['arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'] - - id: cluster.arn - type: string - stability: experimental - brief: > - The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). - examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] - - id: launchtype - type: - allow_custom_values: false - members: - - id: ec2 - value: "ec2" - stability: experimental - - id: fargate - value: "fargate" - stability: experimental - stability: experimental - brief: > - The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. - - id: task.arn - type: string - stability: experimental - brief: > - The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). - examples: [ - 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b', - 'arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' - ] - - id: task.family - type: string - stability: experimental - brief: > - The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. - examples: ['opentelemetry-family'] - - id: task.id - type: string - stability: experimental - brief: > - The ID of a running ECS task. The ID MUST be extracted from `task.arn`. + - ref: aws.ecs.container.arn + requirement_level: recommended + - ref: aws.ecs.cluster.arn + requirement_level: recommended + - ref: aws.ecs.launchtype + requirement_level: recommended + - ref: aws.ecs.task.arn + requirement_level: recommended + - ref: aws.ecs.task.family + requirement_level: recommended + - ref: aws.ecs.task.id requirement_level: conditionally_required: If and only if `task.arn` is populated. examples: [ '10838bed-421f-43ef-870a-f43feacbbb5b', '23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd' ] - - id: task.revision - type: string - stability: experimental - brief: > - The revision for the task definition used to create the ECS task. - examples: ["8", "26"] + - ref: aws.ecs.task.revision + requirement_level: recommended diff --git a/model/resource/cloud_provider/aws/eks.yaml b/model/resource/cloud_provider/aws/eks.yaml index 8eafc481aa..a25713cdfd 100644 --- a/model/resource/cloud_provider/aws/eks.yaml +++ b/model/resource/cloud_provider/aws/eks.yaml @@ -1,13 +1,8 @@ groups: - id: aws.eks - prefix: aws.eks type: resource brief: > Resources used by AWS Elastic Kubernetes Service (EKS). attributes: - - id: cluster.arn - type: string - stability: experimental - brief: > - The ARN of an EKS cluster. - examples: ['arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'] + - ref: aws.eks.cluster.arn + requirement_level: recommended diff --git a/model/resource/cloud_provider/aws/logs.yaml b/model/resource/cloud_provider/aws/logs.yaml index 35889e137c..ffd5feb3d4 100644 --- a/model/resource/cloud_provider/aws/logs.yaml +++ b/model/resource/cloud_provider/aws/logs.yaml @@ -1,43 +1,14 @@ groups: - id: aws.log - prefix: aws.log type: resource brief: > Resources specific to Amazon Web Services. attributes: - - id: group.names - type: string[] - stability: experimental - brief: > - The name(s) of the AWS log group(s) an application is writing to. - examples: ['/aws/lambda/my-function', 'opentelemetry-service'] - note: > - Multiple log groups must be supported for cases like multi-container applications, - where a single application has sidecar containers, and each write to their own log - group. - - id: group.arns - type: string[] - stability: experimental - brief: > - The Amazon Resource Name(s) (ARN) of the AWS log group(s). - examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'] - note: > - See the - [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). - - id: stream.names - type: string[] - stability: experimental - brief: > - The name(s) of the AWS log stream(s) an application is writing to. - examples: ['logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] - - id: stream.arns - type: string[] - stability: experimental - brief: > - The ARN(s) of the AWS log stream(s). - examples: ['arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'] - note: > - See the - [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). - One log group can contain several log streams, so these ARNs necessarily identify both a log - group and a log stream. + - ref: aws.log.group.names + requirement_level: recommended + - ref: aws.log.group.arns + requirement_level: recommended + - ref: aws.log.stream.names + requirement_level: recommended + - ref: aws.log.stream.arns + requirement_level: recommended From 1f3c27ea45d55b1193e605fbb659d53c4ea34ecb Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:46:51 +0200 Subject: [PATCH 424/482] [chore] Combine GCP attributes (#888) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 3 +-- .github/ISSUE_TEMPLATE/change_proposal.yaml | 3 +-- .github/ISSUE_TEMPLATE/new-conventions.yaml | 3 +-- docs/attributes-registry/README.md | 3 +-- docs/attributes-registry/gcp-cloud-run.md | 9 ------- docs/attributes-registry/gcp-gce.md | 9 ------- docs/attributes-registry/gcp.md | 24 ++++++++++++++++++ docs/resource/cloud-provider/gcp/cloud-run.md | 4 +-- docs/resource/cloud-provider/gcp/gce.md | 4 +-- model/registry/gcp-cloud-run.yaml | 25 ------------------- model/registry/{gcp-gce.yaml => gcp.yaml} | 24 ++++++++++++++++++ 11 files changed, 56 insertions(+), 55 deletions(-) delete mode 100644 docs/attributes-registry/gcp-cloud-run.md delete mode 100644 docs/attributes-registry/gcp-gce.md create mode 100644 docs/attributes-registry/gcp.md delete mode 100644 model/registry/gcp-cloud-run.yaml rename model/registry/{gcp-gce.yaml => gcp.yaml} (53%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index ee13d72fe0..ea514863f9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -39,8 +39,7 @@ body: - area:faas - area:feature-flag - area:file - - area:gcp-cloud-run - - area:gcp-gce + - area:gcp - area:graphql - area:heroku - area:host diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 79948d15f1..0b85490497 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -32,8 +32,7 @@ body: - area:faas - area:feature-flag - area:file - - area:gcp-cloud-run - - area:gcp-gce + - area:gcp - area:graphql - area:heroku - area:host diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 710a297c9f..3772bd1134 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -41,8 +41,7 @@ body: - area:faas - area:feature-flag - area:file - - area:gcp-cloud-run - - area:gcp-gce + - area:gcp - area:graphql - area:heroku - area:host diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 7082033cbd..9886a80627 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -46,8 +46,7 @@ Currently, the following namespaces exist: * [FaaS](faas.md) * [Feature Flag](feature-flag.md) * [File](file.md) -* [Google Cloud Run](gcp-cloud-run.md) -* [Google Compute Engine](gcp-gce.md) +* [Google Cloud Platform (GCP)](gcp.md) * [GraphQl](graphql.md) * [Heroku](heroku.md) * [Host](host.md) diff --git a/docs/attributes-registry/gcp-cloud-run.md b/docs/attributes-registry/gcp-cloud-run.md deleted file mode 100644 index fc754e943a..0000000000 --- a/docs/attributes-registry/gcp-cloud-run.md +++ /dev/null @@ -1,9 +0,0 @@ -# Google Cloud Run - -## Google Cloud Run Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/gcp-gce.md b/docs/attributes-registry/gcp-gce.md deleted file mode 100644 index d6735be23e..0000000000 --- a/docs/attributes-registry/gcp-gce.md +++ /dev/null @@ -1,9 +0,0 @@ -# Google Compute Engine - -## Google Compute Engine Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/gcp.md b/docs/attributes-registry/gcp.md new file mode 100644 index 0000000000..ea0a4a200e --- /dev/null +++ b/docs/attributes-registry/gcp.md @@ -0,0 +1,24 @@ +# Google Cloud Platform + + + +- [Google Compute Engine Attributes](#google-compute-engine-attributes) +- [Google Cloud Run Attributes](#google-cloud-run-attributes) + + + +## Google Compute Engine Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Google Cloud Run Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index 161d79237a..abea40486f 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -11,8 +11,8 @@ These conventions are recommended for resources running on Cloud Run. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp-cloud-run.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp-cloud-run.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/gce.md b/docs/resource/cloud-provider/gcp/gce.md index 347388be66..377d74679b 100644 --- a/docs/resource/cloud-provider/gcp/gce.md +++ b/docs/resource/cloud-provider/gcp/gce.md @@ -7,6 +7,6 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp-gce.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gcp.gce.instance.name`](../../../attributes-registry/gcp-gce.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.gce.instance.name`](../../../attributes-registry/gcp.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/registry/gcp-cloud-run.yaml b/model/registry/gcp-cloud-run.yaml deleted file mode 100644 index 11b9481feb..0000000000 --- a/model/registry/gcp-cloud-run.yaml +++ /dev/null @@ -1,25 +0,0 @@ -groups: - - id: registry.gcp.cloud_run - prefix: gcp.cloud_run - type: attribute_group - brief: > - This document defines attributes for Google Cloud Run. - attributes: - - id: job.execution - type: string - stability: experimental - brief: > - The name of the Cloud Run - [execution](https://cloud.google.com/run/docs/managing/job-executions) - being run for the Job, as set by the - [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) - environment variable. - examples: ['job-name-xxxx', 'sample-job-mdw84'] - - id: job.task_index - type: int - stability: experimental - brief: > - The index for a task within an execution as provided by the - [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) - environment variable. - examples: [0, 1] diff --git a/model/registry/gcp-gce.yaml b/model/registry/gcp.yaml similarity index 53% rename from model/registry/gcp-gce.yaml rename to model/registry/gcp.yaml index 1ca30ee72d..3b00f7040e 100644 --- a/model/registry/gcp-gce.yaml +++ b/model/registry/gcp.yaml @@ -1,4 +1,28 @@ groups: + - id: registry.gcp.cloud_run + prefix: gcp.cloud_run + type: attribute_group + brief: > + This document defines attributes for Google Cloud Run. + attributes: + - id: job.execution + type: string + stability: experimental + brief: > + The name of the Cloud Run + [execution](https://cloud.google.com/run/docs/managing/job-executions) + being run for the Job, as set by the + [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + environment variable. + examples: ['job-name-xxxx', 'sample-job-mdw84'] + - id: job.task_index + type: int + stability: experimental + brief: > + The index for a task within an execution as provided by the + [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) + environment variable. + examples: [0, 1] - id: registry.gcp.gce prefix: gcp.gce type: attribute_group From a307d19c867f6e8095515b7b21628397e024815e Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:56:30 +0200 Subject: [PATCH 425/482] Move otel.scope attributes to registry (#889) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/otel.md | 13 ++++++++ model/registry/deprecated/otel.yaml | 19 ++++++++++++ model/registry/otel.yaml | 16 ++++++++++ model/scope/exporter/exporter.yaml | 33 +++------------------ 8 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 docs/attributes-registry/otel.md create mode 100644 model/registry/deprecated/otel.yaml create mode 100644 model/registry/otel.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index ea514863f9..6abd8a9103 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -50,6 +50,7 @@ body: - area:network - area:oci - area:os + - area:otel - area:peer - area:process - area:rpc diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 0b85490497..c064231a77 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -43,6 +43,7 @@ body: - area:network - area:oci - area:os + - area:otel - area:peer - area:process - area:rpc diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 3772bd1134..0b75deac83 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -52,6 +52,7 @@ body: - area:network - area:oci - area:os + - area:otel - area:peer - area:process - area:rpc diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 9886a80627..4d87791234 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -55,6 +55,7 @@ Currently, the following namespaces exist: * [K8s](k8s.md) * [Network](network.md) * [OCI](oci.md) +* [OpenTelemetry](otel.md) * [OS](os.md) * [Peer](peer.md) * [Process](process.md) diff --git a/docs/attributes-registry/otel.md b/docs/attributes-registry/otel.md new file mode 100644 index 0000000000..730ef8a14c --- /dev/null +++ b/docs/attributes-registry/otel.md @@ -0,0 +1,13 @@ + + +# OpenTelemetry + +## Scope Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + diff --git a/model/registry/deprecated/otel.yaml b/model/registry/deprecated/otel.yaml new file mode 100644 index 0000000000..23456367bc --- /dev/null +++ b/model/registry/deprecated/otel.yaml @@ -0,0 +1,19 @@ +groups: + - id: otel.library + prefix: otel.library + type: resource + brief: > + Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + deprecated: use the `otel.scope.name` attribute. + stability: experimental + brief: + examples: ['io.opentelemetry.contrib.mongodb'] + - id: version + type: string + deprecated: use the `otel.scope.version` attribute. + stability: experimental + brief: + examples: ['1.0.0'] diff --git a/model/registry/otel.yaml b/model/registry/otel.yaml new file mode 100644 index 0000000000..1fa7f0da45 --- /dev/null +++ b/model/registry/otel.yaml @@ -0,0 +1,16 @@ +groups: + - id: registry.otel.scope + prefix: otel.scope + type: resource + brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + brief: The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + examples: ['io.opentelemetry.contrib.mongodb'] + stability: stable + - id: version + type: string + brief: The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + examples: ['1.0.0'] + stability: stable diff --git a/model/scope/exporter/exporter.yaml b/model/scope/exporter/exporter.yaml index 41b27571b4..52f47f0b0e 100644 --- a/model/scope/exporter/exporter.yaml +++ b/model/scope/exporter/exporter.yaml @@ -1,34 +1,9 @@ groups: - id: otel.scope - prefix: otel.scope type: resource brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. attributes: - - id: name - type: string - brief: The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). - examples: ['io.opentelemetry.contrib.mongodb'] - stability: stable - - id: version - type: string - brief: The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). - examples: ['1.0.0'] - stability: stable - - id: otel.library - prefix: otel.library - type: resource - brief: > - Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. - attributes: - - id: name - type: string - deprecated: use the `otel.scope.name` attribute. - stability: experimental - brief: - examples: ['io.opentelemetry.contrib.mongodb'] - - id: version - type: string - deprecated: use the `otel.scope.version` attribute. - stability: experimental - brief: - examples: ['1.0.0'] + - ref: otel.scope.name + requirement_level: recommended + - ref: otel.scope.version + requirement_level: recommended From 262271ffb3152b3b2442e376d6833dd3a355ca60 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Fri, 5 Apr 2024 18:30:25 +0200 Subject: [PATCH 426/482] move rpc.message to the registry (#854) Co-authored-by: Liudmila Molkova Co-authored-by: Alexander Wert Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/rpc_registry.yaml | 22 ++++++++++++++ docs/attributes-registry/rpc.md | 21 +++++++++++--- docs/rpc/rpc-spans.md | 14 ++++----- model/registry/deprecated/rpc.yaml | 32 +++++++++++++++++++++ model/registry/rpc.yaml | 24 ++++++++++++++++ model/trace/rpc.yaml | 46 ++++++++++++++---------------- schema-next.yaml | 9 ++++++ 7 files changed, 132 insertions(+), 36 deletions(-) create mode 100755 .chloggen/rpc_registry.yaml create mode 100644 model/registry/deprecated/rpc.yaml diff --git a/.chloggen/rpc_registry.yaml b/.chloggen/rpc_registry.yaml new file mode 100755 index 0000000000..1401a385e6 --- /dev/null +++ b/.chloggen/rpc_registry.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: rpc + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Rename`message.*` attributes under `rpc` to `rpc.message.*`. Deprecate old `message.*` attributes. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [854] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/rpc.md b/docs/attributes-registry/rpc.md index 0c904e3f48..25f7a29087 100644 --- a/docs/attributes-registry/rpc.md +++ b/docs/attributes-registry/rpc.md @@ -20,8 +20,12 @@ RPC attributes are intended to be used in the context of events related to remot | `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [5] | `exampleMethod` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [6] | `myservice.EchoService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.compressed_size` | int | Compressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [5] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.type` | string | Whether this is a received or sent message. | `SENT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -32,9 +36,11 @@ RPC attributes are intended to be used in the context of events related to remot **[4]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. -**[5]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[5]:** This way we guarantee that the values will be consistent between different implementations. -**[6]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[6]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[7]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). `rpc.connect_rpc.error_code` MUST be one of the following: @@ -79,6 +85,13 @@ RPC attributes are intended to be used in the context of events related to remot | `15` | DATA_LOSS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `16` | UNAUTHENTICATED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +`rpc.message.type` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `SENT` | sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `RECEIVED` | received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + `rpc.system` 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 | Stability | diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 20f1d09808..387f5b56b1 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -191,19 +191,19 @@ In the lifetime of an RPC stream, an event for each message sent/received on client and server spans SHOULD be created. In case of unary calls only one sent and one received message will be recorded for both client and server spans. - -The event name MUST be `message`. + +The event name MUST be `rpc.message`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `message.compressed_size` | int | Compressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `message.type` | string | Whether this is a received or sent message. | `SENT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.compressed_size`](../attributes-registry/rpc.md) | int | Compressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.id`](../attributes-registry/rpc.md) | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.type`](../attributes-registry/rpc.md) | string | Whether this is a received or sent message. | `SENT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.uncompressed_size`](../attributes-registry/rpc.md) | int | Uncompressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This way we guarantee that the values will be consistent between different implementations. -`message.type` MUST be one of the following: +`rpc.message.type` MUST be one of the following: | Value | Description | Stability | |---|---|---| diff --git a/model/registry/deprecated/rpc.yaml b/model/registry/deprecated/rpc.yaml new file mode 100644 index 0000000000..c6c36710fe --- /dev/null +++ b/model/registry/deprecated/rpc.yaml @@ -0,0 +1,32 @@ +groups: + - id: attributes.rpc.deprecated + type: attribute_group + brief: 'Deprecated rpc message attributes.' + attributes: + - id: message.type + type: + members: + - id: sent + value: "SENT" + stability: experimental + - id: received + value: "RECEIVED" + stability: experimental + stability: experimental + brief: "Deprecated, use `rpc.message.type` instead." + deprecated: "Replaced by `rpc.message.type`." + - id: message.id + type: int + stability: experimental + brief: "Deprecated, use `rpc.message.id` instead." + deprecated: "Replaced by `rpc.message.id`." + - id: message.compressed_size + type: int + stability: experimental + brief: "Deprecated, use `rpc.message.compressed_size` instead." + deprecated: "Replaced by `rpc.message.compressed_size`." + - id: message.uncompressed_size + type: int + stability: experimental + brief: "Deprecated, use `rpc.message.uncompressed_size` instead." + deprecated: "Replaced by `rpc.message.uncompressed_size`." diff --git a/model/registry/rpc.yaml b/model/registry/rpc.yaml index e7400d540e..d1e0aa05cf 100644 --- a/model/registry/rpc.yaml +++ b/model/registry/rpc.yaml @@ -239,3 +239,27 @@ groups: brief: 'Connect RPC' stability: experimental stability: experimental + - id: message.type + type: + members: + - id: sent + value: "SENT" + stability: experimental + - id: received + value: "RECEIVED" + stability: experimental + stability: experimental + brief: "Whether this is a received or sent message." + - id: message.id + type: int + stability: experimental + brief: "MUST be calculated as two different counters starting from `1` one for sent messages and one for received message." + note: "This way we guarantee that the values will be consistent between different implementations." + - id: message.compressed_size + type: int + stability: experimental + brief: "Compressed size of the message in bytes." + - id: message.uncompressed_size + type: int + stability: experimental + brief: "Uncompressed size of the message in bytes." diff --git a/model/trace/rpc.yaml b/model/trace/rpc.yaml index 7e259966f8..d578c6ba6a 100644 --- a/model/trace/rpc.yaml +++ b/model/trace/rpc.yaml @@ -8,9 +8,13 @@ groups: - ref: rpc.system requirement_level: required - ref: rpc.service + requirement_level: recommended - ref: rpc.method + requirement_level: recommended - ref: network.transport + requirement_level: recommended - ref: network.type + requirement_level: recommended - ref: server.address requirement_level: required brief: > @@ -29,6 +33,7 @@ groups: extends: rpc attributes: - ref: network.peer.address + requirement_level: recommended - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. @@ -40,13 +45,18 @@ groups: brief: 'Semantic Convention for RPC server spans' attributes: - ref: client.address + requirement_level: recommended - ref: client.port + requirement_level: recommended - ref: network.peer.address + requirement_level: recommended - ref: network.peer.port requirement_level: recommended: If `network.peer.address` is set. - ref: network.transport + requirement_level: recommended - ref: network.type + requirement_level: recommended - id: rpc.grpc type: span @@ -75,12 +85,14 @@ groups: conditionally_required: If other than the default version (`1.0`) - ref: rpc.jsonrpc.request_id tag: jsonrpc-tech-specific + requirement_level: recommended - ref: rpc.jsonrpc.error_code tag: jsonrpc-tech-specific requirement_level: conditionally_required: If response is not successful. - ref: rpc.jsonrpc.error_message tag: jsonrpc-tech-specific + requirement_level: recommended - ref: rpc.method tag: jsonrpc-tech-specific requirement_level: required @@ -89,34 +101,18 @@ groups: RPC conventions for more information. - id: rpc.message - prefix: "message" # TODO: Change the prefix to rpc.message? + prefix: rpc.message type: event brief: "RPC received/sent message." attributes: - - id: type - type: - members: - - id: sent - value: "SENT" - stability: experimental - - id: received - value: "RECEIVED" - stability: experimental - stability: experimental - brief: "Whether this is a received or sent message." - - id: id - type: int - stability: experimental - brief: "MUST be calculated as two different counters starting from `1` one for sent messages and one for received message." - note: "This way we guarantee that the values will be consistent between different implementations." - - id: compressed_size - type: int - stability: experimental - brief: "Compressed size of the message in bytes." - - id: uncompressed_size - type: int - stability: experimental - brief: "Uncompressed size of the message in bytes." + - ref: rpc.message.type + requirement_level: recommended + - ref: rpc.message.id + requirement_level: recommended + - ref: rpc.message.compressed_size + requirement_level: recommended + - ref: rpc.message.uncompressed_size + requirement_level: recommended - id: rpc.connect_rpc type: span diff --git a/schema-next.yaml b/schema-next.yaml index 594dff735d..c36ffd7dc5 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -56,6 +56,15 @@ versions: type: process.paging.fault_type apply_to_metrics: - process.paging.faults + all: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/854 + - rename_attributes: + attribute_map: + message.type: rpc.message.type + message.id: rpc.message.id + message.compressed_size: rpc.message.compressed_size + message.uncompressed_size: rpc.message.uncompressed_size 1.24.0: metrics: From 14c8e5291e7b7006c5fa4a2cd8460a059fc07837 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 5 Apr 2024 12:57:13 -0400 Subject: [PATCH 427/482] [editorial] service.md: normalize link to process.md (#883) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- docs/attributes-registry/service.md | 4 ++-- docs/resource/README.md | 2 +- model/registry/service.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/attributes-registry/service.md b/docs/attributes-registry/service.md index 9022d5ac94..ea291b8ac1 100644 --- a/docs/attributes-registry/service.md +++ b/docs/attributes-registry/service.md @@ -40,7 +40,7 @@ However, Collectors can set the `service.instance.id` if they can unambiguously for that telemetry. This is typically the case for scraping receivers, as they know the target address and port. -**[2]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. +**[2]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. **[3]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. - \ No newline at end of file + diff --git a/docs/resource/README.md b/docs/resource/README.md index c00b0cbed8..c26eb9683b 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -85,7 +85,7 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | [`service.name`](../attributes-registry/service.md) | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`service.version`](../attributes-registry/service.md) | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. +**[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. ## Service (Experimental) diff --git a/model/registry/service.yaml b/model/registry/service.yaml index 4e139da36b..5af22be57e 100644 --- a/model/registry/service.yaml +++ b/model/registry/service.yaml @@ -12,7 +12,7 @@ groups: note: > MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated - with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. + with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. examples: ["shoppingcart"] stability: stable From f812621a9128462d1a2466c0d24abcb8a4bdf5fa Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 5 Apr 2024 10:04:26 -0700 Subject: [PATCH 428/482] Rename `db.operation` to `db.operation.name` (#875) Co-authored-by: Liudmila Molkova --- .chloggen/875.yaml | 4 ++++ docs/attributes-registry/db.md | 6 +++--- docs/database/couchdb.md | 6 ++++-- docs/database/database-spans.md | 4 ++-- docs/database/elasticsearch.md | 4 ++-- docs/database/mongodb.md | 5 +++++ docs/database/mssql.md | 14 ++++++++++---- docs/database/sql.md | 10 ++++++++-- model/registry/db.yaml | 12 ++---------- model/registry/deprecated/db.yaml | 6 ++++++ model/trace/database.yaml | 30 +++++++++++++++++++++++------- schema-next.yaml | 4 ++++ 12 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 .chloggen/875.yaml diff --git a/.chloggen/875.yaml b/.chloggen/875.yaml new file mode 100644 index 0000000000..8d75a96c85 --- /dev/null +++ b/.chloggen/875.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Rename `db.operation` to `db.operation.name`. +issues: [ 884 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 63824a6024..e60c2d3741 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -25,15 +25,13 @@ |---|---|---|---|---| | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.operation` | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). -**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. - `db.system` 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 | Stability | @@ -221,6 +219,7 @@ | `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | +| `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | ### Deprecated Elasticsearch Attributes @@ -231,4 +230,5 @@ | `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | +| `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index ebd42dd9b4..20d4963add 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -17,9 +17,11 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` If `db.statement` is not applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). +**[1]:** In **CouchDB**, `db.operation.name` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation.name` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 972635b38d..4b2f1d0d7a 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -75,7 +75,7 @@ Some database systems may allow a connection to switch to a different `db.user`, |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation`](../attributes-registry/db.md) | string | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. [2] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` If `db.statement` is not applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` [4] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -86,7 +86,7 @@ Some database systems may allow a connection to switch to a different `db.user`, **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). -**[2]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. **[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 50cbc3c273..d700e4917d 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -26,7 +26,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation`](../attributes-registry/db.md) | string | The endpoint identifier for the request. [1] | `search`; `ml.close_job`; `cat.aliases` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `search`; `ml.close_job`; `cat.aliases` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://localhost:9200/index/_search?q=user.id:kimchy` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | `Conditionally Required` when the url has dynamic values | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -38,7 +38,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. +**[1]:** This SHOULD be the endpoint identifier for the request. **[2]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index c733f4ffb0..7be3e0559e 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -18,6 +18,11 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [1] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 20829283c2..e7e1178c55 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,12 +17,18 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [2] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [3] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [4] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). +**[1]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[2]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. + +**[3]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +**[4]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index 1357ac2003..7c53a45e5d 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,9 +15,15 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [3] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[1]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. + +**[3]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. ## Example diff --git a/model/registry/db.yaml b/model/registry/db.yaml index f56a830fcb..ec67346e39 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -245,19 +245,11 @@ groups: the database name to be used is the more specific layer (e.g. Oracle schema name). examples: [ 'customers', 'main' ] tag: db-generic - - id: operation + - id: operation.name type: string stability: experimental brief: > - The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) - such as `findAndModify`, or the SQL keyword. - note: > - When setting this to an SQL keyword, it is not recommended to - attempt any client-side parsing of `db.statement` just to get this - property, but it should be set if the operation name is provided by - the library being instrumented. - If the SQL statement has an ambiguous operation, or performs more - than one operation, this value may be omitted. + The name of the operation or command being executed. examples: ['findAndModify', 'HMSET', 'SELECT'] tag: db-generic - id: redis.database_index diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index c2f94cfe22..3d384948c9 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -24,3 +24,9 @@ groups: deprecated: "Replaced by `db.instance.id`." stability: experimental examples: ["instance-0000000001"] + - id: operation + type: string + brief: 'Deprecated, use `db.operation.name` instead.' + stability: experimental + deprecated: "Replaced by `db.operation.name`." + examples: ['findAndModify', 'HMSET', 'SELECT'] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 7435d4e485..6b0dac762f 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -13,9 +13,11 @@ groups: requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. - - ref: db.operation + - ref: db.operation.name requirement_level: - conditionally_required: If `db.statement` is not applicable. + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture + `db.operation.name`, then it SHOULD be the first operation name found in the query. - ref: server.address brief: > Name of the database host. @@ -113,15 +115,15 @@ groups: brief: > Attributes for CouchDB attributes: - - ref: db.operation + - ref: db.operation.name tag: tech-specific brief: > The HTTP method + the target REST route. examples: ['GET /{db}/{docid}'] note: > - In **CouchDB**, `db.operation` should be set to the HTTP method + + In **CouchDB**, `db.operation.name` should be set to the HTTP method + the target REST route according to the API reference documentation. - For example, when retrieving a document, `db.operation` would be set to + For example, when retrieving a document, `db.operation.name` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). @@ -150,6 +152,13 @@ groups: brief: > Attributes for MongoDB attributes: + - ref: db.operation.name + brief: > + The name of the command being executed. + note: > + See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). + examples: ['findAndModify', 'getMore', 'update'] + tag: tech-specific - ref: db.mongodb.collection requirement_level: required tag: tech-specific @@ -163,9 +172,9 @@ groups: - ref: http.request.method requirement_level: required tag: tech-specific - - ref: db.operation + - ref: db.operation.name requirement_level: required - brief: The endpoint identifier for the request. + note: This SHOULD be the endpoint identifier for the request. examples: [ 'search', 'ml.close_job', 'cat.aliases' ] tag: tech-specific - ref: url.full @@ -205,6 +214,13 @@ groups: brief: > Attributes for SQL databases attributes: + - ref: db.operation.name + note: > + This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. + + In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. + examples: ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'mystoredproc'] + tag: tech-specific - ref: db.sql.table tag: tech-specific diff --git a/schema-next.yaml b/schema-next.yaml index c36ffd7dc5..638d717e8c 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -10,6 +10,10 @@ versions: - rename_attributes: attribute_map: messaging.kafka.destination.partition: messaging.destination.partition.id + # https://github.com/open-telemetry/semantic-conventions/pull/875 + - rename_attributes: + attribute_map: + db.operation: db.operation.name metrics: changes: # https://github.com/open-telemetry/semantic-conventions/pull/484 From a08fd23c2861135f96c18b1f91b11bad27f5b52c Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 5 Apr 2024 10:12:06 -0700 Subject: [PATCH 429/482] [chore] Add backward-compatibility check to ci (#764) --- .github/workflows/checks.yml | 7 +++++++ CONTRIBUTING.md | 13 +++++++++++++ Makefile | 10 ++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index a4e32cba18..d7a284a688 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -91,6 +91,13 @@ jobs: - name: verify semantic convention tables run: make table-check + semantic-conventions-compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: verify semantic convention compatibility with latest released version + run: make compatibility-check + schemas-check: runs-on: ubuntu-latest steps: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1435db2e45..f156a5ac4c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,7 @@ requirements and recommendations. - [Markdown style](#markdown-style) - [Misspell check](#misspell-check) - [Markdown link check](#markdown-link-check) + - [Version compatibility check](#version-compatibility-check) - [Updating the referenced specification version](#updating-the-referenced-specification-version) - [Making a Release](#making-a-release) - [Merging existing ECS conventions](#merging-existing-ecs-conventions) @@ -300,6 +301,18 @@ To check the validity of links in all markdown files, run the following command: make markdown-link-check ``` +### Version compatibility check + +Semantic conventions are validated for backward compatibility with last released versions. Here's [the full list of compatibility checks](https://github.com/open-telemetry/build-tools/blob/main/semantic-conventions/README.md#version-compatibility-check). +Removing attributes, metrics, or enum members is not allowed, they should be deprecated instead. +It applies to stable and experimental conventions and prevents semantic conventions auto-generated libraries from introducing breaking changes. + +You can run backward compatibility check in all yaml files with the following command: + +```bash +make compatibility-check +``` + ## Updating the referenced specification version 1. Open the `./internal/tools/update_specification_version.sh` script. diff --git a/Makefile b/Makefile index f330c83b3d..df33d8e6aa 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ SEMCONVGEN_VERSION=0.24.0 # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all -all: install-tools markdownlint markdown-link-check misspell table-check schema-check \ +all: install-tools markdownlint markdown-link-check misspell table-check compatibility-check schema-check \ check-file-and-folder-names-in-docs .PHONY: check-file-and-folder-names-in-docs @@ -103,6 +103,12 @@ table-check: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check +LATEST_RELEASED_SEMCONV_VERSION := $(shell git describe --tags --abbrev=0 | sed 's/v//g') +.PHONY: compatibility-check +compatibility-check: + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ + otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source compatibility --previous-version $(LATEST_RELEASED_SEMCONV_VERSION) + .PHONY: schema-check schema-check: $(TOOLS_DIR)/schema_check.sh @@ -117,7 +123,7 @@ fix-format: # Run all checks in order of speed / likely failure. .PHONY: check -check: misspell markdownlint check-format markdown-toc markdown-link-check +check: misspell markdownlint check-format markdown-toc compatibility-check markdown-link-check git diff --exit-code ':*.md' || (echo 'Generated markdown Table of Contents is out of date, please run "make markdown-toc" and commit the changes in this PR.' && exit 1) @echo "All checks complete" From a00f5ae2430eeddd93805c805275532d300083ac Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 5 Apr 2024 10:19:45 -0700 Subject: [PATCH 430/482] [chore] Update contributing.md - add details on how to create release and push tag (#881) --- CONTRIBUTING.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f156a5ac4c..152f6ce462 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -336,7 +336,15 @@ make compatibility-check `.chloggen` folder automatically - Double check that `CHANGELOG.md` is updated with the proper `v{version}` - Send staging branch as PR for review. -- Create a tag `v{version}` on the merged PR and push remote. +- After the release PR is merged, create a [new release](https://github.com/open-telemetry/semantic-conventions/releases/new): + - Set title and tag to `v{version}` + - Set target to the commit of the merged release PR + - Copy changelog to the release notes + - Verify that the release looks like expected + - Publish release + +New release is then auto-discovered by [opentelemetry.io](https://github.com/open-telemetry/opentelemetry.io) pipelines which (via bot-generated PR) +eventually results in new version of schema file being published. ## Merging existing ECS conventions From 34edf1b967a99d58d516fcbc9438818012b1b9ef Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Fri, 5 Apr 2024 10:29:01 -0700 Subject: [PATCH 431/482] Replace constraints with requirement levels on exceptions (#862) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/862.yaml | 4 ++++ docs/exceptions/exceptions-logs.md | 9 ++++----- docs/exceptions/exceptions-spans.md | 17 ++++++++--------- model/logs/log-exception.yaml | 9 ++++----- model/trace/trace-exception.yaml | 8 ++++---- 5 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 .chloggen/862.yaml diff --git a/.chloggen/862.yaml b/.chloggen/862.yaml new file mode 100644 index 0000000000..828a88899e --- /dev/null +++ b/.chloggen/862.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: exception +note: Replace constraints with requirement levels on exceptions. +issues: [ 862 ] diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index e19e35330c..6f1d98f92c 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -38,14 +38,13 @@ The table below indicates which attributes should be added to the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**Additional attribute requirements:** At least one of the following sets of attributes is required: +**[1]:** Required if `exception.type` is not set, recommended otherwise. -* [`exception.type`](../attributes-registry/exception.md) -* [`exception.message`](../attributes-registry/exception.md) +**[2]:** Required if `exception.message` is not set, recommended otherwise. ### Stacktrace Representation diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index c438e9951b..0dbb2e7313 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -48,12 +48,16 @@ The event name MUST be `exception`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [3] | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | See below | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** An exception is considered to have escaped (or left) the scope of a span, +**[1]:** Required if `exception.type` is not set, recommended otherwise. + +**[2]:** Required if `exception.message` is not set, recommended otherwise. + +**[3]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". This may be actually "in flight" in some languages (e.g. if the exception is passed to a Context manager's `__exit__` method in Python) but will @@ -69,11 +73,6 @@ It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, since the event might have been recorded at a time where it was not clear whether the exception will escape. - -**Additional attribute requirements:** At least one of the following sets of attributes is required: - -* [`exception.type`](../attributes-registry/exception.md) -* [`exception.message`](../attributes-registry/exception.md) ### Stacktrace Representation diff --git a/model/logs/log-exception.yaml b/model/logs/log-exception.yaml index d0b251552a..ab20cb7250 100644 --- a/model/logs/log-exception.yaml +++ b/model/logs/log-exception.yaml @@ -7,10 +7,9 @@ groups: Records. attributes: - ref: exception.type + requirement_level: + conditionally_required: Required if `exception.message` is not set, recommended otherwise. - ref: exception.message + requirement_level: + conditionally_required: Required if `exception.type` is not set, recommended otherwise. - ref: exception.stacktrace - - constraints: - - any_of: - - "exception.type" - - "exception.message" diff --git a/model/trace/trace-exception.yaml b/model/trace/trace-exception.yaml index 8de3abb818..32c53f4b30 100644 --- a/model/trace/trace-exception.yaml +++ b/model/trace/trace-exception.yaml @@ -7,10 +7,10 @@ groups: report a single exception associated with a span. attributes: - ref: exception.type + requirement_level: + conditionally_required: Required if `exception.message` is not set, recommended otherwise. - ref: exception.message + requirement_level: + conditionally_required: Required if `exception.type` is not set, recommended otherwise. - ref: exception.stacktrace - ref: exception.escaped - constraints: - - any_of: - - "exception.type" - - "exception.message" From 3ac1e18fdba9705e2197b6e715c36f0284291047 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:18:52 +0200 Subject: [PATCH 432/482] [chore] move aws lambda and sdk to registry (#893) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- docs/attributes-registry/aws.md | 77 ++++++++++++++++ docs/cloud-providers/aws-sdk.md | 2 +- docs/faas/aws-lambda.md | 2 +- docs/object-stores/s3.md | 12 +-- model/registry/aws.yaml | 116 ++++++++++++++++++++++++ model/trace/aws/lambda.yaml | 11 +-- model/trace/instrumentation/aws-sdk.yml | 104 +++------------------ 7 files changed, 217 insertions(+), 107 deletions(-) diff --git a/docs/attributes-registry/aws.md b/docs/attributes-registry/aws.md index b6fa59ac40..824b0f95ff 100644 --- a/docs/attributes-registry/aws.md +++ b/docs/attributes-registry/aws.md @@ -2,13 +2,23 @@ +- [AWS Generic Attributes](#aws-generic-attributes) - [AWS DynamoDB Attributes](#aws-dynamodb-attributes) - [AWS ECS Attributes](#aws-ecs-attributes) - [AWS EKS Attributes](#aws-eks-attributes) +- [AWS Lambda Attributes](#aws-lambda-attributes) - [AWS Logs Attributes](#aws-logs-attributes) +- [AWS S3 Attributes](#aws-s3-attributes) +## AWS Generic Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + ## AWS DynamoDB Attributes | Attribute | Type | Description | Examples | Stability | @@ -64,6 +74,15 @@ | `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## AWS Lambda Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.lambda.invoked_arn` | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This may be different from `cloud.resource_id` if an alias is involved. + + ## AWS Logs Attributes | Attribute | Type | Description | Examples | Stability | @@ -78,4 +97,62 @@ **[2]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. **[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + + +## AWS S3 Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. +This applies to almost all S3 operations except `list-buckets`. + +**[2]:** The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter +of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). +This applies in particular to the following operations: + +- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + +**[3]:** The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. +The `delete` attribute corresponds to the `--delete` parameter of the +[delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). + +**[4]:** The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. +This applies in particular to the following operations: + +- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) +- [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) +- [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) +- [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) +- [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) +- [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) +- [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) +- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) +- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) +- [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) +- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) +- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + +**[5]:** The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. +The `part_number` attribute corresponds to the `--part-number` parameter of the +[upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). + +**[6]:** The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter +of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. +This applies in particular to the following operations: + +- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) +- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) +- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) +- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) \ No newline at end of file diff --git a/docs/cloud-providers/aws-sdk.md b/docs/cloud-providers/aws-sdk.md index 3ebbf26a9b..487ae23a9b 100644 --- a/docs/cloud-providers/aws-sdk.md +++ b/docs/cloud-providers/aws-sdk.md @@ -28,7 +28,7 @@ with the naming guidelines for RPC client spans. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`rpc.system`](../attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](../attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`rpc.service`](../attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 82c0a4c332..273eb71eeb 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -47,7 +47,7 @@ and the [cloud resource conventions][cloud]. The following AWS Lambda-specific a | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.lambda.invoked_arn` | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.lambda.invoked_arn`](../attributes-registry/aws.md) | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This may be different from `cloud.resource_id` if an alias is involved. diff --git a/docs/object-stores/s3.md b/docs/object-stores/s3.md index cde1a48f32..3ac6a0ab8f 100644 --- a/docs/object-stores/s3.md +++ b/docs/object-stores/s3.md @@ -14,12 +14,12 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.bucket`](../attributes-registry/aws.md) | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.copy_source`](../attributes-registry/aws.md) | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.delete`](../attributes-registry/aws.md) | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.key`](../attributes-registry/aws.md) | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.part_number`](../attributes-registry/aws.md) | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.s3.upload_id`](../attributes-registry/aws.md) | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. diff --git a/model/registry/aws.yaml b/model/registry/aws.yaml index 149d82ad7f..6214375852 100644 --- a/model/registry/aws.yaml +++ b/model/registry/aws.yaml @@ -1,4 +1,17 @@ groups: + - id: registry.aws + prefix: aws + type: attribute_group + brief: > + This document defines generic attributes for AWS services. + attributes: + - id: request_id + type: string + stability: experimental + brief: "The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`." + examples: + - 79b9da39-b7ae-508a-a6bc-864b2829c622 + - C9ER4AJX75574TDJ - id: registry.aws.dynamodb prefix: aws.dynamodb type: attribute_group @@ -354,3 +367,106 @@ groups: [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + + - id: registry.aws.lambda + prefix: aws.lambda + type: attribute_group + brief: > + This document defines attributes for AWS Lambda. + attributes: + - id: invoked_arn + type: string + stability: experimental + brief: > + The full invoked ARN as provided on the `Context` passed to the function + (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). + note: This may be different from `cloud.resource_id` if an alias is involved. + examples: ['arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'] + - id: registry.aws.s3 + prefix: aws.s3 + type: attribute_group + brief: > + This document defines attributes for AWS S3. + attributes: + - id: bucket + type: string + stability: experimental + brief: "The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." + examples: + - some-bucket-name + note: | + The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. + This applies to almost all S3 operations except `list-buckets`. + - id: key + type: string + stability: experimental + brief: "The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." + examples: + - someFile.yml + note: | + The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. + This applies in particular to the following operations: + + - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + - [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) + - [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) + - [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) + - [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) + - [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) + - [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) + - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + - [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) + - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + - id: copy_source + type: string + stability: experimental + brief: "The source object (in the form `bucket`/`key`) for the copy operation." + examples: + - someFile.yml + note: | + The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter + of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). + This applies in particular to the following operations: + + - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + - id: upload_id + type: string + stability: experimental + brief: "Upload ID that identifies the multipart upload." + examples: + - 'dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ' + note: | + The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter + of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. + This applies in particular to the following operations: + + - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) + - id: delete + type: string + stability: experimental + brief: "The delete request container that specifies the objects to be deleted." + examples: + - 'Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean' + note: | + The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. + The `delete` attribute corresponds to the `--delete` parameter of the + [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). + - id: part_number + type: int + stability: experimental + brief: "The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000." + examples: + - 3456 + note: | + The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. + The `part_number` attribute corresponds to the `--part-number` parameter of the + [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). diff --git a/model/trace/aws/lambda.yaml b/model/trace/aws/lambda.yaml index 795736f5ed..41943ab8cb 100644 --- a/model/trace/aws/lambda.yaml +++ b/model/trace/aws/lambda.yaml @@ -1,15 +1,8 @@ groups: - id: aws.lambda - prefix: aws.lambda type: span brief: > Span attributes used by AWS Lambda (in addition to general `faas` attributes). attributes: - - id: invoked_arn - type: string - stability: experimental - brief: > - The full invoked ARN as provided on the `Context` passed to the function - (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). - note: This may be different from `cloud.resource_id` if an alias is involved. - examples: ['arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'] + - ref: aws.lambda.invoked_arn + requirement_level: recommended diff --git a/model/trace/instrumentation/aws-sdk.yml b/model/trace/instrumentation/aws-sdk.yml index 6b6f541544..216f8d1f7f 100644 --- a/model/trace/instrumentation/aws-sdk.yml +++ b/model/trace/instrumentation/aws-sdk.yml @@ -26,13 +26,8 @@ groups: examples: - GetItem - PutItem - - id: request_id - type: string - stability: experimental - brief: "The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`." - examples: - - 79b9da39-b7ae-508a-a6bc-864b2829c622 - - C9ER4AJX75574TDJ + - ref: aws.request_id + requirement_level: recommended - id: dynamodb.all type: span @@ -298,89 +293,18 @@ groups: - id: aws.s3 extends: aws - prefix: aws.s3 type: span brief: "Attributes that exist for S3 request types." attributes: - - id: bucket - type: string - stability: experimental - brief: "The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." - examples: - - some-bucket-name - note: | - The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. - This applies to almost all S3 operations except `list-buckets`. - - id: key - type: string - stability: experimental - brief: "The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations." - examples: - - someFile.yml - note: | - The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. - This applies in particular to the following operations: - - - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) - - [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) - - [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) - - [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) - - [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) - - [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) - - [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) - - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) - - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) - - [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) - - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - - id: copy_source - type: string - stability: experimental - brief: "The source object (in the form `bucket`/`key`) for the copy operation." - examples: - - someFile.yml - note: | - The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter - of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). - This applies in particular to the following operations: - - - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - - id: upload_id - type: string - stability: experimental - brief: "Upload ID that identifies the multipart upload." - examples: - - 'dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ' - note: | - The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter - of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. - This applies in particular to the following operations: - - - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) - - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) - - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - - id: delete - type: string - stability: experimental - brief: "The delete request container that specifies the objects to be deleted." - examples: - - 'Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean' - note: | - The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. - The `delete` attribute corresponds to the `--delete` parameter of the - [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). - - id: part_number - type: int - stability: experimental - brief: "The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000." - examples: - - 3456 - note: | - The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. - The `part_number` attribute corresponds to the `--part-number` parameter of the - [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). + - ref: aws.s3.bucket + requirement_level: recommended + - ref: aws.s3.key + requirement_level: recommended + - ref: aws.s3.copy_source + requirement_level: recommended + - ref: aws.s3.upload_id + requirement_level: recommended + - ref: aws.s3.delete + requirement_level: recommended + - ref: aws.s3.part_number + requirement_level: recommended From 2023cbdaa6f6f7726e5abc911e21cf05d65cf91d Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Mon, 8 Apr 2024 15:56:34 +0200 Subject: [PATCH 433/482] Adjust readme for the registry to include stability level. (#902) Signed-off-by: Alexander Wert --- docs/attributes-registry/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 4d87791234..b69c63fefa 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -9,6 +9,7 @@ The attributes registry is the place where attributes are defined. An attribute - the `id` (the fully qualified name) of the attribute - the `type` of the attribute +- the `stability` of the attribute - a `brief` description of the attribute and optionally a longer `note` - example values From 0d2f7deb5c7069ed283128a76f3fa7e575935e45 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 8 Apr 2024 16:48:15 +0200 Subject: [PATCH 434/482] [chore] change prefix for deprecated attributes (#898) --- docs/attributes-registry/container.md | 15 ++++++++++++++ docs/attributes-registry/db.md | 14 +------------ docs/attributes-registry/http.md | 9 ++++++++- docs/attributes-registry/k8s.md | 17 +++++++++++++++- docs/attributes-registry/messaging.md | 2 +- docs/attributes-registry/network.md | 9 ++++++++- docs/attributes-registry/otel.md | 18 ++++++++++++++++- docs/attributes-registry/rpc.md | 25 ++++++++++++++++++++++++ model/registry/deprecated/container.yaml | 2 +- model/registry/deprecated/db.yaml | 2 +- model/registry/deprecated/http.yaml | 2 +- model/registry/deprecated/k8s.yaml | 2 +- model/registry/deprecated/messaging.yaml | 2 +- model/registry/deprecated/network.yaml | 2 +- model/registry/deprecated/otel.yaml | 7 +++---- model/registry/deprecated/rpc.yaml | 2 +- model/registry/deprecated/system.yaml | 2 +- 17 files changed, 102 insertions(+), 30 deletions(-) diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index b8b37373c6..d3d41467db 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -3,6 +3,13 @@ # Container + + +- [Container Attributes](#container-attributes) +- [Deprecated Container Attributes](#deprecated-container-attributes) + + + ## Container Attributes @@ -37,3 +44,11 @@ The ID is assinged by the container runtime and can vary in different environmen | `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Deprecated Container Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `container.labels.` | string | Deprecated, use `container.label` instead. | `container.label.app=nginx` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `container.label`. | + diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index e60c2d3741..7ed3b02f92 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -14,7 +14,6 @@ - [Redis Attributes](#redis-attributes) - [SQL Attributes](#sql-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) - - [Deprecated Elasticsearch Attributes](#deprecated-elasticsearch-attributes) @@ -213,18 +212,7 @@ ## Deprecated DB Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | -| `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | -| `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | -| `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | - - -### Deprecated Elasticsearch Attributes - - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index e25443590d..c3d92a7b33 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -3,6 +3,13 @@ # HTTP + + +- [HTTP Attributes](#http-attributes) +- [Deprecated HTTP Attributes](#deprecated-http-attributes) + + + ## HTTP Attributes @@ -74,7 +81,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin ## Deprecated HTTP Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index ea7c55d6fc..d60f610782 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -1,6 +1,13 @@ # Kubernetes -## Kubernetes Resource Attributes + + +- [Kubernetes Attributes](#kubernetes-attributes) +- [Deprecated Kubernetes Attributes](#deprecated-kubernetes-attributes) + + + +## Kubernetes Attributes | Attribute | Type | Description | Examples | Stability | @@ -52,3 +59,11 @@ Which states: Therefore, UIDs between clusters should be extremely unlikely to conflict. + +## Deprecated Kubernetes Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `k8s.pod.labels.` | string | Deprecated, use `k8s.pod.label` instead. | `k8s.pod.label.app=my-app` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `k8s.pod.label`. | + \ No newline at end of file diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 3e713cdd5a..ba7f61aec3 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -174,7 +174,7 @@ size should be used. ## Deprecated Messaging Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.kafka.destination.partition` | int | "Deprecated, use `messaging.destination.partition.id` instead." | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 497a575c31..48dabc6512 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -5,6 +5,13 @@ These attributes may be used for any network related operation. + + +- [Network Attributes](#network-attributes) +- [Deprecated Network Attributes](#deprecated-network-attributes) + + + ## Network Attributes @@ -100,7 +107,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. ## Deprecated Network Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | diff --git a/docs/attributes-registry/otel.md b/docs/attributes-registry/otel.md index 730ef8a14c..92c94105c5 100644 --- a/docs/attributes-registry/otel.md +++ b/docs/attributes-registry/otel.md @@ -3,7 +3,14 @@ # OpenTelemetry -## Scope Attributes + + +- [OpenTelemetry Attributes](#opentelemetry-attributes) +- [Deprecated OpenTelemetry Attributes](#deprecated-opentelemetry-attributes) + + + +## OpenTelemetry Attributes | Attribute | Type | Description | Examples | Stability | @@ -11,3 +18,12 @@ | `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +## Deprecated OpenTelemetry Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `otel.library.name` | string | None | `io.opentelemetry.contrib.mongodb` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.name` attribute. | +| `otel.library.version` | string | None | `1.0.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.version` attribute. | + \ No newline at end of file diff --git a/docs/attributes-registry/rpc.md b/docs/attributes-registry/rpc.md index 25f7a29087..f8d8e67844 100644 --- a/docs/attributes-registry/rpc.md +++ b/docs/attributes-registry/rpc.md @@ -3,6 +3,13 @@ # RPC + + +- [RPC Attributes](#rpc-attributes) +- [Deprecated RPC Attributes](#deprecated-rpc-attributes) + + + ## RPC Attributes RPC attributes are intended to be used in the context of events related to remote procedure calls (RPC). @@ -102,3 +109,21 @@ RPC attributes are intended to be used in the context of events related to remot | `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Deprecated RPC Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `message.compressed_size` | int | Deprecated, use `rpc.message.compressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.compressed_size`. | +| `message.id` | int | Deprecated, use `rpc.message.id` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.id`. | +| `message.type` | string | Deprecated, use `rpc.message.type` instead. | `SENT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.type`. | +| `message.uncompressed_size` | int | Deprecated, use `rpc.message.uncompressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.uncompressed_size`. | + +`message.type` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `SENT` | sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `RECEIVED` | received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/model/registry/deprecated/container.yaml b/model/registry/deprecated/container.yaml index 49190f6918..77f3466f02 100644 --- a/model/registry/deprecated/container.yaml +++ b/model/registry/deprecated/container.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.container.deprecated + - id: registry.container.deprecated type: attribute_group brief: "Describes deprecated container attributes." attributes: diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 3d384948c9..2adef825d3 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.db.deprecated + - id: registry.db.deprecated prefix: db type: attribute_group brief: > diff --git a/model/registry/deprecated/http.yaml b/model/registry/deprecated/http.yaml index 746d8f1db4..4eaaa6ce19 100644 --- a/model/registry/deprecated/http.yaml +++ b/model/registry/deprecated/http.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.http.deprecated + - id: registry.http.deprecated type: attribute_group brief: "Describes deprecated HTTP attributes." prefix: http diff --git a/model/registry/deprecated/k8s.yaml b/model/registry/deprecated/k8s.yaml index ae471dd896..e2785dd08e 100644 --- a/model/registry/deprecated/k8s.yaml +++ b/model/registry/deprecated/k8s.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.k8s.deprecated + - id: registry.k8s.deprecated type: attribute_group brief: "Describes deprecated k8s attributes." attributes: diff --git a/model/registry/deprecated/messaging.yaml b/model/registry/deprecated/messaging.yaml index 97da3c55bb..a2675c7c47 100644 --- a/model/registry/deprecated/messaging.yaml +++ b/model/registry/deprecated/messaging.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.messaging.deprecated + - id: registry.messaging.deprecated type: attribute_group brief: "Describes deprecated messaging attributes." attributes: diff --git a/model/registry/deprecated/network.yaml b/model/registry/deprecated/network.yaml index 8377f727e6..6614467174 100644 --- a/model/registry/deprecated/network.yaml +++ b/model/registry/deprecated/network.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.network.deprecated + - id: registry.network.deprecated prefix: net type: attribute_group brief: > diff --git a/model/registry/deprecated/otel.yaml b/model/registry/deprecated/otel.yaml index 23456367bc..c52a51fe8c 100644 --- a/model/registry/deprecated/otel.yaml +++ b/model/registry/deprecated/otel.yaml @@ -1,9 +1,8 @@ groups: - - id: otel.library + - id: registry.otel.library.deprecated prefix: otel.library - type: resource - brief: > - Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + type: attribute_group + brief: "Describes deprecated otel.library attributes." attributes: - id: name type: string diff --git a/model/registry/deprecated/rpc.yaml b/model/registry/deprecated/rpc.yaml index c6c36710fe..1d9d22c2d4 100644 --- a/model/registry/deprecated/rpc.yaml +++ b/model/registry/deprecated/rpc.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.rpc.deprecated + - id: registry.rpc.deprecated type: attribute_group brief: 'Deprecated rpc message attributes.' attributes: diff --git a/model/registry/deprecated/system.yaml b/model/registry/deprecated/system.yaml index bda1dc0e9b..700023ab57 100644 --- a/model/registry/deprecated/system.yaml +++ b/model/registry/deprecated/system.yaml @@ -1,5 +1,5 @@ groups: - - id: attributes.system.deprecated + - id: registry.system.deprecated type: attribute_group brief: "Deprecated system attributes." attributes: From a776eaf3fc41621e9f9f933686bf94ad3b845d7c Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 Apr 2024 08:16:06 -0700 Subject: [PATCH 435/482] Deprecate `db.user` (#894) --- .chloggen/894.yaml | 4 ++++ docs/attributes-registry/db.md | 2 +- docs/database/database-spans.md | 2 -- docs/database/mongodb.md | 1 - docs/database/redis.md | 1 - docs/database/sql.md | 1 - docs/general/attribute-naming.md | 2 +- model/registry/db.yaml | 7 ------- model/registry/deprecated/db.yaml | 6 ++++++ model/trace/database.yaml | 1 - 10 files changed, 12 insertions(+), 15 deletions(-) create mode 100644 .chloggen/894.yaml diff --git a/.chloggen/894.yaml b/.chloggen/894.yaml new file mode 100644 index 0000000000..23f73b1f2c --- /dev/null +++ b/.chloggen/894.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Deprecate the `db.user` attribute. +issues: [ 885 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 7ed3b02f92..ea89a0c930 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -27,7 +27,6 @@ | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.user` | string | Username for accessing the database. | `readonly_user`; `reporting_user` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). @@ -219,4 +218,5 @@ | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | | `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 4b2f1d0d7a..339313e282 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -68,7 +68,6 @@ with all retries. ## Common attributes These attributes will usually be the same for all operations performed over the same database connection. -Some database systems may allow a connection to switch to a different `db.user`, for example, and other database systems may not even have the concept of a connection at all. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | @@ -79,7 +78,6 @@ Some database systems may allow a connection to switch to a different `db.user`, | [`server.port`](../attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` [4] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.user`](../attributes-registry/db.md) | string | Username for accessing the database. | `readonly_user`; `reporting_user` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [6] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 7be3e0559e..473cf4c137 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -31,7 +31,6 @@ described on this page. | :---------------------- | :----------------------------------------------------------- | | Span name | `"products.findAndModify"` | | `db.system` | `"mongodb"` | -| `db.user` | `"the_user"` | | `server.address` | `"mongodb0.example.com"` | | `server.port` | `27017` | | `network.peer.address` | `"192.0.2.14"` | diff --git a/docs/database/redis.md b/docs/database/redis.md index da70edf142..6007bb57b1 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -38,7 +38,6 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an |:--------------------------| :-------------------------------------------- | | Span name | `"HMSET myhash"` | | `db.system` | `"redis"` | -| `db.user` | not set | | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | | `db.name` | not set | diff --git a/docs/database/sql.md b/docs/database/sql.md index 7c53a45e5d..0427c20872 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -34,7 +34,6 @@ This is an example of attributes for a MySQL database span: |:------------------------| :----------------------------------------------------------- | | Span name | `"SELECT ShopDb.orders"` | | `db.system` | `"mysql"` | -| `db.user` | `"billing_user"` | | `server.address` | `"shopdb.example.com"` | | `server.port` | `3306` | | `network.peer.address` | `"192.0.2.12"` | diff --git a/docs/general/attribute-naming.md b/docs/general/attribute-naming.md index 9f4e93dd45..57a99b62cd 100644 --- a/docs/general/attribute-naming.md +++ b/docs/general/attribute-naming.md @@ -60,7 +60,7 @@ Names SHOULD follow these rules: ## Name Pluralization guidelines - When an attribute represents a single entity, the attribute name SHOULD be - singular. Examples: `host.name`, `db.user`, `container.id`. + singular. Examples: `host.name`, `container.id`. - When attribute can represent multiple entities, the attribute name SHOULD be pluralized and the value type SHOULD be an array. E.g. `process.command_args` diff --git a/model/registry/db.yaml b/model/registry/db.yaml index ec67346e39..83b71d16a6 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -494,13 +494,6 @@ groups: stability: experimental stability: experimental tag: db-generic - - id: user - type: string - stability: experimental - brief: > - Username for accessing the database. - examples: ['readonly_user', 'reporting_user'] - tag: db-generic - id: instance.id tag: db-generic type: string diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 2adef825d3..b861dd7fd6 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -30,3 +30,9 @@ groups: stability: experimental deprecated: "Replaced by `db.operation.name`." examples: ['findAndModify', 'HMSET', 'SELECT'] + - id: user + type: string + brief: 'Deprecated, no replacement at this time.' + deprecated: "No replacement at this time." + stability: experimental + examples: ['readonly_user', 'reporting_user'] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 6b0dac762f..5ca47c4f91 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -5,7 +5,6 @@ groups: attributes: - ref: db.system requirement_level: required - - ref: db.user - ref: db.name requirement_level: conditionally_required: If applicable. From c65428b52eeea15db850cf98503e6d28bbdf7fe9 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 8 Apr 2024 17:23:19 +0200 Subject: [PATCH 436/482] [chore] move opentracing to the registry (#900) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/opentracing.md | 21 ++++++++++++++++++++ docs/general/trace-compatibility.md | 6 +++--- model/registry/opentracing.yaml | 22 +++++++++++++++++++++ model/trace/compatibility.yaml | 19 ++---------------- 8 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 docs/attributes-registry/opentracing.md create mode 100644 model/registry/opentracing.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 6abd8a9103..138ec6c592 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -49,6 +49,7 @@ body: - area:messaging - area:network - area:oci + - area:opentracing - area:os - area:otel - area:peer diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index c064231a77..117491cb40 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -42,6 +42,7 @@ body: - area:messaging - area:network - area:oci + - area:opentracing - area:os - area:otel - area:peer diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 0b75deac83..f663263c59 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -51,6 +51,7 @@ body: - area:messaging - area:network - area:oci + - area:opentracing - area:os - area:otel - area:peer diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index b69c63fefa..c9f832ec74 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -57,6 +57,7 @@ Currently, the following namespaces exist: * [Network](network.md) * [OCI](oci.md) * [OpenTelemetry](otel.md) +* [OpenTracing](opentracing.md) * [OS](os.md) * [Peer](peer.md) * [Process](process.md) diff --git a/docs/attributes-registry/opentracing.md b/docs/attributes-registry/opentracing.md new file mode 100644 index 0000000000..727271b544 --- /dev/null +++ b/docs/attributes-registry/opentracing.md @@ -0,0 +1,21 @@ + + +# OpenTracing + +## OpenTracing Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The causal relationship between a child Span and a parent Span. + +`opentracing.ref_type` 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 | Stability | +|---|---|---| +| `child_of` | The parent Span depends on the child Span in some capacity | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index 28d142cdf3..958e6c5b4f 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -24,14 +24,14 @@ with one of the accepted values, describing the direct causal relationships between a child Span and a parent Span, as defined by [OpenTracing](https://github.com/opentracing/specification/blob/master/specification.md). - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`opentracing.ref_type`](../attributes-registry/opentracing.md) | string | Parent-child Reference type [1] | `child_of` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The causal relationship between a child Span and a parent Span. -`opentracing.ref_type` MUST be one of the following: +`opentracing.ref_type` 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 | Stability | |---|---|---| diff --git a/model/registry/opentracing.yaml b/model/registry/opentracing.yaml new file mode 100644 index 0000000000..fd9d68e380 --- /dev/null +++ b/model/registry/opentracing.yaml @@ -0,0 +1,22 @@ +groups: + - id: registry.opentracing + prefix: opentracing + type: attribute_group + brief: Attributes used by the OpenTracing Shim layer. + attributes: + - id: ref_type + brief: 'Parent-child Reference type' + stability: experimental + note: > + The causal relationship between a child Span and a parent Span. + type: + allow_custom_values: true + members: + - id: child_of + value: 'child_of' + brief: "The parent Span depends on the child Span in some capacity" + stability: experimental + - id: follows_from + value: 'follows_from' + brief: "The parent Span doesn't depend in any way on the result of the child Span" + stability: experimental diff --git a/model/trace/compatibility.yaml b/model/trace/compatibility.yaml index 2ed1de06b4..3f906d18cf 100644 --- a/model/trace/compatibility.yaml +++ b/model/trace/compatibility.yaml @@ -1,24 +1,9 @@ groups: - id: opentracing - prefix: opentracing type: span brief: 'This document defines semantic conventions for the OpenTracing Shim' note: > These conventions are used by the OpenTracing Shim layer. attributes: - - id: ref_type - brief: 'Parent-child Reference type' - stability: experimental - note: > - The causal relationship between a child Span and a parent Span. - type: - allow_custom_values: false - members: - - id: child_of - value: 'child_of' - brief: "The parent Span depends on the child Span in some capacity" - stability: experimental - - id: follows_from - value: 'follows_from' - brief: "The parent Span doesn't depend in any way on the result of the child Span" - stability: experimental + - ref: opentracing.ref_type + requirement_level: recommended From b5b2409b52157cabb0debd54ed14bc90f38d7bd9 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 Apr 2024 09:48:04 -0700 Subject: [PATCH 437/482] Rename `db.statement` to `db.query.text` and introduce `db.query.parameter.` (#866) --- .chloggen/866.yaml | 4 ++++ docs/attributes-registry/db.md | 11 ++++++++--- docs/database/cassandra.md | 2 +- docs/database/database-spans.md | 6 +++++- docs/database/elasticsearch.md | 2 +- docs/database/mssql.md | 2 +- docs/database/redis.md | 4 ++-- docs/database/sql.md | 2 +- model/registry/db.yaml | 23 ++++++++++++++++++----- model/registry/deprecated/db.yaml | 6 ++++++ model/trace/database.yaml | 12 +++++++----- schema-next.yaml | 4 ++++ 12 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 .chloggen/866.yaml diff --git a/.chloggen/866.yaml b/.chloggen/866.yaml new file mode 100644 index 0000000000..43ee49568b --- /dev/null +++ b/.chloggen/866.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Rename `db.statement` to `db.query.text` and introduce `db.query.parameter.` +issues: [ 716 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index ea89a0c930..7cbe0819f9 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -25,11 +25,15 @@ | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [2] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[2]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. + `db.system` 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 | Stability | @@ -101,7 +105,7 @@ | `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cassandra.table` | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. `db.cassandra.consistency_level` MUST be one of the following: @@ -206,7 +210,7 @@ |---|---|---|---|---| | `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[1]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. ## Deprecated DB Attributes @@ -218,5 +222,6 @@ | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | | `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 342fdc4053..efcb9b5915 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -30,7 +30,7 @@ described on this page. **[1]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. -**[2]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[2]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. **[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 339313e282..9a1f2222fb 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -77,10 +77,11 @@ These attributes will usually be the same for all operations performed over the | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` [4] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.statement`](../attributes-registry/db.md) | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [6] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [8] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). @@ -97,6 +98,9 @@ If a database operation involved multiple network calls (for example retries), t **[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[8]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. + `db.system` 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 | Stability | diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index d700e4917d..c04c894ca0 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -33,7 +33,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.statement`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/database/mssql.md b/docs/database/mssql.md index e7e1178c55..47ed5a0012 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -28,7 +28,7 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[3]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). -**[4]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[4]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index 6007bb57b1..2011dc67e7 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -18,11 +18,11 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | `Conditionally Required` If other than the default database (`0`). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.statement`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. +**[1]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. **[2]:** Should be collected by default only if there is sanitization that excludes sensitive information. diff --git a/docs/database/sql.md b/docs/database/sql.md index 0427c20872..002fff4d06 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -23,7 +23,7 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[3]:** It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[3]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. ## Example diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 83b71d16a6..f967fdbe64 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -86,7 +86,7 @@ groups: note: > This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of - `db.statement` just to get this property, but it should be set if + `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. @@ -266,18 +266,31 @@ groups: brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). note: > It is not recommended to attempt any client-side parsing of - `db.statement` just to get this property, but it should be set if + `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. examples: ['public.users', 'customers'] tag: tech-specific-sql - - id: statement + - id: query.text type: string stability: experimental brief: > - The database statement being executed. - examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] + The database query being executed. + examples: ['SELECT * FROM wuser_table where username = ?', 'SET mykey "WuValue"'] + tag: db-generic + - id: query.parameter + type: template[string] + stability: experimental + brief: > + The query parameters used in `db.query.text`, with `` being the parameter name, + and the attribute value being the parameter value. + note: > + Query parameters should only be captured when `db.query.text` is parameterized with placeholders. + + If a parameter has no name and instead is referenced only by index, + then `` SHOULD be the 0-based index. + examples: ['someval', '55'] tag: db-generic - id: system brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index b861dd7fd6..1fec703f81 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -36,3 +36,9 @@ groups: deprecated: "No replacement at this time." stability: experimental examples: ['readonly_user', 'reporting_user'] + - id: statement + type: string + brief: The database statement being executed. + deprecated: "Replaced by `db.query.text`." + stability: experimental + examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 5ca47c4f91..8c6f973b39 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -8,10 +8,12 @@ groups: - ref: db.name requirement_level: conditionally_required: If applicable. - - ref: db.statement + - ref: db.query.text requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. + - ref: db.query.parameter + requirement_level: opt_in - ref: db.operation.name requirement_level: conditionally_required: > @@ -136,14 +138,14 @@ groups: requirement_level: conditionally_required: If other than the default database (`0`). tag: tech-specific - - ref: db.statement + - ref: db.query.text tag: tech-specific brief: > The full syntax of the Redis CLI command. examples: ["HMSET myhash field1 'Hello' field2 'World'"] note: > - For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. - If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`. + For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. + If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. - id: db.mongodb type: span @@ -180,7 +182,7 @@ groups: requirement_level: required examples: [ 'https://localhost:9200/index/_search?q=user.id:kimchy' ] tag: tech-specific - - ref: db.statement + - ref: db.query.text requirement_level: recommended: > Should be collected by default for search-type queries and only if there is sanitization that excludes diff --git a/schema-next.yaml b/schema-next.yaml index 638d717e8c..6a217cea7f 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -14,6 +14,10 @@ versions: - rename_attributes: attribute_map: db.operation: db.operation.name + # https://github.com/open-telemetry/semantic-conventions/pull/866 + - rename_attributes: + attribute_map: + db.statement: db.query.text metrics: changes: # https://github.com/open-telemetry/semantic-conventions/pull/484 From ff49c9b6fa0a8b90b4e8a49ffa2ba2ccb0149ea8 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 8 Apr 2024 10:14:27 -0700 Subject: [PATCH 438/482] DB: rename table/container/etc to collection (#870) --- .chloggen/870.yaml | 4 +++ docs/attributes-registry/db.md | 39 +++++++++-------------------- docs/database/cassandra.md | 14 ++++++----- docs/database/cosmosdb.md | 16 ++++++------ docs/database/couchdb.md | 2 +- docs/database/database-spans.md | 39 ++++++++++++++++------------- docs/database/mongodb.md | 10 +++++--- docs/database/mssql.md | 18 ++++++++------ docs/database/sql.md | 16 ++++++------ model/registry/db.yaml | 41 +++++-------------------------- model/registry/deprecated/db.yaml | 24 ++++++++++++++++++ model/trace/database.yaml | 21 ++++++++++++---- schema-next.yaml | 7 ++++++ 13 files changed, 133 insertions(+), 118 deletions(-) create mode 100644 .chloggen/870.yaml diff --git a/.chloggen/870.yaml b/.chloggen/870.yaml new file mode 100644 index 0000000000..dd5dc6fe37 --- /dev/null +++ b/.chloggen/870.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Renames `db.sql.table`, `db.cassandra.table`, `db.mongodb.collection`, and `db.cosmosdb.container` attributes to `db.collection.name` +issues: [ 870 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 7cbe0819f9..45c73f0997 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -9,10 +9,8 @@ - [Cassandra Attributes](#cassandra-attributes) - [CosmosDB Attributes](#cosmosdb-attributes) - [Elasticsearch Attributes](#elasticsearch-attributes) -- [MongoDB Attributes](#mongodb-attributes) - [MSSQL Attributes](#mssql-attributes) - [Redis Attributes](#redis-attributes) -- [SQL Attributes](#sql-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) @@ -22,16 +20,19 @@ | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [2] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [2] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[2]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + +**[3]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. `db.system` 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. @@ -103,9 +104,6 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.table` | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [1] | `mytable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. `db.cassandra.consistency_level` MUST be one of the following: @@ -131,7 +129,6 @@ If a parameter has no name and instead is referenced only by index, then `` |---|---|---|---|---| | `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.container` | string | Cosmos DB container name. | `anystring` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -177,14 +174,6 @@ If a parameter has no name and instead is referenced only by index, then `` **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -## MongoDB Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.mongodb.collection` | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - ## MSSQL Attributes @@ -203,25 +192,19 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## SQL Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.sql.table` | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. - - ## Deprecated DB Attributes | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `db.cassandra.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | +| `db.cosmosdb.container` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | +| `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.sql.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index efcb9b5915..b726721e92 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -17,22 +17,24 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [1] | `mykeyspace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the Cassandra table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [3] | `mykeyspace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.idempotence`](../attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.page_size`](../attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.table`](../attributes-registry/db.md) | string | The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). [2] | `mytable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[3]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +**[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. `db.cassandra.consistency_level` MUST be one of the following: diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 5ec6dd24dc..499d453db6 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -20,21 +20,23 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`db.collection.name`](../attributes-registry/db.md) | string | Cosmos DB container name. [1] | `public.users`; `customers` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.connection_mode`](../attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway` | `Conditionally Required` if not `direct` (or pick gw as default) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.container`](../attributes-registry/db.md) | string | Cosmos DB container name. | `anystring` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.request_charge`](../attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1.0` | `Conditionally Required` when available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.status_code`](../attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | `Conditionally Required` if response was received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.request_content_length`](../attributes-registry/db.md) | int | Request payload size in bytes | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [3] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [4] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** when performing one of the operations in this list +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** when response was received and contained sub-code. +**[2]:** when performing one of the operations in this list -**[3]:** The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. +**[3]:** when response was received and contained sub-code. + +**[4]:** The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). Default value is "NS". diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 20d4963add..6c3ad89c72 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -21,7 +21,7 @@ described on this page. **[1]:** In **CouchDB**, `db.operation.name` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation.name` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 9a1f2222fb..937e8a5770 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -55,8 +55,8 @@ The **span name** SHOULD be set to a low cardinality value representing the stat It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation` and `db.sql.table` are available. -If `db.sql.table` is not available due to its semantics, the span SHOULD be named ` `. +` .`, provided that `db.operation` and `db.collection.name` are available. +If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. It is not recommended to attempt any client-side parsing of `db.statement` just to get these properties, they should only be used if the library being instrumented already provides them. When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. @@ -73,32 +73,37 @@ These attributes will usually be the same for all operations performed over the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Conditionally Required` [4] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [6] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [8] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [10] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). -**[4]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[5]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[6]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[7]:** Should be collected by default only if there is sanitization that excludes sensitive information. + +**[8]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[9]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[8]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[10]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. `db.system` 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. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 473cf4c137..de02a0b6ba 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -17,12 +17,14 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.mongodb.collection`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. | `customers`; `products` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [1] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [2] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[2]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). + +**[3]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 47ed5a0012..e4c0774857 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,18 +17,20 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [3] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [4] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [5] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. -In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[3]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[4]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[5]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index 002fff4d06..60bf0b8cf8 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,15 +15,17 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.sql.table`](../attributes-registry/db.md) | string | The name of the primary table that the operation is acting upon, including the database name (if applicable). [3] | `public.users`; `customers` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. -In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[3]:** It is not recommended to attempt any client-side parsing of `db.query.text` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example @@ -42,6 +44,6 @@ This is an example of attributes for a MySQL database span: | `db.name` | `"ShopDb"` | | `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation` | `"SELECT"` | -| `db.sql.table` | `"orders"` | +| `db.collection.name` | `"orders"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/registry/db.yaml b/model/registry/db.yaml index f967fdbe64..cce3c33972 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -79,19 +79,15 @@ groups: The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. examples: [0, 2] tag: tech-specific-cassandra - - id: cassandra.table + - id: collection.name type: string stability: experimental - brief: The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + brief: The name of a collection (table, container) within the database. note: > - This mirrors the db.sql.table attribute but references cassandra rather than sql. - It is not recommended to attempt any client-side parsing of - `db.query.text` just to get this property, but it should be set if - it is provided by the library being instrumented. - If the operation is acting upon an anonymous table, or more than one table, this - value MUST NOT be set. - examples: 'mytable' - tag: tech-specific-cassandra + If the collection name is parsed from the query, it SHOULD match the value provided + in the query and may be qualified with the schema and database name. + tag: db-generic + examples: ['public.users', 'customers'] - id: cosmosdb.client_id type: string stability: experimental @@ -113,12 +109,6 @@ groups: stability: experimental brief: Cosmos client connection mode. tag: tech-specific-cosmosdb - - id: cosmosdb.container - type: string - stability: experimental - brief: Cosmos DB container name. - examples: 'anystring' - tag: tech-specific-cosmosdb - id: cosmosdb.operation_type type: allow_custom_values: true @@ -213,13 +203,6 @@ groups: in order to map the path part values to their names. examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] tag: tech-specific-elasticsearch - - id: mongodb.collection - type: string - stability: experimental - brief: > - The MongoDB collection being accessed within the database stated in `db.name`. - examples: [ 'customers', 'products' ] - tag: tech-specific-mongodb - id: mssql.instance_name type: string stability: experimental @@ -260,18 +243,6 @@ groups: To be used instead of the generic `db.name` attribute. examples: [0, 1, 15] tag: tech-specific-redis - - id: sql.table - type: string - stability: experimental - brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). - note: > - It is not recommended to attempt any client-side parsing of - `db.query.text` just to get this property, but it should be set if - it is provided by the library being instrumented. - If the operation is acting upon an anonymous table, or more than one table, this - value MUST NOT be set. - examples: ['public.users', 'customers'] - tag: tech-specific-sql - id: query.text type: string stability: experimental diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 1fec703f81..a5a6390b1b 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -42,3 +42,27 @@ groups: deprecated: "Replaced by `db.query.text`." stability: experimental examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] + - id: cassandra.table + type: string + stability: experimental + brief: 'Deprecated, use `db.collection.name` instead.' + deprecated: "Replaced by `db.collection.name`." + examples: 'mytable' + - id: cosmosdb.container + type: string + stability: experimental + brief: 'Deprecated, use `db.collection.name` instead.' + deprecated: "Replaced by `db.collection.name`." + examples: 'mytable' + - id: mongodb.collection + type: string + stability: experimental + brief: 'Deprecated, use `db.collection.name` instead.' + deprecated: "Replaced by `db.collection.name`." + examples: 'mytable' + - id: sql.table + type: string + stability: experimental + brief: 'Deprecated, use `db.collection.name` instead.' + deprecated: "Replaced by `db.collection.name`." + examples: 'mytable' diff --git a/model/trace/database.yaml b/model/trace/database.yaml index 8c6f973b39..b4ed7d0da6 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -17,7 +17,7 @@ groups: - ref: db.operation.name requirement_level: conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.statement` to capture + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. - ref: server.address brief: > @@ -28,6 +28,11 @@ groups: - ref: db.instance.id requirement_level: recommended: If different from the `server.address` + - ref: db.collection.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.collection.name`, then it SHOULD be the first collection name found in the query. - ref: network.peer.address brief: Peer address of the database node where the operation was performed. requirement_level: @@ -86,7 +91,8 @@ groups: tag: tech-specific - ref: db.cassandra.consistency_level tag: tech-specific - - ref: db.cassandra.table + - ref: db.collection.name + brief: The name of the Cassandra table that the operation is acting upon. tag: tech-specific - ref: db.cassandra.idempotence tag: tech-specific @@ -160,7 +166,9 @@ groups: See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). examples: ['findAndModify', 'getMore', 'update'] tag: tech-specific - - ref: db.mongodb.collection + - ref: db.collection.name + brief: + The MongoDB collection being accessed within the database stated in `db.name`. requirement_level: required tag: tech-specific @@ -222,7 +230,8 @@ groups: In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. examples: ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE', 'mystoredproc'] tag: tech-specific - - ref: db.sql.table + - ref: db.collection.name + brief: The name of the SQL table that the operation is acting upon. tag: tech-specific - id: db.cosmosdb @@ -257,7 +266,9 @@ groups: requirement_level: conditionally_required: if not `direct` (or pick gw as default) tag: tech-specific - - ref: db.cosmosdb.container + - ref: db.collection.name + brief: > + Cosmos DB container name. requirement_level: conditionally_required: if available tag: tech-specific diff --git a/schema-next.yaml b/schema-next.yaml index 6a217cea7f..b893a50d4e 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -6,6 +6,13 @@ versions: 1.25.0: spans: changes: + # https://github.com/open-telemetry/semantic-conventions/pull/870 + - rename_attributes: + attribute_map: + db.sql.table: db.collection.name + db.mongodb.collection: db.collection.name + db.cosmosdb.container: db.collection.name + db.cassandra.table: db.collection.name # https://github.com/open-telemetry/semantic-conventions/pull/798 - rename_attributes: attribute_map: From 49669266d979d925b1152885bd0be886929c7f22 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 8 Apr 2024 13:05:09 -0700 Subject: [PATCH 439/482] Update references from `db.operation` to `db.operation.name` (#904) --- docs/database/cosmosdb.md | 2 +- docs/database/database-spans.md | 4 ++-- docs/database/elasticsearch.md | 4 ++-- docs/database/mongodb.md | 6 +++--- docs/database/redis.md | 2 +- docs/database/sql.md | 26 ++++++++++++------------- model/trace/instrumentation/aws-sdk.yml | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 499d453db6..f6a32606fa 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -80,7 +80,7 @@ In addition to Cosmos DB attributes, all spans include | `az.namespace` | `"Microsoft.DocumentDB"` | | `db.system` | `"cosmosdb"` | | `db.name` | `"database name"` | -| `db.operation` | `"ReadItemsAsync"` | +| `db.operation.name` | `"ReadItemsAsync"` | | `server.address` | `"account.documents.azure.com"` | | `db.cosmosdb.client_id` | `3ba4827d-4422-483f-b59f-85b74211c11d` | | `db.cosmosdb.operation_type` | `Read` | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 937e8a5770..3a758bf223 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -55,8 +55,8 @@ The **span name** SHOULD be set to a low cardinality value representing the stat It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation` and `db.collection.name` are available. -If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. +` .`, provided that `db.operation` and `db.collection.name` are available. +If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. It is not recommended to attempt any client-side parsing of `db.statement` just to get these properties, they should only be used if the library being instrumented already provides them. When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index c04c894ca0..1ef894e18a 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -101,10 +101,10 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `server.port` | `9200` | | `http.request.method` | `"GET"` | | `db.statement` | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | -| `db.operation` | `"search"` | +| `db.operation.name` | `"search"` | | `url.full` | `"https://elasticsearch.mydomain.com:9200/my-index-000001/_search?from=40&size=20"` | | `db.elasticsearch.path_parts.index` | `"my-index-000001"` | | `db.elasticsearch.cluster.name` | `"e9106fc68e3044f0b1475b04bf4ffd5f"` | -| `db.instance.id` | `"instance-0000000001"` | +| `db.instance.id` | `"instance-0000000001"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index de02a0b6ba..8f375ca88b 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -29,8 +29,8 @@ described on this page. ## Example -| Key | Value | -| :---------------------- | :----------------------------------------------------------- | +| Key | Value | +|:------------------------| :----------------------------------------------------------- | | Span name | `"products.findAndModify"` | | `db.system` | `"mongodb"` | | `server.address` | `"mongodb0.example.com"` | @@ -40,7 +40,7 @@ described on this page. | `network.transport` | `"tcp"` | | `db.name` | `"shopDb"` | | `db.statement` | not set | -| `db.operation` | `"findAndModify"` | +| `db.operation.name` | `"findAndModify"` | | `db.mongodb.collection` | `"products"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index 2011dc67e7..6a8e94e057 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -42,7 +42,7 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `network.transport` | `"unix"` | | `db.name` | not set | | `db.statement` | `"HMSET myhash field1 'Hello' field2 'World"` | -| `db.operation` | not set | +| `db.operation.name` | not set | | `db.redis.database_index` | `15` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index 60bf0b8cf8..12d24d3448 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -32,18 +32,18 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex This is an example of attributes for a MySQL database span: -| Key | Value | -|:------------------------| :----------------------------------------------------------- | -| Span name | `"SELECT ShopDb.orders"` | -| `db.system` | `"mysql"` | -| `server.address` | `"shopdb.example.com"` | -| `server.port` | `3306` | -| `network.peer.address` | `"192.0.2.12"` | -| `network.peer.port` | `3306` | -| `network.transport` | `"tcp"` | -| `db.name` | `"ShopDb"` | -| `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | -| `db.operation` | `"SELECT"` | -| `db.collection.name` | `"orders"` | +| Key | Value | +|:-----------------------| :----------------------------------------------------------- | +| Span name | `"SELECT ShopDb.orders"` | +| `db.system` | `"mysql"` | +| `server.address` | `"shopdb.example.com"` | +| `server.port` | `3306` | +| `network.peer.address` | `"192.0.2.12"` | +| `network.peer.port` | `3306` | +| `network.transport` | `"tcp"` | +| `db.name` | `"ShopDb"` | +| `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | +| `db.operation.name` | `"SELECT"` | +| `db.collection.name` | `"orders"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/trace/instrumentation/aws-sdk.yml b/model/trace/instrumentation/aws-sdk.yml index 216f8d1f7f..aac648e688 100644 --- a/model/trace/instrumentation/aws-sdk.yml +++ b/model/trace/instrumentation/aws-sdk.yml @@ -44,7 +44,7 @@ groups: type: span brief: "Attributes that exist for multiple DynamoDB request types." attributes: - - ref: db.operation + - ref: db.operation.name brief: "The same value as `rpc.method`." examples: - GetItem From ccb6db6f3dbc6fdb4c2ec16b0ed8fccd1e783e4b Mon Sep 17 00:00:00 2001 From: Steve Rao Date: Tue, 9 Apr 2024 10:54:58 +0800 Subject: [PATCH 440/482] Update missing modification from `db.operation` to `db.operation.name` (#912) --- docs/database/database-spans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 3a758bf223..d43277f9d5 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -55,7 +55,7 @@ The **span name** SHOULD be set to a low cardinality value representing the stat It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation` and `db.collection.name` are available. +` .`, provided that `db.operation.name` and `db.collection.name` are available. If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. It is not recommended to attempt any client-side parsing of `db.statement` just to get these properties, they should only be used if the library being instrumented already provides them. From f731ca75375c0ad5f65c0121fcce649e59a342e7 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:53:24 +0200 Subject: [PATCH 441/482] Move webengine attributes to the registry (#901) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/webengine.md | 14 ++++++++++++ docs/resource/webengine.md | 6 ++--- model/registry/webengine.yaml | 25 +++++++++++++++++++++ model/resource/webengine.yaml | 24 +++++--------------- 8 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 docs/attributes-registry/webengine.md create mode 100644 model/registry/webengine.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 138ec6c592..850464b1ca 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -64,6 +64,7 @@ body: - area:tls - area:url - area:user-agent + - area:webengine # End semconv area list - type: textarea attributes: diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 117491cb40..69dec212c1 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -57,6 +57,7 @@ body: - area:tls - area:url - area:user-agent + - area:webengine # End semconv area list - type: textarea attributes: diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index f663263c59..aa3679844a 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -66,6 +66,7 @@ body: - area:tls - area:url - area:user-agent + - area:webengine # End semconv area list - type: textarea attributes: diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index c9f832ec74..766e390a94 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -71,5 +71,6 @@ Currently, the following namespaces exist: * [TLS](tls.md) * [URL](url.md) * [User agent](user-agent.md) +* [Webengine](webengine.md) [developers recommendations]: ../general/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/webengine.md b/docs/attributes-registry/webengine.md new file mode 100644 index 0000000000..784d7adc94 --- /dev/null +++ b/docs/attributes-registry/webengine.md @@ -0,0 +1,14 @@ + + +# Webengine + +## Webengine Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `webengine.name` | string | The name of the web engine. | `WildFly` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `webengine.version` | string | The version of the web engine. | `21.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 0f136433ef..4ff192e9b4 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `webengine.name` | string | The name of the web engine. | `WildFly` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `webengine.version` | string | The version of the web engine. | `21.0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.name`](../attributes-registry/webengine.md) | string | The name of the web engine. | `WildFly` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.description`](../attributes-registry/webengine.md) | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.version`](../attributes-registry/webengine.md) | string | The version of the web engine. | `21.0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Information describing the web engine SHOULD be captured using the values acquired from the API provided by the web engine, preferably during runtime, to avoid maintenance burden on engine version upgrades. As an example - Java engines are often but not always packaged as application servers. For Java application servers supporting Servlet API the required information MAY be captured by invoking `ServletContext.getServerInfo()` during runtime and parsing the result. diff --git a/model/registry/webengine.yaml b/model/registry/webengine.yaml new file mode 100644 index 0000000000..a1579b7d24 --- /dev/null +++ b/model/registry/webengine.yaml @@ -0,0 +1,25 @@ +groups: + - id: registry.webengine + prefix: webengine + type: attribute_group + brief: > + This document defines the attributes used to describe the packaged software running the application code. + attributes: + - id: name + type: string + stability: experimental + brief: > + The name of the web engine. + examples: ['WildFly'] + - id: version + type: string + stability: experimental + brief: > + The version of the web engine. + examples: ['21.0.0'] + - id: description + type: string + stability: experimental + brief: > + Additional description of the web engine (e.g. detailed version and edition information). + examples: ['WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'] diff --git a/model/resource/webengine.yaml b/model/resource/webengine.yaml index 10485dcc18..9e8a586b0f 100644 --- a/model/resource/webengine.yaml +++ b/model/resource/webengine.yaml @@ -1,26 +1,12 @@ groups: - id: webengine_resource - prefix: webengine type: resource brief: > Resource describing the packaged software running the application code. Web engines are typically executed using process.runtime. attributes: - - id: name - type: string - stability: experimental + - ref: webengine.name requirement_level: required - brief: > - The name of the web engine. - examples: ['WildFly'] - - id: version - type: string - stability: experimental - brief: > - The version of the web engine. - examples: ['21.0.0'] - - id: description - type: string - stability: experimental - brief: > - Additional description of the web engine (e.g. detailed version and edition information). - examples: ['WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'] + - ref: webengine.version + requirement_level: recommended + - ref: webengine.description + requirement_level: recommended From c9b8445e09de1b4bc17ec4ba259727a83645c076 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Tue, 9 Apr 2024 08:56:23 -0700 Subject: [PATCH 442/482] Add additional process attributes to registry (#564) Co-authored-by: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> --- .chloggen/564.yaml | 22 ++++++++ docs/attributes-registry/process.md | 15 +++++ model/registry/process.yaml | 85 ++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 .chloggen/564.yaml diff --git a/.chloggen/564.yaml b/.chloggen/564.yaml new file mode 100644 index 0000000000..777f5f8b7b --- /dev/null +++ b/.chloggen/564.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: process + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add additional attributes to process attribute registry + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [564] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 280cb7e851..0d0e005b66 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -11,12 +11,27 @@ | `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.creation.time` | string | The date and time the process was created, in ISO 8601 format. | `2023-11-21T09:25:34.853Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.exit.code` | int | The exit code of the process. | `127` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.exit.time` | string | The date and time the process exited, in ISO 8601 format. | `2023-11-21T09:26:12.315Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.group_leader.pid` | int | The PID of the process's group leader. This is also the process group ID (PGID) of the process. | `23` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.interactive` | boolean | Whether the process is connected to an interactive shell. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.owner` | string | The username of the user that owns the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.pid` | int | Process identifier (PID). | `1234` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.real_user.id` | int | The real user ID (RUID) of the process. | `1000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.real_user.name` | string | The username of the real user of the process. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.saved_user.id` | int | The saved user ID (SUID) of the process. | `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.saved_user.name` | string | The username of the saved user. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.session_leader.pid` | int | The PID of the process's session leader. This is also the session ID (SID) of the process. | `14` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.user.id` | int | The effective user ID (EUID) of the process. | `1001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.user.name` | string | The username of the effective user of the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.vpid` | int | Virtual process identifier. [1] | `12` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. diff --git a/model/registry/process.yaml b/model/registry/process.yaml index 4279a9e33a..bccb070551 100644 --- a/model/registry/process.yaml +++ b/model/registry/process.yaml @@ -17,6 +17,30 @@ groups: brief: > Parent Process identifier (PPID). examples: [111] + - id: vpid + type: int + stability: experimental + brief: > + Virtual process identifier. + note: > + The process ID within a PID namespace. This is not necessarily unique + across all processes on the host but it is unique within the process + namespace that the process exists within. + examples: [12] + - id: session_leader.pid + type: int + stability: experimental + brief: > + The PID of the process's session leader. This is also the session ID + (SID) of the process. + examples: [14] + - id: group_leader.pid + type: int + stability: experimental + brief: > + The PID of the process's group leader. This is also the process group + ID (PGID) of the process. + examples: [23] - id: executable.name type: string stability: experimental @@ -65,7 +89,43 @@ groups: stability: experimental brief: > The username of the user that owns the process. - examples: 'root' + examples: ['root'] + - id: user.id + type: int + stability: experimental + brief: > + The effective user ID (EUID) of the process. + examples: [1001] + - id: user.name + type: string + stability: experimental + brief: > + The username of the effective user of the process. + examples: ['root'] + - id: real_user.id + type: int + stability: experimental + brief: > + The real user ID (RUID) of the process. + examples: [1000] + - id: real_user.name + type: string + stability: experimental + brief: > + The username of the real user of the process. + examples: ['operator'] + - id: saved_user.id + type: int + stability: experimental + brief: > + The saved user ID (SUID) of the process. + examples: [1002] + - id: saved_user.name + type: string + stability: experimental + brief: > + The username of the saved user. + examples: ['operator'] - id: runtime.name type: string stability: experimental @@ -87,3 +147,26 @@ groups: An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' + - id: creation.time + type: string + stability: experimental + brief: > + The date and time the process was created, in ISO 8601 format. + examples: ['2023-11-21T09:25:34.853Z'] + - id: exit.time + type: string + stability: experimental + brief: > + The date and time the process exited, in ISO 8601 format. + examples: ['2023-11-21T09:26:12.315Z'] + - id: exit.code + type: int + stability: experimental + brief: > + The exit code of the process. + examples: [127] + - id: interactive + type: boolean + stability: experimental + brief: > + Whether the process is connected to an interactive shell. From 82b2fb2b87b8c90d31dadeac18c3b21ee0c2b7e3 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 9 Apr 2024 09:25:52 -0700 Subject: [PATCH 443/482] Process: replace constraints with requirement levels and note (#863) --- .chloggen/863.yaml | 4 ++++ docs/resource/process.md | 33 +++++++++++++++++++++------------ model/resource/process.yaml | 17 +++++------------ 3 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 .chloggen/863.yaml diff --git a/.chloggen/863.yaml b/.chloggen/863.yaml new file mode 100644 index 0000000000..6dc53c5dcf --- /dev/null +++ b/.chloggen/863.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: process +note: Replace constraints with requirement_level in process attributes. +issues: [ 863 ] diff --git a/docs/resource/process.md b/docs/resource/process.md index aa9ccea63f..8b5c5f9619 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -7,6 +7,7 @@ - [Process](#process) + - [Selecting process attributes](#selecting-process-attributes) - [Process runtimes](#process-runtimes) - [Erlang Runtimes](#erlang-runtimes) - [Go Runtimes](#go-runtimes) @@ -27,32 +28,40 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` See alternative attributes below. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**Additional attribute requirements:** At least one of the following sets of attributes is required: +**[1]:** See [Selecting process attributes](#selecting-process-attributes) for details. + +**[2]:** See [Selecting process attributes](#selecting-process-attributes) for details. + +**[3]:** See [Selecting process attributes](#selecting-process-attributes) for details. + +**[4]:** See [Selecting process attributes](#selecting-process-attributes) for details. + +**[5]:** See [Selecting process attributes](#selecting-process-attributes) for details. + + +### Selecting process attributes + +At least one of the following attributes is required: * [`process.executable.name`](../attributes-registry/process.md) * [`process.executable.path`](../attributes-registry/process.md) * [`process.command`](../attributes-registry/process.md) * [`process.command_line`](../attributes-registry/process.md) * [`process.command_args`](../attributes-registry/process.md) - Between `process.command_args` and `process.command_line`, usually `process.command_args` should be preferred. On Windows and other systems where the native format of process commands is a single string, `process.command_line` can additionally (or instead) be used. -For backwards compatibility with older versions of this semantic convention, -it is possible but deprecated to use an array as type for `process.command_line`. -In that case it MUST be interpreted as if it was `process.command_args`. - ## Process runtimes **type:** `process.runtime` @@ -94,7 +103,7 @@ Go Runtimes SHOULD fill in the as follows: ```go import "runtime" - + func getRuntimeName() string { if runtime.Compiler == "gc" { return "go" diff --git a/model/resource/process.yaml b/model/resource/process.yaml index 61223d61ce..36becc7606 100644 --- a/model/resource/process.yaml +++ b/model/resource/process.yaml @@ -9,27 +9,20 @@ groups: - ref: process.parent_pid - ref: process.executable.name requirement_level: - conditionally_required: See alternative attributes below. + conditionally_required: See [Selecting process attributes](#selecting-process-attributes) for details. - ref: process.executable.path requirement_level: - conditionally_required: See alternative attributes below. + conditionally_required: See [Selecting process attributes](#selecting-process-attributes) for details. - ref: process.command requirement_level: - conditionally_required: See alternative attributes below. + conditionally_required: See [Selecting process attributes](#selecting-process-attributes) for details. - ref: process.command_line requirement_level: - conditionally_required: See alternative attributes below. + conditionally_required: See [Selecting process attributes](#selecting-process-attributes) for details. - ref: process.command_args requirement_level: - conditionally_required: See alternative attributes below. + conditionally_required: See [Selecting process attributes](#selecting-process-attributes) for details. - ref: process.owner - constraints: - - any_of: - - process.executable.name - - process.executable.path - - process.command - - process.command_line - - process.command_args - id: process.runtime prefix: process.runtime From 51813f68cabbf07bc0f1c3a30471d2cb65b0417c Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:06:05 +0200 Subject: [PATCH 444/482] [chore] move event to registry (#907) Co-authored-by: Alexander Wert Co-authored-by: Liudmila Molkova --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/event.md | 15 +++++++++++++++ docs/general/events.md | 2 +- model/logs/events.yaml | 13 +------------ model/registry/event.yaml | 18 ++++++++++++++++++ 8 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 docs/attributes-registry/event.md create mode 100644 model/registry/event.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 850464b1ca..2639c99423 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -35,6 +35,7 @@ body: - area:dns - area:enduser - area:error + - area:event - area:exception - area:faas - area:feature-flag diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 69dec212c1..46733b2f73 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -28,6 +28,7 @@ body: - area:dns - area:enduser - area:error + - area:event - area:exception - area:faas - area:feature-flag diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index aa3679844a..a89d94a13e 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -37,6 +37,7 @@ body: - area:dns - area:enduser - area:error + - area:event - area:exception - area:faas - area:feature-flag diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 766e390a94..4669206415 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -43,6 +43,7 @@ Currently, the following namespaces exist: * [Disk](disk.md) * [End user](enduser.md) * [Error](error.md) +* [Event](event.md) * [Exception](exception.md) * [FaaS](faas.md) * [Feature Flag](feature-flag.md) diff --git a/docs/attributes-registry/event.md b/docs/attributes-registry/event.md new file mode 100644 index 0000000000..c377cf5068 --- /dev/null +++ b/docs/attributes-registry/event.md @@ -0,0 +1,15 @@ + + +# Event + +## Event Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. + diff --git a/docs/general/events.md b/docs/general/events.md index 73668bb423..1cf9f33abb 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -55,7 +55,7 @@ that identify the class of Events but not the instance of the Event. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`event.name`](../attributes-registry/event.md) | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. diff --git a/model/logs/events.yaml b/model/logs/events.yaml index 1576901054..b07e25a8df 100644 --- a/model/logs/events.yaml +++ b/model/logs/events.yaml @@ -1,19 +1,8 @@ groups: - id: event type: attribute_group - prefix: event brief: > This document defines attributes for Events represented using Log Records. attributes: - - id: name - type: string - stability: experimental + - ref: event.name requirement_level: required - brief: > - Identifies the class / type of event. - note: > - Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). - Notably, event names are namespaced to avoid collisions and provide a clean - separation of semantics for events in separate domains like browser, mobile, and - kubernetes. - examples: ['browser.mouse.click', 'device.app.lifecycle'] diff --git a/model/registry/event.yaml b/model/registry/event.yaml new file mode 100644 index 0000000000..aa69709b69 --- /dev/null +++ b/model/registry/event.yaml @@ -0,0 +1,18 @@ +groups: + - id: registry.event + prefix: event + type: attribute_group + brief: > + Attributes for Events represented using Log Records. + attributes: + - id: name + type: string + stability: experimental + brief: > + Identifies the class / type of event. + note: > + Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). + Notably, event names are namespaced to avoid collisions and provide a clean + separation of semantics for events in separate domains like browser, mobile, and + kubernetes. + examples: ['browser.mouse.click', 'device.app.lifecycle'] From 768a23c3627e4bd96146d9f713db214bee7aecf3 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Wed, 10 Apr 2024 09:57:09 +0200 Subject: [PATCH 445/482] [chore] Move otel.* attributes to registry (#891) --- docs/attributes-registry/otel.md | 21 +++++++++++++++++++-- model/registry/otel.yaml | 24 ++++++++++++++++++++++++ model/trace/exporter/exporter.yaml | 24 ++++-------------------- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/docs/attributes-registry/otel.md b/docs/attributes-registry/otel.md index 92c94105c5..a064129e90 100644 --- a/docs/attributes-registry/otel.md +++ b/docs/attributes-registry/otel.md @@ -5,12 +5,29 @@ -- [OpenTelemetry Attributes](#opentelemetry-attributes) +- [General Attributes](#general-attributes) +- [Scope Attributes](#scope-attributes) - [Deprecated OpenTelemetry Attributes](#deprecated-opentelemetry-attributes) -## OpenTelemetry Attributes +## General Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`otel.status_code` 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 | Stability | +|---|---|---| +| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ERROR` | The operation contains an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + +## Scope Attributes | Attribute | Type | Description | Examples | Stability | diff --git a/model/registry/otel.yaml b/model/registry/otel.yaml index 1fa7f0da45..7da6ece282 100644 --- a/model/registry/otel.yaml +++ b/model/registry/otel.yaml @@ -1,4 +1,28 @@ groups: + - id: registry.otel + prefix: otel + type: attribute_group + brief: Attributes reserved for OpenTelemetry + attributes: + - id: status_code + type: + allow_custom_values: true + members: + - id: ok + value: OK + brief: 'The operation has been validated by an Application developer or Operator to have completed successfully.' + stability: stable + - id: error + value: ERROR + brief: 'The operation contains an error.' + stability: stable + brief: Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + stability: stable + - id: status_description + type: string + brief: "Description of the Status if it has a value, otherwise not set." + examples: ['resource not found'] + stability: stable - id: registry.otel.scope prefix: otel.scope type: resource diff --git a/model/trace/exporter/exporter.yaml b/model/trace/exporter/exporter.yaml index 124c5da191..0c4e8c6a8f 100644 --- a/model/trace/exporter/exporter.yaml +++ b/model/trace/exporter/exporter.yaml @@ -1,25 +1,9 @@ groups: - id: otel_span - prefix: otel type: span brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Span's concepts. attributes: - - id: status_code - type: - allow_custom_values: false - members: - - id: ok - value: OK - brief: 'The operation has been validated by an Application developer or Operator to have completed successfully.' - stability: experimental - - id: error - value: ERROR - brief: 'The operation contains an error.' - stability: experimental - brief: Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. - stability: stable - - id: status_description - type: string - brief: "Description of the Status if it has a value, otherwise not set." - examples: ['resource not found'] - stability: stable + - ref: otel.status_code + requirement_level: recommended + - ref: otel.status_description + requirement_level: recommended From 91d267081fe036180a6ef5a62eb3637017be8778 Mon Sep 17 00:00:00 2001 From: ET Date: Sat, 13 Apr 2024 13:37:38 +1200 Subject: [PATCH 446/482] [chore] Fix typo in container attributes registry (#920) --- docs/attributes-registry/container.md | 2 +- docs/resource/container.md | 2 +- model/registry/container.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index d3d41467db..2459f17e24 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -32,7 +32,7 @@ **[2]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. -The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. +The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. **[3]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. diff --git a/docs/resource/container.md b/docs/resource/container.md index b33f646058..f119a180d1 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -24,7 +24,7 @@ **[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. -The ID is assinged by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. +The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. **[2]:** [Docker](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. diff --git a/model/registry/container.yaml b/model/registry/container.yaml index e04514e57a..b2ff38239f 100644 --- a/model/registry/container.yaml +++ b/model/registry/container.yaml @@ -53,7 +53,7 @@ groups: K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. - The ID is assinged by the container runtime and can vary in different environments. + The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. examples: ['sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f'] From 677ab9e3797dff8dfa4bab9db88c4b15345dc226 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 15 Apr 2024 17:36:22 +0200 Subject: [PATCH 447/482] add missing link to messaging metrics (#924) --- docs/general/metrics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/general/metrics.md b/docs/general/metrics.md index 0e8e656c8c..fb96d14606 100644 --- a/docs/general/metrics.md +++ b/docs/general/metrics.md @@ -31,6 +31,7 @@ The following semantic conventions surrounding metrics are defined: * [Database](/docs/database/database-metrics.md): For SQL and NoSQL client metrics. * [FaaS](/docs/faas/faas-metrics.md): For [Function as a Service](https://wikipedia.org/wiki/Function_as_a_service) metrics. * [HTTP](/docs/http/http-metrics.md): For HTTP client and server metrics. +* [Messaging](/docs/messaging/messaging-metrics.md): For messaging systems (queues, publish/subscribe, etc.) metrics. * [RPC](/docs/rpc/rpc-metrics.md): For RPC client and server metrics. * **System metrics** * [System](/docs/system/system-metrics.md): For standard system metrics. From f12a4d38337f0b42f119b646827323669da078fb Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 16 Apr 2024 23:12:31 +0200 Subject: [PATCH 448/482] BREAKING: Rename `messaging.operation` to `messaging.operation.name` (#913) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/890.yaml | 4 ++ docs/attributes-registry/messaging.md | 8 ++-- docs/messaging/azure-messaging.md | 18 --------- docs/messaging/gcp-pubsub.md | 2 +- docs/messaging/kafka.md | 4 +- docs/messaging/messaging-spans.md | 48 ++++++++++++++---------- model/registry/deprecated/messaging.yaml | 9 ++++- model/registry/messaging.yaml | 11 +++++- model/trace/messaging.yaml | 5 ++- schema-next.yaml | 4 ++ 10 files changed, 65 insertions(+), 48 deletions(-) create mode 100644 .chloggen/890.yaml diff --git a/.chloggen/890.yaml b/.chloggen/890.yaml new file mode 100644 index 0000000000..4c3e5ce030 --- /dev/null +++ b/.chloggen/890.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: messaging +note: Rename `messaging.operation` to `messaging.operation.type`, add `messaging.operation.name`. +issues: [ 890 ] diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index ba7f61aec3..7e83f76a3c 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -34,7 +34,8 @@ | `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.operation` | string | A string identifying the kind of messaging operation. [7] | `publish` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.operation.name` | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.operation.type` | string | A string identifying the type of the messaging operation. [7] | `publish` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -55,7 +56,7 @@ size should be used. **[7]:** If a custom value is used, it MUST be of low cardinality. -`messaging.operation` 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. +`messaging.operation.type` 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 | Stability | |---|---|---| @@ -177,5 +178,6 @@ size should be used. | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `messaging.kafka.destination.partition` | int | "Deprecated, use `messaging.destination.partition.id` instead." | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | +| `messaging.kafka.destination.partition` | int | Deprecated, use `messaging.destination.partition.id` instead. | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | +| `messaging.operation` | string | Deprecated, use `messaging.operation.type` instead. | `publish`; `create`; `process` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.operation.type`. | \ No newline at end of file diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index ad68bdf0c5..8028640677 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -12,15 +12,6 @@ The Semantic Conventions for [Azure Service Bus](https://learn.microsoft.com/azu `messaging.system` MUST be set to `"servicebus"`. -### Span names - -The span name SHOULD follow [the general messaging span name pattern](../messaging/azure-messaging.md): it SHOULD start with the messaging destination name (Event Hubs queue or topic name) and contain a low-cardinality name of the operation the span describes: - -- Spans names for `settle` operations SHOULD follow the ` {messaging.servicebus.disposition_status}` pattern. - For example, `my-queue complete` or `my-queue abandon`. -- Spans names for `publish` operations SHOULD follow the ` send` pattern. -- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. - ### Span attributes The following additional attributes are defined: @@ -39,15 +30,6 @@ The following additional attributes are defined: `messaging.system` MUST be set to `"eventhubs"`. -### Span names - -The span name SHOULD follow the [general messaging span name pattern](../messaging/azure-messaging.md): it SHOULD start with the messaging destination name (Event Hubs namespace) and -contain a low-cardinality name of an operation the span describes: - -- Spans for `settle` operations SHOULD follow the ` checkpoint` pattern (matching Event Hubs terminology). -- Spans names for `publish` operations SHOULD follow the ` send` pattern. -- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. - ### Span attributes The following additional attributes are defined: diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index d1a7274b1b..b586668d69 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -53,7 +53,7 @@ flowchart LR; | Status | `Ok` | `Ok` | `Ok` | | `messaging.batch.message_count` | | | 2 | | `messaging.destination.name` | `"T"` | `"T"` | `"T"` | -| `messaging.operation` | `"create"` | `"create"` | `"publish"` | +| `messaging.operation.type` | `"create"` | `"create"` | `"publish"` | | `messaging.message.id` | `"a1"` | `"a2"` | | | `messaging.message.envelope.size` | `1` | `1` | | | `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 88beccf2d4..5002947f9e 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -53,7 +53,7 @@ One process, CA, receives the message and publishes a new message to a topic T2 Frameworks such as Quarkus and Spring Boot separate processing of a received message from producing subsequent messages out. For this reason, receiving (Span Rcv1) is the parent of both processing (Span Proc1) and producing a new message (Span Prod2). -The span representing message receiving (Span Rcv1) should not set `messaging.operation` to `receive`, +The span representing message receiving (Span Rcv1) should not set `messaging.operation.type` to `receive`, as it does not only receive the message but also converts the input message to something suitable for the processing operation to consume and creates the output message from the result of processing. ``` @@ -77,7 +77,7 @@ Process CB: | Span Rcv2 | | `service.name` | | `"myConsumer1"` | `"myConsumer1"` | | `"myConsumer2"` | | `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | | `messaging.destination.name` | `"T1"` | `"T1"` | `"T1"` | `"T2"` | `"T2"` | -| `messaging.operation` | | | `"process"` | | `"receive"` | +| `messaging.operation.type` | | | `"process"` | | `"receive"` | | `messaging.client_id` | | `"5"` | `"5"` | `"5"` | `"8"` | | `messaging.kafka.message.key` | `"myKey"` | `"myKey"` | `"myKey"` | `"anotherKey"` | `"anotherKey"` | | `messaging.kafka.consumer.group` | | `"my-group"` | `"my-group"` | | `"another-group"` | diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index cfae7e750b..4b4f450e5c 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -18,7 +18,7 @@ - [Conventions](#conventions) - [Context propagation](#context-propagation) - [Span name](#span-name) - - [Operation names](#operation-names) + - [Operation types](#operation-types) - [Span kind](#span-kind) - [Trace structure](#trace-structure) - [Producer spans](#producer-spans) @@ -153,37 +153,42 @@ in such a way that it cannot be changed by intermediaries. ### Span name -The span name SHOULD be set to the message destination name and the operation being performed in the following format: +The span name SHOULD be set to the message destination name and the name of the operation being performed (as captured in [`messaging.operation.name`](../attributes-registry/messaging.md)) in the following format: ``` ``` +If the operation name is not specified by the messaging system, then the operation type as defined in [Operation types](#operation-types) SHOULD be used: + +``` + +``` + The destination name SHOULD only be used for the span name if it is known to be of low cardinality (cf. [general span name guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#span)). This can be assumed if it is statically derived from application code or configuration. Wherever possible, the real destination names after resolving logical or aliased names SHOULD be used. If the destination name is dynamic, such as a [conversation ID](#conversations) or a value obtained from a `Reply-To` header, it SHOULD NOT be used for the span name. In these cases, an artificial destination name that best expresses the destination, or a generic, static fallback like `"(anonymous)"` for [anonymous destinations](#temporary-and-anonymous-destinations) SHOULD be used instead. -The values allowed for `` are defined in the section [Operation names](#operation-names) below. - Examples: * `shop.orders publish` -* `shop.orders receive` +* `shop.orders subscribe` * `shop.orders settle` * `print_jobs publish` +* `print_jobs nack` * `topic with spaces process` * `AuthenticationRequest-Conversations settle` -* `(anonymous) publish` (`(anonymous)` being a stable identifier for an unnamed destination) +* `(anonymous) send` (`(anonymous)` being a stable identifier for an unnamed destination) Messaging system specific adaptions to span naming MUST be documented in [semantic conventions for specific messaging technologies](#semantic-conventions-for-specific-messaging-technologies). -### Operation names +### Operation types -The following operations related to messages are defined for these semantic conventions: +The following operation types related to messages are defined for these semantic conventions: -| Operation name | Description | +| Operation type | Description | | -------------- | ----------- | | `create` | A message is created or passed to a client library for publishing. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | @@ -194,9 +199,9 @@ The following operations related to messages are defined for these semantic conv ### Span kind [Span kinds](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#spankind) -SHOULD be set according to the following table, based on the operation a span describes. +SHOULD be set according to the following table, based on the operation type a span describes. -| Operation name | Span kind| +| Operation type | Span kind| |----------------|-------------| | `create` | `PRODUCER` | | `publish` | `PRODUCER` if the context of the "Publish" span is used as creation context. | @@ -281,7 +286,7 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.operation`](../attributes-registry/messaging.md) | string | A string identifying the kind of messaging operation. [1] | `publish` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.type`](../attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -296,9 +301,10 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.operation.name`](../attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. @@ -345,13 +351,15 @@ body size should be used. **[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[16]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[17]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -`messaging.operation` 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. +`messaging.operation.type` 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 | Stability | |---|---|---| @@ -469,7 +477,7 @@ flowchart LR; | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"rabbitmq"` | `"rabbitmq"` | `"rabbitmq"` | | `messaging.destination.name` | `"T"` | `"T"` | `"T"` | -| `messaging.operation` | `"publish"` | `"process"` | `"process"` | +| `messaging.operation.type` | `"publish"` | `"process"` | `"process"` | | `messaging.message.id` | `"a"` | `"a"`| `"a"` | ### Batch receiving @@ -507,7 +515,7 @@ flowchart LR; | `server.port` | `1234` | `1234` | `1234` | | `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | | `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | -| `messaging.operation` | `"publish"` | `"publish"` | `"receive"` | +| `messaging.operation.type` | `"publish"` | `"publish"` | `"receive"` | | `messaging.message.id` | `"a1"` | `"a2"` | | | `messaging.batch.message_count` | | | 2 | @@ -552,7 +560,7 @@ flowchart LR; | `server.port` | `1234` | `1234` | `1234` | `1234` | `1234` | | `messaging.system` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | `"kafka"` | | `messaging.destination.name` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | `"Q"` | -| `messaging.operation` | `"create"` | `"create"` | `"publish"` | `"receive"` | `"receive"` | +| `messaging.operation.type` | `"create"` | `"create"` | `"publish"` | `"receive"` | `"receive"` | | `messaging.message.id` | `"a1"` | `"a2"` | | `"a1"` | `"a2"` | | `messaging.batch.message_count` | | | 2 | | | diff --git a/model/registry/deprecated/messaging.yaml b/model/registry/deprecated/messaging.yaml index a2675c7c47..4f27d8e09a 100644 --- a/model/registry/deprecated/messaging.yaml +++ b/model/registry/deprecated/messaging.yaml @@ -6,7 +6,14 @@ groups: - id: messaging.kafka.destination.partition type: int brief: > - "Deprecated, use `messaging.destination.partition.id` instead." + Deprecated, use `messaging.destination.partition.id` instead. examples: 2 deprecated: "Replaced by `messaging.destination.partition.id`." stability: experimental + - id: messaging.operation + type: string + stability: experimental + brief: > + Deprecated, use `messaging.operation.type` instead. + examples: ["publish", "create", "process"] + deprecated: "Replaced by `messaging.operation.type`." diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 4938ddd045..32e603d1dc 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -139,7 +139,7 @@ groups: body size should be used. examples: 1439 tag: messaging-generic - - id: operation + - id: operation.type type: allow_custom_values: true members: @@ -173,9 +173,16 @@ groups: stability: experimental stability: experimental brief: > - A string identifying the kind of messaging operation. + A string identifying the type of the messaging operation. note: If a custom value is used, it MUST be of low cardinality. tag: messaging-generic + - id: operation.name + type: string + stability: experimental + brief: > + The system-specific name of the messaging operation. + examples: [ "ack", "nack", "send" ] + tag: messaging-generic - id: rabbitmq.destination.routing_key type: string stability: experimental diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index 2c669cce82..f12a96b1df 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -54,8 +54,11 @@ groups: messaging systems. extends: messaging.attributes.common attributes: - - ref: messaging.operation + - ref: messaging.operation.type requirement_level: required + - ref: messaging.operation.name + requirement_level: + recommended: If the operation is not sufficiently described by `messaging.operation.type`. - ref: messaging.batch.message_count requirement_level: conditionally_required: If the span describes an operation on a batch of messages. diff --git a/schema-next.yaml b/schema-next.yaml index b893a50d4e..430901253a 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -21,6 +21,10 @@ versions: - rename_attributes: attribute_map: db.operation: db.operation.name + # https://github.com/open-telemetry/semantic-conventions/pull/913 + - rename_attributes: + attribute_map: + messaging.operation: messaging.operation.type # https://github.com/open-telemetry/semantic-conventions/pull/866 - rename_attributes: attribute_map: From 1c93c94ce6f1aafc3e40ba645084370626dcdfb8 Mon Sep 17 00:00:00 2001 From: Nir Gazit Date: Tue, 16 Apr 2024 16:04:32 -0700 Subject: [PATCH 449/482] LLM Semantic Conventions: Initial PR (#825) Co-authored-by: Drew Robbins Co-authored-by: Drew Robbins Co-authored-by: Liudmila Molkova Co-authored-by: Phillip Carter Co-authored-by: Patrice Chalin --- .chloggen/first-gen-ai.yaml | 22 ++++++ .github/CODEOWNERS | 7 ++ .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/README.md | 1 + docs/attributes-registry/llm.md | 59 ++++++++++++++ docs/gen-ai/README.md | 25 ++++++ docs/gen-ai/llm-spans.md | 84 ++++++++++++++++++++ model/registry/gen-ai.yaml | 87 +++++++++++++++++++++ model/trace/gen-ai.yaml | 68 ++++++++++++++++ 11 files changed, 356 insertions(+) create mode 100755 .chloggen/first-gen-ai.yaml create mode 100644 docs/attributes-registry/llm.md create mode 100644 docs/gen-ai/README.md create mode 100644 docs/gen-ai/llm-spans.md create mode 100644 model/registry/gen-ai.yaml create mode 100644 model/trace/gen-ai.yaml diff --git a/.chloggen/first-gen-ai.yaml b/.chloggen/first-gen-ai.yaml new file mode 100755 index 0000000000..62dec0d56e --- /dev/null +++ b/.chloggen/first-gen-ai.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: new_component + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: gen-ai + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Introducing semantic conventions for GenAI clients. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [327] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3556a7bbe4..185fedbfdb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -78,4 +78,11 @@ /model/metrics/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers /docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +# Gen-AI semantic conventions approvers +/model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/trace/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/docs/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/docs/attributes-registry/llm.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers + # TODO - Add semconv area experts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 2639c99423..1385c47095 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -41,6 +41,7 @@ body: - area:feature-flag - area:file - area:gcp + - area:gen-ai - area:graphql - area:heroku - area:host diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 46733b2f73..2ca1722167 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -34,6 +34,7 @@ body: - area:feature-flag - area:file - area:gcp + - area:gen-ai - area:graphql - area:heroku - area:host diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index a89d94a13e..7c661db388 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -43,6 +43,7 @@ body: - area:feature-flag - area:file - area:gcp + - area:gen-ai - area:graphql - area:heroku - area:host diff --git a/docs/README.md b/docs/README.md index 1dfe42baf3..27c2c200a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,7 @@ Semantic Conventions are defined for the following areas: * [Exceptions](exceptions/README.md): Semantic Conventions for exceptions. * [FaaS](faas/README.md): Semantic Conventions for Function as a Service (FaaS) operations. * [Feature Flags](feature-flags/README.md): Semantic Conventions for feature flag evaluations. +* [Generative AI](gen-ai/README.md): Semantic Conventions for generative AI (LLM, etc.) operations. * [GraphQL](graphql/graphql-spans.md): Semantic Conventions for GraphQL implementations. * [HTTP](http/README.md): Semantic Conventions for HTTP client and server operations. * [Messaging](messaging/README.md): Semantic Conventions for messaging operations and systems. diff --git a/docs/attributes-registry/llm.md b/docs/attributes-registry/llm.md new file mode 100644 index 0000000000..9a20ed6199 --- /dev/null +++ b/docs/attributes-registry/llm.md @@ -0,0 +1,59 @@ + + +# Large Language Model + + + +- [Generic LLM Attributes](#generic-llm-attributes) + - [Request Attributes](#request-attributes) + - [Response Attributes](#response-attributes) + - [Event Attributes](#event-attributes) + + + +## Generic LLM Attributes + +### Request Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gen_ai.request.max_tokens` | int | The maximum number of tokens the LLM generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.model` | string | The name of the LLM a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.temperature` | double | The temperature setting for the LLM request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.top_p` | double | The top_p sampling setting for the LLM request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.system` | string | The name of the LLM foundation model vendor. | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`gen_ai.system` 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 | Stability | +|---|---|---| +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### Response Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `[stop]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.model` | string | The name of the LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### Event Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `gen_ai.completion` | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.prompt` | string | The full prompt sent to an LLM. [2] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + +**[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + \ No newline at end of file diff --git a/docs/gen-ai/README.md b/docs/gen-ai/README.md new file mode 100644 index 0000000000..1197a88522 --- /dev/null +++ b/docs/gen-ai/README.md @@ -0,0 +1,25 @@ + + +# Semantic Conventions for Generative AI systems + +**Status**: [Experimental][DocumentStatus] + +**Warning**: +The semantic conventions for GenAI and LLM are currently in development. +We encourage instrumentation libraries and telemetry consumers developers to +use the conventions in limited non-critical workloads and share the feedback + +This document defines semantic conventions for the following kind of Generative AI systems: + +* LLMs + +Semantic conventions for LLM operations are defined for the following signals: + +* [LLM Spans](llm-spans.md): Semantic Conventions for LLM requests - *spans*. + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/gen-ai/llm-spans.md b/docs/gen-ai/llm-spans.md new file mode 100644 index 0000000000..80d4176edf --- /dev/null +++ b/docs/gen-ai/llm-spans.md @@ -0,0 +1,84 @@ + + +# Semantic Conventions for LLM requests + +**Status**: [Experimental][DocumentStatus] + + + + + +- [Configuration](#configuration) +- [LLM Request attributes](#llm-request-attributes) +- [Events](#events) + + + +A request to an LLM is modeled as a span in a trace. + +**Span kind:** MUST always be `CLIENT`. + +The **span name** SHOULD be set to a low cardinality value describing an operation made to an LLM. +For example, the API name such as [Create chat completion](https://platform.openai.com/docs/api-reference/chat/create) could be represented as `ChatCompletions gpt-4` to include the API and the LLM. + +## Configuration + +Instrumentations for LLMs MAY capture prompts and completions. +Instrumentations that support it, MUST offer the ability to turn off capture of prompts and completions. This is for three primary reasons: + +1. Data privacy concerns. End users of LLM applications may input sensitive information or personally identifiable information (PII) that they do not wish to be sent to a telemetry backend. +2. Data size concerns. Although there is no specified limit to sizes, there are practical limitations in programming languages and telemetry systems. Some LLMs allow for extremely large context windows that end users may take full advantage of. +3. Performance concerns. Sending large amounts of data to a telemetry backend may cause performance issues for the application. + +## LLM Request attributes + +These attributes track input data and metadata for a request to an LLM. Each attribute represents a concept that is common to most LLMs. + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gen_ai.request.model`](../attributes-registry/llm.md) | string | The name of the LLM a request is being made to. [1] | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](../attributes-registry/llm.md) | string | The name of the LLM foundation model vendor. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.max_tokens`](../attributes-registry/llm.md) | int | The maximum number of tokens the LLM generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.temperature`](../attributes-registry/llm.md) | double | The temperature setting for the LLM request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.top_p`](../attributes-registry/llm.md) | double | The top_p sampling setting for the LLM request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.finish_reasons`](../attributes-registry/llm.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `[stop]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.id`](../attributes-registry/llm.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.model`](../attributes-registry/llm.md) | string | The name of the LLM a response was generated from. [3] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.completion_tokens`](../attributes-registry/llm.md) | int | The number of tokens used in the LLM response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.prompt_tokens`](../attributes-registry/llm.md) | int | The number of tokens used in the LLM prompt. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The name of the LLM a request is being made to. If the LLM is supplied by a vendor, then the value must be the exact name of the model requested. If the LLM is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. + +**[2]:** If not using a vendor-supplied model, provide a custom friendly name, such as a name of the company or project. If the instrumetnation reports any attributes specific to a custom model, the value provided in the `gen_ai.system` SHOULD match the custom attribute namespace segment. For example, if `gen_ai.system` is set to `the_best_llm`, custom attributes should be added in the `gen_ai.the_best_llm.*` namespace. If none of above options apply, the instrumentation should set `_OTHER`. + +**[3]:** If available. The name of the LLM serving a response. If the LLM is supplied by a vendor, then the value must be the exact name of the model actually used. If the LLM is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. + + +## Events + +In the lifetime of an LLM span, an event for prompts sent and completions received MAY be created, depending on the configuration of the instrumentation. + + +The event name MUST be `gen_ai.content.prompt`. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gen_ai.prompt`](../attributes-registry/llm.md) | string | The full prompt sent to an LLM. [1] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + + + +The event name MUST be `gen_ai.content.completion`. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gen_ai.completion`](../attributes-registry/llm.md) | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/registry/gen-ai.yaml b/model/registry/gen-ai.yaml new file mode 100644 index 0000000000..100523a3b8 --- /dev/null +++ b/model/registry/gen-ai.yaml @@ -0,0 +1,87 @@ +groups: + - id: registry.gen_ai + prefix: gen_ai + type: attribute_group + brief: > + This document defines the attributes used to describe telemetry in the context of LLM (Large Language Models) requests and responses. + attributes: + - id: system + stability: experimental + type: + allow_custom_values: true + members: + - id: openai + stability: experimental + value: "openai" + brief: 'OpenAI' + brief: The name of the LLM foundation model vendor. + examples: 'openai' + tag: llm-generic-request + - id: request.model + stability: experimental + type: string + brief: The name of the LLM a request is being made to. + examples: 'gpt-4' + tag: llm-generic-request + - id: request.max_tokens + stability: experimental + type: int + brief: The maximum number of tokens the LLM generates for a request. + examples: [100] + tag: llm-generic-request + - id: request.temperature + stability: experimental + type: double + brief: The temperature setting for the LLM request. + examples: [0.0] + tag: llm-generic-request + - id: request.top_p + stability: experimental + type: double + brief: The top_p sampling setting for the LLM request. + examples: [1.0] + tag: llm-generic-request + - id: response.id + stability: experimental + type: string + brief: The unique identifier for the completion. + examples: ['chatcmpl-123'] + tag: llm-generic-response + - id: response.model + stability: experimental + type: string + brief: The name of the LLM a response was generated from. + examples: ['gpt-4-0613'] + tag: llm-generic-response + - id: response.finish_reasons + stability: experimental + type: string[] + brief: Array of reasons the model stopped generating tokens, corresponding to each generation received. + examples: ['stop'] + tag: llm-generic-response + - id: usage.prompt_tokens + stability: experimental + type: int + brief: The number of tokens used in the LLM prompt. + examples: [100] + tag: llm-generic-response + - id: usage.completion_tokens + stability: experimental + type: int + brief: The number of tokens used in the LLM response (completion). + examples: [180] + tag: llm-generic-response + - id: prompt + stability: experimental + type: string + brief: The full prompt sent to an LLM. + note: It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + examples: ["[{'role': 'user', 'content': 'What is the capital of France?'}]"] + tag: llm-generic-events + - id: completion + stability: experimental + type: string + brief: The full response received from the LLM. + note: It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + examples: ["[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]"] + tag: llm-generic-events diff --git a/model/trace/gen-ai.yaml b/model/trace/gen-ai.yaml new file mode 100644 index 0000000000..bf1d112e37 --- /dev/null +++ b/model/trace/gen-ai.yaml @@ -0,0 +1,68 @@ +groups: + - id: gen_ai.request + type: span + brief: > + A request to an LLM is modeled as a span in a trace. The span name should be a low cardinality value representing the request made to an LLM, like the name of the API endpoint being called. + attributes: + - ref: gen_ai.system + requirement_level: required + note: > + If not using a vendor-supplied model, provide a custom friendly name, such as a name of the company or project. + If the instrumetnation reports any attributes specific to a custom model, the value provided in the `gen_ai.system` SHOULD match the custom attribute namespace segment. + For example, if `gen_ai.system` is set to `the_best_llm`, custom attributes should be added in the `gen_ai.the_best_llm.*` namespace. + If none of above options apply, the instrumentation should set `_OTHER`. + - ref: gen_ai.request.model + requirement_level: required + note: > + The name of the LLM a request is being made to. If the LLM is supplied by a vendor, + then the value must be the exact name of the model requested. If the LLM is a fine-tuned + custom model, the value should have a more specific name than the base model that's been fine-tuned. + - ref: gen_ai.request.max_tokens + requirement_level: recommended + - ref: gen_ai.request.temperature + requirement_level: recommended + - ref: gen_ai.request.top_p + requirement_level: recommended + - ref: gen_ai.response.id + requirement_level: recommended + - ref: gen_ai.response.model + requirement_level: recommended + note: > + If available. The name of the LLM serving a response. If the LLM is supplied by a vendor, + then the value must be the exact name of the model actually used. If the LLM is a + fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. + - ref: gen_ai.response.finish_reasons + requirement_level: recommended + - ref: gen_ai.usage.prompt_tokens + requirement_level: recommended + - ref: gen_ai.usage.completion_tokens + requirement_level: recommended + events: + - gen_ai.content.prompt + - gen_ai.content.completion + + - id: gen_ai.content.prompt + name: gen_ai.content.prompt + type: event + brief: > + In the lifetime of an LLM span, events for prompts sent and completions received + may be created, depending on the configuration of the instrumentation. + attributes: + - ref: gen_ai.prompt + requirement_level: + conditionally_required: if and only if corresponding event is enabled + note: > + It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + + - id: gen_ai.content.completion + name: gen_ai.content.completion + type: event + brief: > + In the lifetime of an LLM span, events for prompts sent and completions received + may be created, depending on the configuration of the instrumentation. + attributes: + - ref: gen_ai.completion + requirement_level: + conditionally_required: if and only if corresponding event is enabled + note: > + It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) From 4728f6374361ad82949eecdfccb67759f9f2535c Mon Sep 17 00:00:00 2001 From: Gergely Kalapos Date: Wed, 17 Apr 2024 11:44:09 +0200 Subject: [PATCH 450/482] [chore] Move system metric attributes to the registry (#867) Co-authored-by: Chris Mark Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/system.md | 178 +++++++++++++ docs/system/container-metrics.md | 4 +- docs/system/system-metrics.md | 68 ++--- model/metrics/system-metrics.yaml | 277 +------------------- model/registry/system.yaml | 255 ++++++++++++++++++ 8 files changed, 484 insertions(+), 301 deletions(-) create mode 100644 docs/attributes-registry/system.md create mode 100644 model/registry/system.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1385c47095..bb5ede00e1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -61,6 +61,7 @@ body: - area:service - area:session - area:source + - area:system - area:telemetry - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 2ca1722167..53520602e3 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -54,6 +54,7 @@ body: - area:service - area:session - area:source + - area:system - area:telemetry - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 7c661db388..0e79351f21 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -63,6 +63,7 @@ body: - area:service - area:session - area:source + - area:system - area:telemetry - area:thread - area:tls diff --git a/docs/attributes-registry/system.md b/docs/attributes-registry/system.md new file mode 100644 index 0000000000..9760a9ee6b --- /dev/null +++ b/docs/attributes-registry/system.md @@ -0,0 +1,178 @@ +# System + + + +- [CPU attributes](#cpu-attributes) +- [Memory attributes](#memory-attributes) +- [Paging attributes](#paging-attributes) +- [Filesystem attributes](#filesystem-attributes) +- [Network attributes](#network-attributes) +- [Process attributes](#process-attributes) +- [Deprecated System Attributes](#deprecated-system-attributes) + + + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.device` | string | The device identifier | `(identifier)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## CPU attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.cpu.state` 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 | Stability | +|---|---|---| +| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Memory attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.memory.state` | string | The memory state | `free`; `cached` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.memory.state` 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 | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Paging attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.paging.direction` | string | The paging access direction | `in` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.paging.state` | string | The memory paging state | `free` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.paging.type` | string | The memory paging type | `minor` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.direction` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `in` | in | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out` | out | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.type` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Filesystem attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.state` | string | The filesystem state | `used` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.type` | string | The filesystem type | `ext4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.filesystem.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `reserved` | reserved | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.filesystem.type` 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 | Stability | +|---|---|---| +| `fat32` | fat32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `exfat` | exfat | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ntfs` | ntfs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `refs` | refs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hfsplus` | hfsplus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ext4` | ext4 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Network attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.network.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `close` | close | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `close_wait` | close_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `closing` | closing | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `established` | established | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_1` | fin_wait_1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_2` | fin_wait_2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `last_ack` | last_ack | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `listen` | listen | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_recv` | syn_recv | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_sent` | syn_sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `time_wait` | time_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Process attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.process.status` 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 | Stability | +|---|---|---| +| `running` | running | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sleeping` | sleeping | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stopped` | stopped | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defunct` | defunct | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +## Deprecated System Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `system.processes.status` | string | Deprecated, use `system.process.status` instead. | `running` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `system.process.status`. | + +`system.processes.status` 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 | Stability | +|---|---|---| +| `running` | running | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sleeping` | sleeping | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stopped` | stopped | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defunct` | defunct | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md index 7691f286a9..bec823a405 100644 --- a/docs/system/container-metrics.md +++ b/docs/system/container-metrics.md @@ -65,7 +65,7 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: @@ -91,7 +91,7 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index ca1fddf56d..8a62a0ec7d 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -86,8 +86,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.state`](../attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.cpu.state` 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. @@ -115,8 +115,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.cpu.state` | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.state`](../attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.cpu.state` 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. @@ -170,7 +170,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Memory Metrics @@ -194,7 +194,7 @@ available on the system, that is `system.memory.limit`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.memory.state` | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.memory.state`](../attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.memory.state` 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. @@ -235,7 +235,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.memory.state` | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.memory.state`](../attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.memory.state` 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. @@ -265,7 +265,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.paging.state` | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.state`](../attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.state` MUST be one of the following: @@ -288,7 +288,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.paging.state` | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.state`](../attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.state` MUST be one of the following: @@ -311,7 +311,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.paging.type` | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.type`](../attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.type` MUST be one of the following: @@ -334,8 +334,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.paging.direction` | string | The paging access direction | `in` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.paging.type` | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.direction`](../attributes-registry/system.md) | string | The paging access direction | `in` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.type`](../attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.paging.direction` MUST be one of the following: @@ -370,7 +370,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: @@ -394,7 +394,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: @@ -424,7 +424,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.operation_time` @@ -446,7 +446,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: @@ -470,7 +470,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `disk.io.direction` MUST be one of the following: @@ -497,11 +497,11 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.state` | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.type` | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mode`](../attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mountpoint`](../attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.state`](../attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.type`](../attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.filesystem.state` MUST be one of the following: @@ -536,11 +536,11 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.state` | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.type` | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mode`](../attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mountpoint`](../attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.state`](../attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.type`](../attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.filesystem.state` MUST be one of the following: @@ -586,7 +586,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: @@ -610,7 +610,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: @@ -640,7 +640,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: @@ -664,7 +664,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.io.direction` MUST be one of the following: @@ -688,8 +688,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `system.device` | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.network.state`](../attributes-registry/system.md) | string | A stateless protocol MUST NOT set this attribute | `close_wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value SHOULD be normalized to lowercase. @@ -741,7 +741,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.process.status`](../attributes-registry/system.md) | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.process.status` 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. diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index e567fb8a41..a1e534e379 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -1,56 +1,5 @@ groups: - # General system attributes - - id: attributes.system - prefix: system - type: attribute_group - brief: "Describes System metric attributes" - attributes: - - id: device - type: string - stability: experimental - brief: "The device identifier" - examples: ["(identifier)"] - - # system.cpu.* metrics and attribute group - - id: attributes.system.cpu - prefix: system.cpu - type: attribute_group - brief: "Describes System CPU metric attributes" - attributes: - - id: state - type: - allow_custom_values: true - members: - - id: user - value: 'user' - stability: experimental - - id: system - value: 'system' - stability: experimental - - id: nice - value: 'nice' - stability: experimental - - id: idle - value: 'idle' - stability: experimental - - id: iowait - value: 'iowait' - stability: experimental - - id: interrupt - value: 'interrupt' - stability: experimental - - id: steal - value: 'steal' - stability: experimental - brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." - stability: experimental - examples: ["idle", "interrupt"] - - id: logical_number - type: int - stability: experimental - brief: "The logical CPU number [0..n-1]" - examples: [1] - + # system.cpu.* metrics - id: metric.system.cpu.time type: metric metric_name: system.cpu.time @@ -60,6 +9,7 @@ groups: unit: "s" attributes: - ref: system.cpu.state + brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." - ref: system.cpu.logical_number - id: metric.system.cpu.utilization @@ -71,6 +21,7 @@ groups: unit: "1" attributes: - ref: system.cpu.state + brief: "The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels." - ref: system.cpu.logical_number - id: metric.system.cpu.frequency @@ -101,35 +52,7 @@ groups: unit: "{cpu}" attributes: [] - # sytem.memory.* metrics and attribute group - - id: attributes.system.memory - prefix: system.memory - type: attribute_group - brief: "Describes System Memory metric attributes" - attributes: - - id: state - type: - allow_custom_values: true - members: - - id: used - value: 'used' - stability: experimental - - id: free - value: 'free' - stability: experimental - - id: shared - value: 'shared' - stability: experimental - - id: buffers - value: 'buffers' - stability: experimental - - id: cached - value: 'cached' - stability: experimental - stability: experimental - brief: "The memory state" - examples: ["free", "cached"] - + # sytem.memory.* metrics - id: metric.system.memory.usage type: metric metric_name: system.memory.usage @@ -152,6 +75,7 @@ groups: Its value SHOULD equal the sum of `system.memory.state` over all states. instrument: updowncounter unit: "By" + attributes: [] - id: metric.system.memory.utilization type: metric @@ -163,51 +87,7 @@ groups: attributes: - ref: system.memory.state - # system.paging.* metrics and attribute group - - id: attributes.system.paging - prefix: system.paging - type: attribute_group - brief: "Describes System Memory Paging metric attributes" - attributes: - - id: state - type: - allow_custom_values: false - members: - - id: used - value: 'used' - stability: experimental - - id: free - value: 'free' - stability: experimental - stability: experimental - brief: "The memory paging state" - examples: ["free"] - - id: type - type: - allow_custom_values: false - members: - - id: major - value: 'major' - stability: experimental - - id: minor - value: 'minor' - stability: experimental - stability: experimental - brief: "The memory paging type" - examples: ["minor"] - - id: direction - type: - allow_custom_values: false - members: - - id: in - value: 'in' - stability: experimental - - id: out - value: 'out' - stability: experimental - stability: experimental - brief: "The paging access direction" - examples: ["in"] + # system.paging.* metrics - id: metric.system.paging.usage type: metric metric_name: system.paging.usage @@ -249,7 +129,7 @@ groups: - ref: system.paging.type - ref: system.paging.direction - # system.disk.* metrics and attribute group + # system.disk.* metrics - id: metric.system.disk.io type: metric metric_name: system.disk.io @@ -316,64 +196,7 @@ groups: - ref: system.device - ref: disk.io.direction - # system.filesystem.* metrics and attribute group - - id: attributes.system.filesystem - prefix: system.filesystem - type: attribute_group - brief: "Describes Filesystem metric attributes" - attributes: - - id: state - brief: "The filesystem state" - type: - allow_custom_values: false - members: - - id: used - value: 'used' - stability: experimental - - id: free - value: 'free' - stability: experimental - - id: reserved - value: 'reserved' - stability: experimental - stability: experimental - examples: ["used"] - - id: type - type: - allow_custom_values: true - members: - - id: fat32 - value: 'fat32' - stability: experimental - - id: exfat - value: 'exfat' - stability: experimental - - id: ntfs - value: 'ntfs' - stability: experimental - - id: refs - value: 'refs' - stability: experimental - - id: hfsplus - value: 'hfsplus' - stability: experimental - - id: ext4 - value: 'ext4' - stability: experimental - stability: experimental - brief: "The filesystem type" - examples: ["ext4"] - - id: mode - type: string - stability: experimental - brief: "The filesystem mode" - examples: ["rw, ro"] - - id: mountpoint - type: string - stability: experimental - brief: "The filesystem mount path" - examples: ["/mnt/data"] - + # system.filesystem.* metrics - id: metric.system.filesystem.usage type: metric metric_name: system.filesystem.usage @@ -402,58 +225,7 @@ groups: - ref: system.filesystem.mode - ref: system.filesystem.mountpoint - # system.network.* metrics and attribute group - - # System-specific network attributes - - id: attributes.system.network - prefix: system.network - type: attribute_group - brief: "Describes Network metric attributes" - attributes: - - id: state - type: - allow_custom_values: false - members: - - id: close - value: 'close' - stability: experimental - - id: close_wait - value: 'close_wait' - stability: experimental - - id: closing - value: 'closing' - stability: experimental - - id: delete - value: 'delete' - stability: experimental - - id: established - value: 'established' - stability: experimental - - id: fin_wait_1 - value: 'fin_wait_1' - stability: experimental - - id: fin_wait_2 - value: 'fin_wait_2' - stability: experimental - - id: last_ack - value: 'last_ack' - stability: experimental - - id: listen - value: 'listen' - stability: experimental - - id: syn_recv - value: 'syn_recv' - stability: experimental - - id: syn_sent - value: 'syn_sent' - stability: experimental - - id: time_wait - value: 'time_wait' - stability: experimental - stability: experimental - brief: "A stateless protocol MUST NOT set this attribute" - examples: ["close_wait"] - + # system.network.* metrics - id: metric.system.network.dropped type: metric metric_name: system.network.dropped @@ -522,34 +294,7 @@ groups: - ref: system.network.state - ref: network.transport - # system.process.* metrics and attribute group - - id: attributes.system.process - prefix: system.process - type: attribute_group - brief: "Describes System Process metric attributes" - attributes: - - id: status - type: - allow_custom_values: true - members: - - id: running - value: 'running' - stability: experimental - - id: sleeping - value: 'sleeping' - stability: experimental - - id: stopped - value: 'stopped' - stability: experimental - - id: defunct - value: 'defunct' - stability: experimental - stability: experimental - brief: > - The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) - examples: ["running"] - - + # system.process.* metrics - id: metric.system.process.count type: metric metric_name: system.process.count @@ -567,6 +312,7 @@ groups: brief: "Total number of processes created over uptime of the host" instrument: counter unit: "{process}" + attributes: [] # system.linux.* metrics - id: metric.system.linux.memory.available @@ -582,3 +328,4 @@ groups: See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). instrument: updowncounter unit: "By" + attributes: [] diff --git a/model/registry/system.yaml b/model/registry/system.yaml new file mode 100644 index 0000000000..19d3c60964 --- /dev/null +++ b/model/registry/system.yaml @@ -0,0 +1,255 @@ +groups: + # General system attributes + - id: registry.system + prefix: system + type: attribute_group + brief: "Describes System attributes" + attributes: + - id: device + type: string + stability: experimental + brief: "The device identifier" + examples: ["(identifier)"] + # system.cpu.* attribute group + - id: registry.system.cpu + prefix: system.cpu + type: attribute_group + brief: "Describes System CPU attributes" + attributes: + - id: state + type: + allow_custom_values: true + members: + - id: user + value: 'user' + stability: experimental + - id: system + value: 'system' + stability: experimental + - id: nice + value: 'nice' + stability: experimental + - id: idle + value: 'idle' + stability: experimental + - id: iowait + value: 'iowait' + stability: experimental + - id: interrupt + value: 'interrupt' + stability: experimental + - id: steal + value: 'steal' + stability: experimental + brief: "The state of the CPU" + stability: experimental + examples: ["idle", "interrupt"] + - id: logical_number + type: int + stability: experimental + brief: "The logical CPU number [0..n-1]" + examples: [1] + # sytem.memory.* attribute group + - id: registry.system.memory + prefix: system.memory + type: attribute_group + brief: "Describes System Memory attributes" + attributes: + - id: state + type: + allow_custom_values: true + members: + - id: used + value: 'used' + stability: experimental + - id: free + value: 'free' + stability: experimental + - id: shared + value: 'shared' + stability: experimental + - id: buffers + value: 'buffers' + stability: experimental + - id: cached + value: 'cached' + stability: experimental + stability: experimental + brief: "The memory state" + examples: ["free", "cached"] + # system.paging.* attribute group + - id: registry.system.paging + prefix: system.paging + type: attribute_group + brief: "Describes System Memory Paging attributes" + attributes: + - id: state + type: + allow_custom_values: false + members: + - id: used + value: 'used' + stability: experimental + - id: free + value: 'free' + stability: experimental + stability: experimental + brief: "The memory paging state" + examples: ["free"] + - id: type + type: + allow_custom_values: false + members: + - id: major + value: 'major' + stability: experimental + - id: minor + value: 'minor' + stability: experimental + stability: experimental + brief: "The memory paging type" + examples: ["minor"] + - id: direction + type: + allow_custom_values: false + members: + - id: in + value: 'in' + stability: experimental + - id: out + value: 'out' + stability: experimental + stability: experimental + brief: "The paging access direction" + examples: ["in"] + - id: registry.system.filesystem + prefix: system.filesystem + type: attribute_group + brief: "Describes Filesystem attributes" + attributes: + - id: state + brief: "The filesystem state" + type: + allow_custom_values: false + members: + - id: used + value: 'used' + stability: experimental + - id: free + value: 'free' + stability: experimental + - id: reserved + value: 'reserved' + stability: experimental + stability: experimental + examples: ["used"] + - id: type + type: + allow_custom_values: true + members: + - id: fat32 + value: 'fat32' + stability: experimental + - id: exfat + value: 'exfat' + stability: experimental + - id: ntfs + value: 'ntfs' + stability: experimental + - id: refs + value: 'refs' + stability: experimental + - id: hfsplus + value: 'hfsplus' + stability: experimental + - id: ext4 + value: 'ext4' + stability: experimental + stability: experimental + brief: "The filesystem type" + examples: ["ext4"] + - id: mode + type: string + stability: experimental + brief: "The filesystem mode" + examples: ["rw, ro"] + - id: mountpoint + type: string + stability: experimental + brief: "The filesystem mount path" + examples: ["/mnt/data"] + # System-specific network attributes + - id: registry.system.network + prefix: system.network + type: attribute_group + brief: "Describes Network attributes" + attributes: + - id: state + type: + allow_custom_values: false + members: + - id: close + value: 'close' + stability: experimental + - id: close_wait + value: 'close_wait' + stability: experimental + - id: closing + value: 'closing' + stability: experimental + - id: delete + value: 'delete' + stability: experimental + - id: established + value: 'established' + stability: experimental + - id: fin_wait_1 + value: 'fin_wait_1' + stability: experimental + - id: fin_wait_2 + value: 'fin_wait_2' + stability: experimental + - id: last_ack + value: 'last_ack' + stability: experimental + - id: listen + value: 'listen' + stability: experimental + - id: syn_recv + value: 'syn_recv' + stability: experimental + - id: syn_sent + value: 'syn_sent' + stability: experimental + - id: time_wait + value: 'time_wait' + stability: experimental + stability: experimental + brief: "A stateless protocol MUST NOT set this attribute" + examples: ["close_wait"] + # system.process.* attribute group + - id: registry.system.process + prefix: system.process + type: attribute_group + brief: "Describes System Process attributes" + attributes: + - id: status + type: + allow_custom_values: true + members: + - id: running + value: 'running' + stability: experimental + - id: sleeping + value: 'sleeping' + stability: experimental + - id: stopped + value: 'stopped' + stability: experimental + - id: defunct + value: 'defunct' + stability: experimental + stability: experimental + brief: > + The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) + examples: ["running"] From ac9f85f0581e1fd621f539392a7218c5cf4f3a25 Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Apr 2024 23:27:48 +0200 Subject: [PATCH 451/482] [chore] fix typo in resource attributes docs (#919) Co-authored-by: Liudmila Molkova --- docs/resource/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/resource/README.md b/docs/resource/README.md index c26eb9683b..be562f4587 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -24,7 +24,7 @@ This document defines standard attributes for resources. These attributes are ty - [Service](#service) - [Service (Experimental)](#service-experimental) - [Telemetry SDK](#telemetry-sdk) -- [Telemetry SDK (Experimental)](#telemetry-sdk-experimental) +- [Telemetry Distribution (Experimental)](#telemetry-distribution-experimental) - [Compute Unit](#compute-unit) - [Compute Instance](#compute-instance) - [Environment](#environment) @@ -186,13 +186,13 @@ All custom identifiers SHOULD be stable across different versions of an implemen | `webjs` | webjs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -## Telemetry SDK (Experimental) +## Telemetry Distribution (Experimental) **Status**: [Experimental][DocumentStatus] -**type:** `telemetry.sdk` +**type:** `telemetry.distro` -**Description:** Additions to the telemetry SDK. +**Description:** The telemetry distribution (distro) used to capture data recorded by the instrumentation libraries. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | From 0e6aae3dd5366497c9f5ffa1efe5afd19c655043 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 18 Apr 2024 08:00:34 -0700 Subject: [PATCH 452/482] Replace `db.statement` with `db.query.text` in examples (#932) --- docs/database/database-spans.md | 4 ++-- docs/database/elasticsearch.md | 2 +- docs/database/mongodb.md | 2 +- docs/database/redis.md | 2 +- docs/database/sql.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index d43277f9d5..275ae4e5a9 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -57,7 +57,7 @@ Since SQL statements may have very high cardinality even without arguments, SQL following way, unless the statement is known to be of low cardinality: ` .`, provided that `db.operation.name` and `db.collection.name` are available. If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. -It is not recommended to attempt any client-side parsing of `db.statement` just to get these properties, +It is not recommended to attempt any client-side parsing of `db.query.text` just to get these properties, they should only be used if the library being instrumented already provides them. When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. @@ -178,7 +178,7 @@ This allows multiple instrumentations for the same database to be aligned and ea The value `other_sql` is intended as a fallback and MUST only be used if the DBMS is known to be SQL-compliant but the concrete product is not known to the instrumentation. If the concrete DBMS is known to the instrumentation, its specific identifier MUST be used. -Back ends could, for example, use the provided identifier to determine the appropriate SQL dialect for parsing the `db.statement`. +Back ends could, for example, use the provided identifier to determine the appropriate SQL dialect for parsing the `db.query.text`. When additional attributes are added that only apply to a specific DBMS, its identifier SHOULD be used as a namespace in the attribute key as for the attributes in the sections below. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 1ef894e18a..f95b4ffe80 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -100,7 +100,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `server.address` | `"elasticsearch.mydomain.com"` | | `server.port` | `9200` | | `http.request.method` | `"GET"` | -| `db.statement` | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | +| `db.query.text` | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | | `db.operation.name` | `"search"` | | `url.full` | `"https://elasticsearch.mydomain.com:9200/my-index-000001/_search?from=40&size=20"` | | `db.elasticsearch.path_parts.index` | `"my-index-000001"` | diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 8f375ca88b..be34d3430a 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -39,7 +39,7 @@ described on this page. | `network.peer.port` | `27017` | | `network.transport` | `"tcp"` | | `db.name` | `"shopDb"` | -| `db.statement` | not set | +| `db.query.text` | not set | | `db.operation.name` | `"findAndModify"` | | `db.mongodb.collection` | `"products"` | diff --git a/docs/database/redis.md b/docs/database/redis.md index 6a8e94e057..27b9e0461d 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -41,7 +41,7 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | | `db.name` | not set | -| `db.statement` | `"HMSET myhash field1 'Hello' field2 'World"` | +| `db.query.text` | `"HMSET myhash field1 'Hello' field2 'World"` | | `db.operation.name` | not set | | `db.redis.database_index` | `15` | diff --git a/docs/database/sql.md b/docs/database/sql.md index 12d24d3448..dcd4d0ba2e 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -42,7 +42,7 @@ This is an example of attributes for a MySQL database span: | `network.peer.port` | `3306` | | `network.transport` | `"tcp"` | | `db.name` | `"ShopDb"` | -| `db.statement` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | +| `db.query.text` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation.name` | `"SELECT"` | | `db.collection.name` | `"orders"` | From 5e822ddfe9764de99fc7937317aa1f75947a223a Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 18 Apr 2024 18:02:49 +0200 Subject: [PATCH 453/482] Fix title for the JVM docs page (#934) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/runtime/jvm-metrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 7c658f95f8..bffa79169d 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -1,5 +1,5 @@ # Semantic Conventions for JVM Metrics From 54cc03eb612d9d271afd8ab9f8a6c5a9d33d407c Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 18 Apr 2024 10:56:06 -0700 Subject: [PATCH 454/482] HTTP spans restructuring: explicitly list all http client and server attributes, remove common (#931) --- .chloggen/931.yaml | 7 ++ docs/http/http-spans.md | 240 ++++++++++++++++++++++++++-------------- model/trace/http.yaml | 58 +++++----- 3 files changed, 195 insertions(+), 110 deletions(-) create mode 100644 .chloggen/931.yaml diff --git a/.chloggen/931.yaml b/.chloggen/931.yaml new file mode 100644 index 0000000000..ad215bd516 --- /dev/null +++ b/.chloggen/931.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: http + +note: List all HTTP client and server attributes in the corresponding table, remove common attributes from yaml and markdown. + +issues: [928] diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 6a350d5876..73a6915e58 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -16,7 +16,6 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Name](#name) - [Status](#status) -- [Common Attributes](#common-attributes) - [HTTP client](#http-client) - [HTTP client span duration](#http-client-span-duration) - [HTTP request retries and redirects](#http-request-retries-and-redirects) @@ -108,25 +107,40 @@ the client or server from sending/receiving the request/response fully. When instrumentation detects such errors it MUST set span status to `Error` and MUST set the `error.type` attribute. -## Common Attributes +## HTTP client -The common attributes listed in this section apply to both HTTP clients and servers in addition to -the specific attributes listed in the [HTTP client](#http-client) and [HTTP server](#http-server) -sections below. +This span type represents an outbound HTTP request. There are two ways this can be achieved in an instrumentation: - +1. Instrumentations SHOULD create an HTTP span for each attempt to send an HTTP request over the wire. + In case the request is resent, the resend attempts MUST follow the [HTTP resend spec](#http-request-retries-and-redirects). + In this case, instrumentations SHOULD NOT (also) emit a logical encompassing HTTP client span. + +2. If for some reason it is not possible to emit a span for each send attempt (because e.g. the instrumented library does not expose hooks that would allow this), + instrumentations MAY create an HTTP span for the top-most operation of the HTTP client. + In this case, the `url.full` MUST be the absolute URL that was originally requested, before any HTTP-redirects that may happen when executing the request. + +For an HTTP client span, `SpanKind` MUST be `Client`. + + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [4] | `http`; `spdy` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [9] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [6] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [7] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [10] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [11] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [12] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [13] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -143,7 +157,15 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -**[2]:** If the request fails with an error before response status code was sent or received, +**[2]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. + +**[3]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[4]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. + +**[5]:** If the request fails with an error before response status code was sent or received, `error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error identifier. @@ -160,23 +182,32 @@ additional filters are applied. If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. -**[3]:** If and only if it's different than `http.request.method`. +**[6]:** If and only if it's different than `http.request.method`. + +**[7]:** The value SHOULD be normalized to lowercase. -**[4]:** The value SHOULD be normalized to lowercase. +**[8]:** If not `http` and `network.protocol.version` is set. -**[5]:** If not `http` and `network.protocol.version` is set. +**[9]:** 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). -**[6]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[10]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[7]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[11]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[12]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. -**[8]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. +**[13]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): * [`http.request.method`](../attributes-registry/http.md) +* [`server.address`](../attributes-registry/server.md) +* [`server.port`](../attributes-registry/server.md) +* [`url.full`](../attributes-registry/url.md) `http.request.method` 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. @@ -209,52 +240,6 @@ The following attributes can be important for making sampling decisions and SHOU | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -## HTTP client - -This span type represents an outbound HTTP request. There are two ways this can be achieved in an instrumentation: - -1. Instrumentations SHOULD create an HTTP span for each attempt to send an HTTP request over the wire. - In case the request is resent, the resend attempts MUST follow the [HTTP resend spec](#http-request-retries-and-redirects). - In this case, instrumentations SHOULD NOT (also) emit a logical encompassing HTTP client span. - -2. If for some reason it is not possible to emit a span for each send attempt (because e.g. the instrumented library does not expose hooks that would allow this), - instrumentations MAY create an HTTP span for the top-most operation of the HTTP client. - In this case, the `url.full` MUST be the absolute URL that was originally requested, before any HTTP-redirects that may happen when executing the request. - -For an HTTP client span, `SpanKind` MUST be `Client`. - - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [4] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [5] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - -**[1]:** If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used. - -**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. - -**[3]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. - -**[4]:** 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). - -**[5]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. -The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. -The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. - -The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): - -* [`server.address`](../attributes-registry/server.md) -* [`server.port`](../attributes-registry/server.md) -* [`url.full`](../attributes-registry/url.md) - - ### HTTP client span duration There are some minimal constraints that SHOULD be honored: @@ -335,45 +320,102 @@ This span type represents an inbound HTTP request. For an HTTP server span, `SpanKind` MUST be `Server`. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [1] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [3] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [5] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [3] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [6] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [10] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [12] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [8] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [9] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [14] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [15] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [16] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. +**[1]:** HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). -**[2]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +**[2]:** Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. + +**[3]:** The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request. + +**[4]:** If the request fails with an error before response status code was sent or received, +`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable) +or a component-specific low cardinality error identifier. + +If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md), +`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier. + +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low, but +telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time, when no +additional filters are applied. -**[3]:** 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. +If the request has completed successfully, instrumentations SHOULD NOT set `error.type`. + +**[5]:** If and only if it's different than `http.request.method`. + +**[6]:** 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](/docs/http/http-spans.md#http-server-definitions) if there is one. -**[4]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[7]:** The value SHOULD be normalized to lowercase. + +**[8]:** If not `http` and `network.protocol.version` is set. -**[5]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. +**[9]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). -**[6]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. +**[10]:** Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. -**[7]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). +**[11]:** The IP address of the original client behind all proxies, if known (e.g. from [Forwarded#for](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#for), [X-Forwarded-For](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-For), or a similar header). Otherwise, the immediate client peer address. -**[8]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[12]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[9]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +**[13]:** See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes). + +**[14]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. + +**[15]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. +**[16]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + +**[17]:** Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. + The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): +* [`http.request.method`](../attributes-registry/http.md) * [`url.path`](../attributes-registry/url.md) * [`url.scheme`](../attributes-registry/url.md) * [`server.port`](../attributes-registry/server.md) @@ -382,6 +424,36 @@ The following attributes can be important for making sampling decisions and SHOU * [`server.address`](../attributes-registry/server.md) * [`user_agent.original`](../attributes-registry/user-agent.md) * [`http.request.header.`](../attributes-registry/http.md) + +`http.request.method` 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 | Stability | +|---|---|---| +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`network.transport` 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 | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. diff --git a/model/trace/http.yaml b/model/trace/http.yaml index 1e5667ad4f..b463f38497 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -1,41 +1,22 @@ groups: - - id: trace.http.common - 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: - - ref: http.request.method_original - requirement_level: - conditionally_required: If and only if it's different than `http.request.method`. - - ref: http.response.header - requirement_level: opt_in - - ref: http.request.method - sampling_relevant: true - requirement_level: required - - ref: network.peer.address - - ref: network.peer.port - requirement_level: - recommended: If `network.peer.address` is set. - - ref: network.transport - requirement_level: opt_in - note: > - Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. - Other obscure implementations are possible. - - id: trace.http.client type: span extends: attributes.http.client span_kind: client brief: 'Semantic Convention for HTTP Client' attributes: + - ref: http.request.method + sampling_relevant: true + - ref: http.request.method_original + requirement_level: + conditionally_required: If and only if it's different than `http.request.method`. - ref: http.request.resend_count requirement_level: recommended: if and only if request was retried. - ref: http.request.header requirement_level: opt_in + - ref: http.response.header + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -46,6 +27,15 @@ groups: - ref: user_agent.original requirement_level: opt_in - ref: url.scheme + - ref: network.peer.address + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. + - ref: network.transport + requirement_level: opt_in + note: > + Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. + Other obscure implementations are possible. - id: trace.http.server type: span @@ -53,10 +43,17 @@ groups: span_kind: server brief: 'Semantic Convention for HTTP Server' attributes: + - ref: http.request.method + sampling_relevant: true + - ref: http.request.method_original + requirement_level: + conditionally_required: If and only if it's different than `http.request.method`. - ref: http.route - ref: http.request.header sampling_relevant: true requirement_level: opt_in + - ref: http.response.header + requirement_level: opt_in - ref: server.address sampling_relevant: true - ref: server.port @@ -89,3 +86,12 @@ groups: sampling_relevant: true - ref: user_agent.original sampling_relevant: true + - ref: network.peer.address + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. + - ref: network.transport + requirement_level: opt_in + note: > + Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. + Other obscure implementations are possible. From bee13d413c06f8c1ec7ea3e186e9f2fbff0fc0a5 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Thu, 18 Apr 2024 23:26:30 +0200 Subject: [PATCH 455/482] [BREAKING] move attributes from db metrics to the registry (#909) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/db_metrics.yaml | 22 +++++++++++ docs/attributes-registry/db.md | 25 ++++++++++++ docs/database/database-metrics.md | 22 +++++------ model/metrics/database-metrics.yaml | 59 ++++++++++------------------- model/registry/db.yaml | 24 ++++++++++++ model/registry/deprecated/db.yaml | 26 +++++++++++++ schema-next.yaml | 21 ++++++++++ 7 files changed, 149 insertions(+), 50 deletions(-) create mode 100755 .chloggen/db_metrics.yaml diff --git a/.chloggen/db_metrics.yaml b/.chloggen/db_metrics.yaml new file mode 100755 index 0000000000..0e8468e967 --- /dev/null +++ b/.chloggen/db_metrics.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Rename `pool.name` to `db.client.connections.pool.name` and `state` to `db.client.connections.state`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [909] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 45c73f0997..5940f91d71 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -12,6 +12,7 @@ - [MSSQL Attributes](#mssql-attributes) - [Redis Attributes](#redis-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) +- [Deprecated DB Metrics Attributes](#deprecated-db-metrics-attributes) @@ -20,6 +21,8 @@ | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [2] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -35,6 +38,13 @@ **[3]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. +`db.client.connections.state` 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 | Stability | +|---|---|---| +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + `db.system` 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 | Stability | @@ -208,3 +218,18 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | + +## Deprecated DB Metrics Attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `pool.name` | string | Deprecated, use `db.client.connections.pool.name` instead. | `myDataSource` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.pool.name`. | +| `state` | string | Deprecated, use `db.client.connections.state` instead. | `idle` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.state`. | + +`state` 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 | Stability | +|---|---|---| +| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + \ No newline at end of file diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index cff733d139..d779bc7a6d 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -52,10 +52,10 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `state` | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.state`](../attributes-registry/db.md) | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`state` MUST be one of the following: +`db.client.connections.state` 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 | Stability | |---|---|---| @@ -75,7 +75,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.idle.min` @@ -91,7 +91,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.max` @@ -107,7 +107,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.pending_requests` @@ -123,7 +123,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.timeouts` @@ -139,7 +139,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.create_time` @@ -155,7 +155,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.wait_time` @@ -171,7 +171,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.use_time` @@ -187,7 +187,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index d172d9e4b6..cce9257e4f 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -1,33 +1,4 @@ groups: - - id: attributes.db - type: attribute_group - brief: Describes Database attributes - attributes: - - id: state - stability: experimental - type: - allow_custom_values: false - members: - - id: idle - value: 'idle' - stability: experimental - - id: used - value: 'used' - stability: experimental - requirement_level: required - brief: "The state of a connection in the pool" - examples: ["idle"] - - id: pool.name - type: string - stability: experimental - requirement_level: required - brief: > - The name of the connection pool; unique within the instrumented application. - In case the connection pool implementation doesn't provide a name, - instrumentation should use a combination of `server.address` and `server.port` attributes - formatted as `server.address:server.port`. - examples: ["myDataSource"] - - id: metric.db.client.connections.usage type: metric metric_name: db.client.connections.usage @@ -36,8 +7,10 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: state - - ref: pool.name + - ref: db.client.connections.state + requirement_level: required + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.idle.max type: metric @@ -47,7 +20,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.idle.min type: metric @@ -57,7 +31,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.max type: metric @@ -67,7 +42,8 @@ groups: instrument: updowncounter unit: "{connection}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.pending_requests type: metric @@ -77,7 +53,8 @@ groups: instrument: updowncounter unit: "{request}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.timeouts type: metric @@ -87,7 +64,8 @@ groups: instrument: counter unit: "{timeout}" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.create_time type: metric @@ -97,7 +75,8 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.wait_time type: metric @@ -107,7 +86,8 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required - id: metric.db.client.connections.use_time type: metric @@ -117,4 +97,5 @@ groups: instrument: histogram unit: "ms" attributes: - - ref: pool.name + - ref: db.client.connections.pool.name + requirement_level: required diff --git a/model/registry/db.yaml b/model/registry/db.yaml index cce3c33972..25532ab6a4 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -487,3 +487,27 @@ groups: This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. examples: 'mysql-e26b99z.example.com' + - id: client.connections.state + tag: db-generic + stability: experimental + type: + allow_custom_values: true + members: + - id: idle + value: 'idle' + stability: experimental + - id: used + value: 'used' + stability: experimental + brief: "The state of a connection in the pool" + examples: ["idle"] + - id: client.connections.pool.name + tag: db-generic + type: string + stability: experimental + brief: > + The name of the connection pool; unique within the instrumented application. + In case the connection pool implementation doesn't provide a name, + instrumentation should use a combination of `server.address` and `server.port` attributes + formatted as `server.address:server.port`. + examples: ["myDataSource"] diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index a5a6390b1b..de58225c67 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -66,3 +66,29 @@ groups: brief: 'Deprecated, use `db.collection.name` instead.' deprecated: "Replaced by `db.collection.name`." examples: 'mytable' + + - id: registry.db.metrics.deprecated + type: attribute_group + brief: > + "Describes deprecated db metrics attributes." + attributes: + - id: state + stability: experimental + type: + allow_custom_values: true + members: + - id: idle + value: 'idle' + stability: experimental + - id: used + value: 'used' + stability: experimental + brief: "Deprecated, use `db.client.connections.state` instead." + deprecated: "Replaced by `db.client.connections.state`." + examples: ["idle"] + - id: pool.name + type: string + stability: experimental + brief: "Deprecated, use `db.client.connections.pool.name` instead." + deprecated: "Replaced by `db.client.connections.pool.name`." + examples: ["myDataSource"] diff --git a/schema-next.yaml b/schema-next.yaml index 430901253a..5fc05edea2 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -2,6 +2,27 @@ file_format: 1.1.0 schema_url: https://opentelemetry.io/schemas/next versions: next: + metrics: + changes: + # https://github.com/open-telemetry/semantic-conventions/pull/909 + - rename_attributes: + attribute_map: + state: db.client.connections.state + apply_to_metrics: + - db.client.connections.usage + - rename_attributes: + attribute_map: + pool.name: db.client.connections.pool.name + apply_to_metrics: + - db.client.connections.usage + - db.client.connections.idle.max + - db.client.connections.idle.min + - db.client.connections.max + - db.client.connections.pending_requests + - db.client.connections.timeouts + - db.client.connections.create_time + - db.client.connections.wait_time + - db.client.connections.use_time 1.25.0: spans: From 1b6bde0287f7534a13d8828370e69cb2e1415489 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:58:15 -0700 Subject: [PATCH 456/482] Move common DB attributes (#910) Co-authored-by: Liudmila Molkova --- .chloggen/910.yaml | 4 +++ model/db-common.yaml | 41 ++++++++++++++++++++++++++++++ model/trace/database.yaml | 53 +++++++-------------------------------- 3 files changed, 54 insertions(+), 44 deletions(-) create mode 100644 .chloggen/910.yaml create mode 100644 model/db-common.yaml diff --git a/.chloggen/910.yaml b/.chloggen/910.yaml new file mode 100644 index 0000000000..fbfbe2cd73 --- /dev/null +++ b/.chloggen/910.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: db +note: Reorganize DB conventions to be shared across span and metric conventions. +issues: [ 910 ] diff --git a/model/db-common.yaml b/model/db-common.yaml new file mode 100644 index 0000000000..fdefe67883 --- /dev/null +++ b/model/db-common.yaml @@ -0,0 +1,41 @@ +groups: + - id: attributes.db.client + type: attribute_group + brief: 'Database Client attributes' + attributes: + - ref: db.name + requirement_level: + conditionally_required: If applicable. + - ref: db.collection.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.collection.name`, then it SHOULD be the first collection name found in the query. + - ref: db.instance.id + requirement_level: + recommended: If different from the `server.address` + - ref: db.operation.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.operation.name`, then it SHOULD be the first operation name found in the query. + - ref: db.system + requirement_level: required + - ref: network.peer.address + brief: Peer address of the database node where the operation was performed. + requirement_level: + recommended: If applicable for this database system. + note: > + Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. + Network peer address and port are useful when the application interacts with individual database nodes directly. + + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + - ref: network.peer.port + requirement_level: + recommended: if and only if `network.peer.address` is set. + - ref: server.address + brief: > + Name of the database host. + - ref: server.port + requirement_level: + conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. diff --git a/model/trace/database.yaml b/model/trace/database.yaml index b4ed7d0da6..d42d1c6b68 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -1,55 +1,20 @@ groups: - - id: db.common.attributes + - id: trace.db.common + extends: attributes.db.client type: attribute_group brief: This group defines the attributes used to perform database client calls. attributes: - - ref: db.system - requirement_level: required - - ref: db.name - requirement_level: - conditionally_required: If applicable. - ref: db.query.text requirement_level: recommended: > Should be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in - - ref: db.operation.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.operation.name`, then it SHOULD be the first operation name found in the query. - - ref: server.address - brief: > - Name of the database host. - - ref: server.port - requirement_level: - conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - - ref: db.instance.id - requirement_level: - recommended: If different from the `server.address` - - ref: db.collection.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.collection.name`, then it SHOULD be the first collection name found in the query. - - ref: network.peer.address - brief: Peer address of the database node where the operation was performed. - requirement_level: - recommended: If applicable for this database system. - note: > - Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. - Network peer address and port are useful when the application interacts with individual database nodes directly. - - If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - - ref: network.peer.port - requirement_level: - recommended: if and only if `network.peer.address` is set. - id: db.tech_specific.network.attributes type: attribute_group brief: This group documents attributes that describe database call along with network information. - extends: db.common.attributes + extends: trace.db.common attributes: - ref: network.peer.address requirement_level: @@ -64,7 +29,7 @@ groups: type: span brief: This span defines the attributes used to perform database client calls. span_kind: client - extends: db.common.attributes + extends: trace.db.common - id: db.mssql type: span @@ -105,7 +70,7 @@ groups: - id: db.hbase type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for HBase attributes: @@ -118,7 +83,7 @@ groups: - id: db.couchdb type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for CouchDB attributes: @@ -155,7 +120,7 @@ groups: - id: db.mongodb type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for MongoDB attributes: @@ -219,7 +184,7 @@ groups: - id: db.sql type: span - extends: db.common.attributes + extends: trace.db.common brief: > Attributes for SQL databases attributes: @@ -236,7 +201,7 @@ groups: - id: db.cosmosdb type: span - extends: db.common.attributes + extends: trace.db.common prefix: db.cosmosdb brief: > Attributes for Cosmos DB. From b77c881ad68dca7bb7af2c97899a0ef64357c47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerhard=20St=C3=B6bich?= Date: Fri, 19 Apr 2024 12:04:14 +0200 Subject: [PATCH 457/482] [chore] adapt lambda examples to current conventions (#938) --- docs/faas/aws-lambda.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 273eb71eeb..0719970912 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -158,8 +158,8 @@ added as a link to the span. This means the span may have as many links as messa See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. - [`faas.trigger`][faas] MUST be set to `pubsub`. -- [`messaging.operation`](/docs/messaging/messaging-spans.md) MUST be set to `process`. -- [`messaging.system`](/docs/messaging/messaging-spans.md) MUST be set to `AmazonSQS`. +- [`messaging.operation.type`](/docs/messaging/messaging-spans.md) MUST be set to `process`. +- [`messaging.system`](/docs/messaging/messaging-spans.md) MUST be set to `aws_sqs`. ### SQS Message @@ -171,8 +171,8 @@ added as a link to the span. See [compatibility](../../supplementary-guidelines/compatibility/aws.md#context-propagation) for more info. - [`faas.trigger`][faas] MUST be set to `pubsub`. -- [`messaging.operation`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `process`. -- [`messaging.system`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `AmazonSQS`. +- [`messaging.operation.type`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `process`. +- [`messaging.system`](/docs/messaging/messaging-spans.md#messaging-attributes) MUST be set to `aws_sqs`. Other [Messaging attributes](/docs/messaging/messaging-spans.md#messaging-attributes) SHOULD be set based on the available information in the SQS message event. @@ -251,9 +251,9 @@ Function F: | Span ProcBatch | | Links | | | | Span Prod1 | Span Prod2 | | SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | `CONSUMER` | `CONSUMER` | | Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` | -| `messaging.system` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | `AmazonSQS` | +| `messaging.system` | `aws_sqs` | `aws_sqs` | `aws_sqs` | `aws_sqs` | `aws_sqs` | | `messaging.destination.name` | `Q` | `Q` | `Q` | `Q` | `Q` | -| `messaging.operation` | | | `process` | `process` | `process` | +| `messaging.operation.type` | | | `process` | `process` | `process` | | `messaging.message.id` | | | | `"a1"` | `"a2"` | Note that if Span Prod1 and Span Prod2 were sent to different queues, Span ProcBatch would not have From c8a1337e7a45ddb01572ef6aea777174af837e96 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Mon, 22 Apr 2024 02:14:04 -0700 Subject: [PATCH 458/482] Fix the linkTitle for Azure Messaging (#944) --- docs/messaging/azure-messaging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 8028640677..3deba05a1c 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -1,5 +1,5 @@ # Semantic Conventions for Azure Messaging systems From 7f6876de7d0c5fcafaab812b00a31d56b524be77 Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Mon, 22 Apr 2024 13:40:25 +0200 Subject: [PATCH 459/482] [chore] move log to registry (#908) Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/log.md | 52 +++++++++++++++ docs/general/logs.md | 16 ++--- model/logs/general.yaml | 14 +--- model/logs/media.yaml | 47 ++------------ model/registry/log.yaml | 72 +++++++++++++++++++++ 9 files changed, 143 insertions(+), 62 deletions(-) create mode 100644 docs/attributes-registry/log.md create mode 100644 model/registry/log.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index bb5ede00e1..c78207d5fe 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -48,6 +48,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 53520602e3..355217d372 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -41,6 +41,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 0e79351f21..c4dd0faedb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -50,6 +50,7 @@ body: - area:http - area:ios - area:k8s + - area:log - area:messaging - area:network - area:oci diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 4669206415..a0f1684213 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -55,6 +55,7 @@ Currently, the following namespaces exist: * [HTTP](http.md) * [iOS](ios.md) * [K8s](k8s.md) +* [Log](log.md) * [Network](network.md) * [OCI](oci.md) * [OpenTelemetry](otel.md) diff --git a/docs/attributes-registry/log.md b/docs/attributes-registry/log.md new file mode 100644 index 0000000000..89c5145c1b --- /dev/null +++ b/docs/attributes-registry/log.md @@ -0,0 +1,52 @@ + + +# Log + + + +- [Log Attributes](#log-attributes) + - [Generic log attributes](#generic-log-attributes) + - [File log attributes](#file-log-attributes) + - [Record log attributes](#record-log-attributes) + + + +## Log Attributes + +### Generic log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`log.iostream` 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 | Stability | +|---|---|---| +| `stdout` | Logs from stdout stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stderr` | Events from stderr stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### File log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.file.name` | string | The basename of the file. | `audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +### Record log attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. +The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. + \ No newline at end of file diff --git a/docs/general/logs.md b/docs/general/logs.md index 748c2e61fc..cd443a3b2d 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -38,7 +38,7 @@ These attributes may be used for identifying a Log Record. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.record.uid`](../attributes-registry/log.md) | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. @@ -59,22 +59,22 @@ As such, these should be recorded as Log Record attributes when applicable. They | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.file.name` | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name`](../attributes-registry/log.md) | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name_resolved`](../attributes-registry/log.md) | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path`](../attributes-registry/log.md) | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path_resolved`](../attributes-registry/log.md) | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### I/O Stream **Description:** The I/O stream to which the log was emitted. - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.iostream`](../attributes-registry/log.md) | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`log.iostream` MUST be one of the following: +`log.iostream` 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 | Stability | |---|---|---| diff --git a/model/logs/general.yaml b/model/logs/general.yaml index e8f9ea5853..b4afe2c16c 100644 --- a/model/logs/general.yaml +++ b/model/logs/general.yaml @@ -1,20 +1,8 @@ groups: - id: log.record - prefix: log.record type: attribute_group brief: > The attributes described in this section are rather generic. They may be used in any Log Record they apply to. attributes: - - id: uid - type: string - stability: experimental + - ref: log.record.uid requirement_level: opt_in - brief: > - A unique identifier for the Log Record. - note: > - If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. - This means, that two distinguishable log records MUST have different values. - - The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), - but other identifiers (e.g. UUID) may be used as needed. - examples: ["01ARZ3NDEKTSV4RRFFQ69G5FAV"] diff --git a/model/logs/media.yaml b/model/logs/media.yaml index b6bfea89d4..34c7631d5c 100644 --- a/model/logs/media.yaml +++ b/model/logs/media.yaml @@ -1,56 +1,21 @@ groups: - id: attributes.log - prefix: log type: attribute_group brief: "Describes Log attributes" attributes: - - id: iostream + - ref: log.iostream requirement_level: opt_in - stability: experimental - brief: > - The stream associated with the log. See below for a list of well-known values. - type: - allow_custom_values: false - members: - - id: stdout - value: 'stdout' - brief: 'Logs from stdout stream' - stability: experimental - - id: stderr - value: 'stderr' - brief: 'Events from stderr stream' - stability: experimental + - id: attributes.log.file - prefix: log.file type: attribute_group brief: > A file to which log was emitted. attributes: - - id: name - type: string - stability: experimental + - ref: log.file.name requirement_level: recommended - brief: > - The basename of the file. - examples: ["audit.log"] - - id: path - type: string - stability: experimental + - ref: log.file.path requirement_level: opt_in - brief: > - The full path to the file. - examples: [ "/var/log/mysql/audit.log" ] - - id: name_resolved - type: string - stability: experimental + - ref: log.file.name_resolved requirement_level: opt_in - brief: > - The basename of the file, with symlinks resolved. - examples: [ "uuid.log" ] - - id: path_resolved - type: string - stability: experimental + - ref: log.file.path_resolved requirement_level: opt_in - brief: > - The full path to the file, with symlinks resolved. - examples: [ "/var/lib/docker/uuid.log" ] diff --git a/model/registry/log.yaml b/model/registry/log.yaml new file mode 100644 index 0000000000..b26870a696 --- /dev/null +++ b/model/registry/log.yaml @@ -0,0 +1,72 @@ +groups: + - id: registry.log + type: attribute_group + prefix: log + brief: > + This document defines log attributes + attributes: + - id: iostream + stability: experimental + brief: > + The stream associated with the log. See below for a list of well-known values. + type: + allow_custom_values: true + members: + - id: stdout + value: 'stdout' + brief: 'Logs from stdout stream' + stability: experimental + - id: stderr + value: 'stderr' + brief: 'Events from stderr stream' + stability: experimental + + - id: registry.log.file # TODO: should we move it to the file model? + type: attribute_group + prefix: log.file + brief: > + Attributes for a file to which log was emitted. + attributes: + - id: name + type: string + stability: experimental + brief: > + The basename of the file. + examples: [ "audit.log" ] + - id: path + type: string + stability: experimental + brief: > + The full path to the file. + examples: [ "/var/log/mysql/audit.log" ] + - id: name_resolved + type: string + stability: experimental + brief: > + The basename of the file, with symlinks resolved. + examples: [ "uuid.log" ] + - id: path_resolved + type: string + stability: experimental + brief: > + The full path to the file, with symlinks resolved. + examples: [ "/var/lib/docker/uuid.log" ] + + - id: registry.log.record + type: attribute_group + prefix: log.record + brief: > + This document defines the generic attributes that may be used in any Log Record. + attributes: + - id: uid + type: string + stability: experimental + brief: > + A unique identifier for the Log Record. + note: > + If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. + This means, that two distinguishable log records MUST have different values. + + The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), + but other identifiers (e.g. UUID) may be used as needed. + examples: ["01ARZ3NDEKTSV4RRFFQ69G5FAV"] From b6bc365b7689df96d97682a164318f44e0cd3bd8 Mon Sep 17 00:00:00 2001 From: Nev <54870357+MSNev@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:41:54 -0700 Subject: [PATCH 460/482] Update the device.app.lifecycle event description and constraints (#794) Co-authored-by: Liudmila Molkova --- .chloggen/device_app_lifecycle.yaml | 26 +++++++ .github/ISSUE_TEMPLATE/bug_report.yaml | 1 - .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 - .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 - .gitignore | 1 + .vscode/settings.json | 2 +- docs/attributes-registry/android.md | 9 ++- docs/attributes-registry/ios.md | 8 +- docs/mobile/events.md | 57 +++++++------- model/logs/mobile-events.yaml | 85 +++++++++++++++++---- model/registry/android.yaml | 34 --------- model/registry/deprecated/android.yaml | 36 +++++++++ model/registry/{ => deprecated}/ios.yaml | 6 +- 13 files changed, 180 insertions(+), 87 deletions(-) create mode 100644 .chloggen/device_app_lifecycle.yaml create mode 100644 model/registry/deprecated/android.yaml rename model/registry/{ => deprecated}/ios.yaml (88%) diff --git a/.chloggen/device_app_lifecycle.yaml b/.chloggen/device_app_lifecycle.yaml new file mode 100644 index 0000000000..18fdf8a931 --- /dev/null +++ b/.chloggen/device_app_lifecycle.yaml @@ -0,0 +1,26 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: device.app.lifecycle + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: > + Reformat and update the `device.app.lifecycle` event description adds constraints for the possible values of + the `android.state` and `ios.state`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [794] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: > + Removes the `ios.lifecycle.events` and `android.lifecycle.events` attributes from the global registry and adds + constraints for the possible values of the `android.state` and `ios.state` attributes. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index c78207d5fe..896738c60c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -46,7 +46,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 355217d372..ca2933bc38 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -39,7 +39,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index c4dd0faedb..1c1afe1779 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -48,7 +48,6 @@ body: - area:heroku - area:host - area:http - - area:ios - area:k8s - area:log - area:messaging diff --git a/.gitignore b/.gitignore index c9508b6a86..fdb9989733 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ .project .settings bin +.vs # NetBeans /.nb-gradle diff --git a/.vscode/settings.json b/.vscode/settings.json index ec636cc19b..7741a3e1f5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,7 +11,7 @@ }, "yaml.schemas": { "https://raw.githubusercontent.com/open-telemetry/build-tools/v0.24.0/semantic-conventions/semconv.schema.json": [ - "model/**/*.yaml", + "model/**/*.yaml" ] }, "json.schemaDownload.enable": true diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index f2ca703769..971f390749 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -3,23 +3,24 @@ - [Android Attributes](#android-attributes) -- [Android Lifecycle Event Attributes](#android-lifecycle-event-attributes) +- [Deprecated Android Attributes](#deprecated-android-attributes) ## Android Attributes + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## Android Lifecycle Event Attributes +## Deprecated Android Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `android.state` | string | Deprecated use the `device.app.lifecycle` event definition including `android.state` as a payload field instead. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. diff --git a/docs/attributes-registry/ios.md b/docs/attributes-registry/ios.md index e8aea69f54..b867deac8e 100644 --- a/docs/attributes-registry/ios.md +++ b/docs/attributes-registry/ios.md @@ -5,16 +5,16 @@ -- [iOS Lifecycle Event Attributes](#ios-lifecycle-event-attributes) +- [Deprecated iOS Attributes](#deprecated-ios-attributes) -## iOS Lifecycle Event Attributes +## Deprecated iOS Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| -| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ios.state` | string | Deprecated use the `device.app.lifecycle` event definition including `ios.state` as a payload field instead. [1] | `active` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Moved to a payload field of `device.app.lifecycle`. | **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. diff --git a/docs/mobile/events.md b/docs/mobile/events.md index b02760674b..06a6907ef4 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -9,8 +9,7 @@ events on mobile platforms. All mobile events MUST use a namespace of - [Lifecycle instrumentation](#lifecycle-instrumentation) - - [iOS](#ios) - - [Android](#android) + - [Event details](#event-details) @@ -21,39 +20,35 @@ application lifecycle. This event is meant to be used in conjunction with `os.name` [resource semantic convention](/docs/resource/os.md) to identify the mobile operating system (e.g. Android, iOS). -### iOS +The following table describes the payload fields that MUST +be used to describe the state of the application at the time of the event. - -The event name MUST be `device.app.lifecycle`. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`ios.state`](../attributes-registry/ios.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `active` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +The `android.state` and `ios.state` fields are mutually exclusive and MUST +NOT be used together, each field MUST be used with its corresponding +`os.name` [resource semantic convention](/docs/resource/os.md) value. -**[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. +### Event details -`ios.state` 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. + +The event name MUST be `device.app.lifecycle`. -| Value | Description | Stability | -|---|---|---| -| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Android - - -The event name MUST be `device.app.lifecycle`. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | + +| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`android.state`](../attributes-registry/android.md) | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `android.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [1] | `created` | `Conditionally Required`: if and only if `os.name` is `android` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ios.state` | string | This attribute represents the state the application has transitioned into at the occurrence of the event. [2] | `active` | `Conditionally Required`: if and only if `os.name` is `ios` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. +**[2]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. + +**Additional attribute requirements:** At least one of the following sets of attributes is required: + +* `ios.state` +* `android.state` + `android.state` 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 | Stability | @@ -61,6 +56,16 @@ The event name MUST be `device.app.lifecycle`. | `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + +`ios.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md diff --git a/model/logs/mobile-events.yaml b/model/logs/mobile-events.yaml index 6664bd1edb..4b1d956b21 100644 --- a/model/logs/mobile-events.yaml +++ b/model/logs/mobile-events.yaml @@ -1,17 +1,76 @@ groups: - - id: ios.lifecycle.events + - id: device.app.lifecycle + stability: experimental type: event name: device.app.lifecycle brief: > - This event represents an occurrence of a lifecycle transition on the iOS platform. - attributes: - - ref: ios.state - requirement_level: "required" - - id: android.lifecycle.events - type: event - name: device.app.lifecycle - brief: > - This event represents an occurrence of a lifecycle transition on the Android platform. - attributes: - - ref: android.state - requirement_level: required + This event represents an occurrence of a lifecycle transition on Android or iOS platform. + note: > + This event identifies the fields that are common to all lifecycle events for android and iOS using + the `android.state` and `ios.state` fields. The `android.state` and `ios.state` attributes are + mutually exclusive. + # Future Note: When the build tools support this definition please uncomment and validate the details + # included here and what has been added to the manual markdown table + # body: + # fields: + # - id: ios.state + # stability: experimental + # requirement_level: + # conditional_required: if and only if `os.name` is `ios` + # note: > + # The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), + # and from which the `OS terminology` column values are derived. + # brief: > + # This attribute represents the state the application has transitioned into at the occurrence of the event. + # type: + # allow_custom_values: false + # members: + # - id: active + # value: 'active' + # brief: > + # The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + # - id: inactive + # value: 'inactive' + # brief: > + # The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + # - id: background + # value: 'background' + # brief: > + # The app is now in the background. + # This value is associated with UIKit notification `applicationDidEnterBackground`. + # - id: foreground + # value: 'foreground' + # brief: > + # The app is now in the foreground. + # This value is associated with UIKit notification `applicationWillEnterForeground`. + # - id: terminate + # value: 'terminate' + # brief: > + # The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + # - id: android.state + # stability: experimental + # requirement_level: + # conditional_required: if and only if `os.name` is `android` + # brief: > + # This attribute represents the state the application has transitioned into at the occurrence of the event. + # note: > + # The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + # and from which the `OS identifiers` are derived. + # type: + # allow_custom_values: false + # members: + # - id: created + # value: 'created' + # brief: > + # Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + # has been called in the app for the first time. + # - id: background + # value: 'background' + # brief: > + # Any time after Activity.onPause() or, if the app has no Activity, + # Context.stopService() has been called when the app was in the foreground state. + # - id: foreground + # value: 'foreground' + # brief: > + # Any time after Activity.onResume() or, if the app has no Activity, + # Context.startService() has been called when the app was in either the created or background states. diff --git a/model/registry/android.yaml b/model/registry/android.yaml index bddc74a09a..cfdcac8a46 100644 --- a/model/registry/android.yaml +++ b/model/registry/android.yaml @@ -13,37 +13,3 @@ groups: (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). examples: ['33', '32'] - - id: registry.android.lifecycle.events - prefix: android - type: attribute_group - brief: > - This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. - attributes: - - id: state - stability: experimental - brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. - note: > - The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), - and from which the `OS identifiers` are derived. - type: - allow_custom_values: true - members: - - id: created - value: 'created' - brief: > - Any time before Activity.onResume() or, if the app has no Activity, Context.startService() - has been called in the app for the first time. - stability: experimental - - id: background - value: 'background' - brief: > - Any time after Activity.onPause() or, if the app has no Activity, - Context.stopService() has been called when the app was in the foreground state. - stability: experimental - - id: foreground - value: 'foreground' - brief: > - Any time after Activity.onResume() or, if the app has no Activity, - Context.startService() has been called when the app was in either the created or background states. - stability: experimental diff --git a/model/registry/deprecated/android.yaml b/model/registry/deprecated/android.yaml new file mode 100644 index 0000000000..97e9bd1e7a --- /dev/null +++ b/model/registry/deprecated/android.yaml @@ -0,0 +1,36 @@ +groups: + - id: registry.android.deprecated + prefix: android + type: attribute_group + brief: > + This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. + attributes: + - id: state + stability: experimental + brief: > + Deprecated use the `device.app.lifecycle` event definition including + `android.state` as a payload field instead. + note: > + The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), + and from which the `OS identifiers` are derived. + type: + allow_custom_values: true + members: + - id: created + value: 'created' + brief: > + Any time before Activity.onResume() or, if the app has no Activity, Context.startService() + has been called in the app for the first time. + stability: experimental + - id: background + value: 'background' + brief: > + Any time after Activity.onPause() or, if the app has no Activity, + Context.stopService() has been called when the app was in the foreground state. + stability: experimental + - id: foreground + value: 'foreground' + brief: > + Any time after Activity.onResume() or, if the app has no Activity, + Context.startService() has been called when the app was in either the created or background states. + stability: experimental diff --git a/model/registry/ios.yaml b/model/registry/deprecated/ios.yaml similarity index 88% rename from model/registry/ios.yaml rename to model/registry/deprecated/ios.yaml index 1bfe30f325..acc1a9f1f9 100644 --- a/model/registry/ios.yaml +++ b/model/registry/deprecated/ios.yaml @@ -1,5 +1,5 @@ groups: - - id: registry.ios.lifecycle.events + - id: registry.ios.deprecated prefix: ios type: attribute_group brief: > @@ -7,11 +7,13 @@ groups: attributes: - id: state stability: experimental + deprecated: "Moved to a payload field of `device.app.lifecycle`." note: > The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. brief: > - This attribute represents the state the application has transitioned into at the occurrence of the event. + Deprecated use the `device.app.lifecycle` event definition including + `ios.state` as a payload field instead. type: allow_custom_values: true members: From c0e170d51e02dfd68d48a766f258895a55ee87da Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:39:10 -0700 Subject: [PATCH 461/482] Add db.client.operation.duration metric (#735) Co-authored-by: Trask Stalnaker Co-authored-by: Liudmila Molkova --- .chloggen/735.yaml | 22 ++++++ docs/database/database-metrics.md | 110 ++++++++++++++++++++++++++++ model/metrics/database-metrics.yaml | 9 +++ 3 files changed, 141 insertions(+) create mode 100644 .chloggen/735.yaml diff --git a/.chloggen/735.yaml b/.chloggen/735.yaml new file mode 100644 index 0000000000..e28402e049 --- /dev/null +++ b/.chloggen/735.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add `db.client.operation.duration` metric + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [512] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index d779bc7a6d..ccf76a54b1 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -15,6 +15,8 @@ and attributes but more may be added in the future. +- [Database operation](#database-operation) + - [Metric: `db.client.operation.duration`](#metric-dbclientoperationduration) - [Connection pools](#connection-pools) - [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) - [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) @@ -35,6 +37,114 @@ and attributes but more may be added in the future. > until a transition plan to the (future) stable semantic conventions has been published. > Conventions include, but are not limited to, attributes, metric and span names, and unit of measure. +## Database operation + +### Metric: `db.client.operation.duration` + +**Status**: [Experimental][DocumentStatus] + +This metric is [required][MetricRequired]. + +When this metric is reported alongside a database operation span, the metric value SHOULD be the same as the database operation span duration. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `db.client.operation.duration` | Histogram | `s` | Duration of database client operations. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [7] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + +**[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. + +**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. + +**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[7]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +`db.system` 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 | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + ## Connection pools The following metric instruments describe database client connection pool operations. diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index cce9257e4f..ec8f61c55c 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -1,4 +1,13 @@ groups: + - id: metric.db.client.operation.duration + type: metric + metric_name: db.client.operation.duration + brief: "Duration of database client operations." + instrument: histogram + unit: "s" + stability: experimental + extends: attributes.db.client + - id: metric.db.client.connections.usage type: metric metric_name: db.client.connections.usage From dd73dba5ac55bd4e6adca0ac5ff217818923c241 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 23 Apr 2024 02:47:35 -0700 Subject: [PATCH 462/482] Should -> SHOULD (#946) Co-authored-by: Armin Ruech <7052238+arminru@users.noreply.github.com> --- docs/database/database-spans.md | 2 +- docs/database/redis.md | 2 +- model/trace/database.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 275ae4e5a9..15a6080f17 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -96,7 +96,7 @@ These attributes will usually be the same for all operations performed over the **[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[7]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[7]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. **[8]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/database/redis.md b/docs/database/redis.md index 27b9e0461d..052c0a8048 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -24,7 +24,7 @@ described on this page. **[1]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. -**[2]:** Should be collected by default only if there is sanitization that excludes sensitive information. +**[2]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. **[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/model/trace/database.yaml b/model/trace/database.yaml index d42d1c6b68..e0f6aee6c5 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -7,7 +7,7 @@ groups: - ref: db.query.text requirement_level: recommended: > - Should be collected by default only if there is sanitization that excludes sensitive information. + SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in From 8d6f12bd82a28f827d5efce7b70fc413659fb212 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:30:22 +0200 Subject: [PATCH 463/482] Clarify fully-qualified name should be used for `error.type` (#945) Co-authored-by: Liudmila Molkova --- docs/attributes-registry/error.md | 6 +++++- docs/dotnet/dotnet-aspnetcore-metrics.md | 6 +++++- docs/messaging/messaging-metrics.md | 6 +++++- docs/messaging/messaging-spans.md | 6 +++++- model/registry/error.yaml | 6 +++++- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/attributes-registry/error.md b/docs/attributes-registry/error.md index 1b43a77600..a97583c0f4 100644 --- a/docs/attributes-registry/error.md +++ b/docs/attributes-registry/error.md @@ -10,7 +10,11 @@ |---|---|---|---|---| | `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index d2b8491d18..edcd0615ef 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -79,7 +79,11 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index a92f357914..6d3f8da201 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -40,7 +40,11 @@ All messaging metrics share the same set of attributes: | [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 4b4f450e5c..1b83775077 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -308,7 +308,11 @@ as described in [Attributes specific to certain messaging systems](#attributes-s **[1]:** If a custom value is used, it MUST be of low cardinality. -**[2]:** The `error.type` SHOULD be predictable and SHOULD have low cardinality. +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. diff --git a/model/registry/error.yaml b/model/registry/error.yaml index 9864db9ce3..68bde170ba 100644 --- a/model/registry/error.yaml +++ b/model/registry/error.yaml @@ -19,7 +19,11 @@ groups: A fallback error value to be used when the instrumentation doesn't define a custom value. examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500'] note: | - The `error.type` SHOULD be predictable and SHOULD have low cardinality. + The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + + When `error.type` is set to a type (e.g., an exception type), its + canonical class name identifying the type within the artifact SHOULD be used. + Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. From 6af1ab47a81cb4a7610b77f46901422c29f69c15 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 23 Apr 2024 18:06:15 -0700 Subject: [PATCH 464/482] Fix markdown status of exceptions (#951) --- docs/exceptions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/exceptions/README.md b/docs/exceptions/README.md index 5791b59882..91f6c88305 100644 --- a/docs/exceptions/README.md +++ b/docs/exceptions/README.md @@ -7,7 +7,7 @@ path_base_for_github_subdir: # Semantic Conventions for Exceptions -**Status**: [Experimental][DocumentStatus] +**Status**: [Stable][DocumentStatus] This document defines semantic conventions for Exceptions. From 83369f23dd091ca205f432a310493b38402130e4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 06:21:16 -0700 Subject: [PATCH 465/482] [chore] Split db and messaging registry groups (#952) --- docs/attributes-registry/db.md | 12 +- docs/attributes-registry/messaging.md | 16 +- model/registry/db.yaml | 440 +++++++++++++------------- model/registry/messaging.yaml | 225 +++++++------ 4 files changed, 347 insertions(+), 346 deletions(-) diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 5940f91d71..57f2d98a46 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -18,7 +18,7 @@ ## Generic Database Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -105,7 +105,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Cassandra Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -134,7 +134,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## CosmosDB Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -175,7 +175,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Elasticsearch Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -186,7 +186,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## MSSQL Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -196,7 +196,7 @@ If a parameter has no name and instead is referenced only by index, then `` ## Redis Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 7e83f76a3c..b41d340165 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -18,7 +18,7 @@ ## Generic Messaging Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -84,7 +84,7 @@ size should be used. ## GCP Pub/Sub Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -92,7 +92,7 @@ size should be used. ## Kafka Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -105,7 +105,7 @@ size should be used. ## RabbitMQ Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -114,7 +114,7 @@ size should be used. ## RocketMQ Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -146,7 +146,7 @@ size should be used. ## Azure Event Hubs Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -155,7 +155,7 @@ size should be used. ## Azure Service Bus Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -175,7 +175,7 @@ size should be used. ## Deprecated Messaging Attributes - + | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `messaging.kafka.destination.partition` | int | Deprecated, use `messaging.destination.partition.id` instead. | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 25532ab6a4..293ec073fb 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -3,82 +3,8 @@ groups: prefix: db type: attribute_group brief: > - This document defines the attributes used to describe telemetry in the context of databases. + This group defines the attributes used to describe telemetry in the context of databases. attributes: - - id: cassandra.coordinator.dc - type: string - stability: experimental - brief: > - The data center of the coordinating node for a query. - examples: 'us-west-2' - tag: tech-specific-cassandra - - id: cassandra.coordinator.id - type: string - stability: experimental - brief: > - The ID of the coordinating node for a query. - examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' - tag: tech-specific-cassandra - - id: cassandra.consistency_level - brief: > - The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). - type: - members: - - id: all - value: 'all' - stability: experimental - - id: each_quorum - value: 'each_quorum' - stability: experimental - - id: quorum - value: 'quorum' - stability: experimental - - id: local_quorum - value: 'local_quorum' - stability: experimental - - id: one - value: 'one' - stability: experimental - - id: two - value: 'two' - stability: experimental - - id: three - value: 'three' - stability: experimental - - id: local_one - value: 'local_one' - stability: experimental - - id: any - value: 'any' - stability: experimental - - id: serial - value: 'serial' - stability: experimental - - id: local_serial - value: 'local_serial' - stability: experimental - stability: experimental - tag: tech-specific-cassandra - - id: cassandra.idempotence - type: boolean - stability: experimental - brief: > - Whether or not the query is idempotent. - tag: tech-specific-cassandra - - id: cassandra.page_size - type: int - stability: experimental - brief: > - The fetch size used for paging, i.e. how many rows will be returned at once. - examples: [5000] - tag: tech-specific-cassandra - - id: cassandra.speculative_execution_count - type: int - stability: experimental - brief: > - The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. - examples: [0, 2] - tag: tech-specific-cassandra - id: collection.name type: string stability: experimental @@ -86,134 +12,7 @@ groups: note: > If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. - tag: db-generic examples: ['public.users', 'customers'] - - id: cosmosdb.client_id - type: string - stability: experimental - brief: Unique Cosmos client instance id. - examples: '3ba4827d-4422-483f-b59f-85b74211c11d' - tag: tech-specific-cosmosdb - - id: cosmosdb.connection_mode - type: - allow_custom_values: false - members: - - id: gateway - value: 'gateway' - brief: Gateway (HTTP) connections mode - stability: experimental - - id: direct - value: 'direct' - brief: Direct connection. - stability: experimental - stability: experimental - brief: Cosmos client connection mode. - tag: tech-specific-cosmosdb - - id: cosmosdb.operation_type - type: - allow_custom_values: true - members: - - id: invalid - value: 'Invalid' - stability: experimental - - id: create - value: 'Create' - stability: experimental - - id: patch - value: 'Patch' - stability: experimental - - id: read - value: 'Read' - stability: experimental - - id: read_feed - value: 'ReadFeed' - stability: experimental - - id: delete - value: 'Delete' - stability: experimental - - id: replace - value: 'Replace' - stability: experimental - - id: execute - value: 'Execute' - stability: experimental - - id: query - value: 'Query' - stability: experimental - - id: head - value: 'Head' - stability: experimental - - id: head_feed - value: 'HeadFeed' - stability: experimental - - id: upsert - value: 'Upsert' - stability: experimental - - id: batch - value: 'Batch' - stability: experimental - - id: query_plan - value: 'QueryPlan' - stability: experimental - - id: execute_javascript - value: 'ExecuteJavaScript' - stability: experimental - stability: experimental - brief: CosmosDB Operation Type. - tag: tech-specific-cosmosdb - - id: cosmosdb.request_charge - type: double - stability: experimental - brief: RU consumed for that operation - examples: [46.18, 1.0] - tag: tech-specific-cosmosdb - - id: cosmosdb.request_content_length - type: int - stability: experimental - brief: Request payload size in bytes - tag: tech-specific-cosmosdb - - id: cosmosdb.status_code - type: int - stability: experimental - brief: Cosmos DB status code. - examples: [200, 201] - tag: tech-specific-cosmosdb - - id: cosmosdb.sub_status_code - type: int - stability: experimental - brief: Cosmos DB sub status code. - examples: [1000, 1002] - tag: tech-specific-cosmosdb - - id: elasticsearch.cluster.name - type: string - stability: experimental - brief: > - Represents the identifier of an Elasticsearch cluster. - examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] - tag: tech-specific-elasticsearch - - id: elasticsearch.path_parts - type: template[string] - stability: experimental - brief: > - A dynamic value in the url path. - note: > - Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format - `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD - reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) - in order to map the path part values to their names. - examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - tag: tech-specific-elasticsearch - - id: mssql.instance_name - type: string - stability: experimental - note: > - If setting a `db.mssql.instance_name`, `server.port` is no longer - required (but still recommended if non-standard). - brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) - connecting to. This name is used to determine the port of a named instance. - examples: 'MSSQLSERVER' - tag: tech-specific-mssql - id: name type: string stability: experimental @@ -227,29 +26,18 @@ groups: (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). examples: [ 'customers', 'main' ] - tag: db-generic - id: operation.name type: string stability: experimental brief: > The name of the operation or command being executed. examples: ['findAndModify', 'HMSET', 'SELECT'] - tag: db-generic - - id: redis.database_index - type: int - stability: experimental - brief: > - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. - To be used instead of the generic `db.name` attribute. - examples: [0, 1, 15] - tag: tech-specific-redis - id: query.text type: string stability: experimental brief: > The database query being executed. examples: ['SELECT * FROM wuser_table where username = ?', 'SET mykey "WuValue"'] - tag: db-generic - id: query.parameter type: template[string] stability: experimental @@ -262,7 +50,6 @@ groups: If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. examples: ['someval', '55'] - tag: db-generic - id: system brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. type: @@ -477,9 +264,7 @@ groups: brief: 'Trino' stability: experimental stability: experimental - tag: db-generic - id: instance.id - tag: db-generic type: string stability: experimental brief: > @@ -488,7 +273,6 @@ groups: The client may obtain this value in databases like MySQL using queries like `select @@hostname`. examples: 'mysql-e26b99z.example.com' - id: client.connections.state - tag: db-generic stability: experimental type: allow_custom_values: true @@ -502,7 +286,6 @@ groups: brief: "The state of a connection in the pool" examples: ["idle"] - id: client.connections.pool.name - tag: db-generic type: string stability: experimental brief: > @@ -511,3 +294,224 @@ groups: instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. examples: ["myDataSource"] + - id: registry.db.cassandra + prefix: db + type: attribute_group + brief: > + This group defines attributes for Cassandra. + attributes: + - id: cassandra.coordinator.dc + type: string + stability: experimental + brief: > + The data center of the coordinating node for a query. + examples: 'us-west-2' + - id: cassandra.coordinator.id + type: string + stability: experimental + brief: > + The ID of the coordinating node for a query. + examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + - id: cassandra.consistency_level + brief: > + The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + type: + members: + - id: all + value: 'all' + stability: experimental + - id: each_quorum + value: 'each_quorum' + stability: experimental + - id: quorum + value: 'quorum' + stability: experimental + - id: local_quorum + value: 'local_quorum' + stability: experimental + - id: one + value: 'one' + stability: experimental + - id: two + value: 'two' + stability: experimental + - id: three + value: 'three' + stability: experimental + - id: local_one + value: 'local_one' + stability: experimental + - id: any + value: 'any' + stability: experimental + - id: serial + value: 'serial' + stability: experimental + - id: local_serial + value: 'local_serial' + stability: experimental + stability: experimental + - id: cassandra.idempotence + type: boolean + stability: experimental + brief: > + Whether or not the query is idempotent. + - id: cassandra.page_size + type: int + stability: experimental + brief: > + The fetch size used for paging, i.e. how many rows will be returned at once. + examples: [5000] + - id: cassandra.speculative_execution_count + type: int + stability: experimental + brief: > + The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + examples: [0, 2] + - id: registry.db.cosmosdb + prefix: db + type: attribute_group + brief: > + This group defines attributes for Azure Cosmos DB. + attributes: + - id: cosmosdb.client_id + type: string + stability: experimental + brief: Unique Cosmos client instance id. + examples: '3ba4827d-4422-483f-b59f-85b74211c11d' + - id: cosmosdb.connection_mode + type: + allow_custom_values: false + members: + - id: gateway + value: 'gateway' + brief: Gateway (HTTP) connections mode + stability: experimental + - id: direct + value: 'direct' + brief: Direct connection. + stability: experimental + stability: experimental + brief: Cosmos client connection mode. + - id: cosmosdb.operation_type + type: + allow_custom_values: true + members: + - id: invalid + value: 'Invalid' + stability: experimental + - id: create + value: 'Create' + stability: experimental + - id: patch + value: 'Patch' + stability: experimental + - id: read + value: 'Read' + stability: experimental + - id: read_feed + value: 'ReadFeed' + stability: experimental + - id: delete + value: 'Delete' + stability: experimental + - id: replace + value: 'Replace' + stability: experimental + - id: execute + value: 'Execute' + stability: experimental + - id: query + value: 'Query' + stability: experimental + - id: head + value: 'Head' + stability: experimental + - id: head_feed + value: 'HeadFeed' + stability: experimental + - id: upsert + value: 'Upsert' + stability: experimental + - id: batch + value: 'Batch' + stability: experimental + - id: query_plan + value: 'QueryPlan' + stability: experimental + - id: execute_javascript + value: 'ExecuteJavaScript' + stability: experimental + stability: experimental + brief: CosmosDB Operation Type. + - id: cosmosdb.request_charge + type: double + stability: experimental + brief: RU consumed for that operation + examples: [46.18, 1.0] + - id: cosmosdb.request_content_length + type: int + stability: experimental + brief: Request payload size in bytes + - id: cosmosdb.status_code + type: int + stability: experimental + brief: Cosmos DB status code. + examples: [200, 201] + - id: cosmosdb.sub_status_code + type: int + stability: experimental + brief: Cosmos DB sub status code. + examples: [1000, 1002] + - id: registry.db.elasticsearch + prefix: db + type: attribute_group + brief: > + This group defines attributes for Elasticsearch. + attributes: + - id: elasticsearch.cluster.name + type: string + stability: experimental + brief: > + Represents the identifier of an Elasticsearch cluster. + examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + - id: elasticsearch.path_parts + type: template[string] + stability: experimental + brief: > + A dynamic value in the url path. + note: > + Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format + `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD + reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) + in order to map the path part values to their names. + examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] + - id: registry.db.mssql + prefix: db + type: attribute_group + brief: > + This group defines attributes for Microsoft SQL Server. + attributes: + - id: mssql.instance_name + type: string + stability: experimental + note: > + If setting a `db.mssql.instance_name`, `server.port` is no longer + required (but still recommended if non-standard). + brief: > + The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) + connecting to. This name is used to determine the port of a named instance. + examples: 'MSSQLSERVER' + - id: registry.db.redis + prefix: db + type: attribute_group + brief: > + This group defines attributes for Redis. + attributes: + - id: redis.database_index + type: int + stability: experimental + brief: > + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. + To be used instead of the generic `db.name` attribute. + examples: [0, 1, 15] diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 32e603d1dc..4a2c6a2714 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -13,14 +13,12 @@ groups: When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. examples: [0, 1, 2] - tag: messaging-generic - id: client_id type: string stability: experimental brief: > A unique identifier for the client that consumes or produces a message. examples: ['client-5', 'myhost@8742@s8083jm'] - tag: messaging-generic - id: destination.name type: string stability: experimental @@ -29,7 +27,6 @@ groups: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - tag: messaging-generic - id: destination.template type: string stability: experimental @@ -41,22 +38,18 @@ groups: the underlying template is of low cardinality and can be effectively used for grouping and aggregation. examples: ['/customers/{customerId}'] - tag: messaging-generic - id: destination.anonymous type: boolean stability: experimental brief: 'A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).' - tag: messaging-generic - id: destination.temporary type: boolean stability: experimental brief: 'A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.' - tag: messaging-generic - id: destination_publish.anonymous type: boolean stability: experimental brief: 'A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).' - tag: messaging-generic - id: destination_publish.name type: string stability: experimental @@ -65,46 +58,12 @@ groups: The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. examples: ['MyQueue', 'MyTopic'] - tag: messaging-generic - id: destination.partition.id type: string stability: experimental brief: > The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. examples: '1' - tag: messaging-generic - - id: kafka.consumer.group - type: string - stability: experimental - brief: > - Name of the Kafka Consumer Group that is handling the message. - Only applies to consumers, not producers. - examples: 'my-group' - tag: tech-specific-kafka - - id: kafka.message.key - type: string - stability: experimental - brief: > - Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. - They differ from `messaging.message.id` in that they're not unique. - If the key is `null`, the attribute MUST NOT be set. - note: > - If the key type is not string, it's string representation has to be supplied for the attribute. - If the key has no unambiguous, canonical string form, don't include its value. - examples: 'myKey' - tag: tech-specific-kafka - - id: kafka.message.offset - type: int - stability: experimental - brief: > - The offset of a record in the corresponding Kafka partition. - examples: 42 - tag: tech-specific-kafka - - id: kafka.message.tombstone - type: boolean - stability: experimental - brief: 'A boolean that is true if the message is a tombstone.' - tag: tech-specific-kafka - id: message.conversation_id type: string stability: experimental @@ -112,7 +71,6 @@ groups: The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". examples: 'MyConversationId' - tag: messaging-generic - id: message.envelope.size type: int stability: experimental @@ -122,13 +80,11 @@ groups: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. examples: 2738 - tag: messaging-generic - id: message.id type: string stability: experimental brief: 'A value used by the messaging system as an identifier for the message, represented as a string.' examples: '452a7c7c7c7048c2f887f61572b18fc2' - tag: messaging-generic - id: message.body.size type: int stability: experimental @@ -138,7 +94,6 @@ groups: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. examples: 1439 - tag: messaging-generic - id: operation.type type: allow_custom_values: true @@ -175,36 +130,123 @@ groups: brief: > A string identifying the type of the messaging operation. note: If a custom value is used, it MUST be of low cardinality. - tag: messaging-generic - id: operation.name type: string stability: experimental brief: > The system-specific name of the messaging operation. examples: [ "ack", "nack", "send" ] - tag: messaging-generic + - id: system + brief: > + An identifier for the messaging system being used. See below for a list of well-known identifiers. + type: + allow_custom_values: true + members: + - id: activemq + value: 'activemq' + brief: 'Apache ActiveMQ' + stability: experimental + - id: aws_sqs + value: 'aws_sqs' + brief: 'Amazon Simple Queue Service (SQS)' + stability: experimental + - id: eventgrid + value: 'eventgrid' + brief: 'Azure Event Grid' + stability: experimental + - id: eventhubs + value: 'eventhubs' + brief: 'Azure Event Hubs' + stability: experimental + - id: servicebus + value: 'servicebus' + brief: 'Azure Service Bus' + stability: experimental + - id: gcp_pubsub + value: 'gcp_pubsub' + brief: 'Google Cloud Pub/Sub' + stability: experimental + - id: jms + value: 'jms' + brief: 'Java Message Service' + stability: experimental + - id: kafka + value: 'kafka' + brief: 'Apache Kafka' + stability: experimental + - id: rabbitmq + value: 'rabbitmq' + brief: 'RabbitMQ' + stability: experimental + - id: rocketmq + value: 'rocketmq' + brief: 'Apache RocketMQ' + stability: experimental + stability: experimental + - id: registry.messaging.kafka + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Apache Kafka. + attributes: + - id: kafka.consumer.group + type: string + stability: experimental + brief: > + Name of the Kafka Consumer Group that is handling the message. + Only applies to consumers, not producers. + examples: 'my-group' + - id: kafka.message.key + type: string + stability: experimental + brief: > + Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. + They differ from `messaging.message.id` in that they're not unique. + If the key is `null`, the attribute MUST NOT be set. + note: > + If the key type is not string, it's string representation has to be supplied for the attribute. + If the key has no unambiguous, canonical string form, don't include its value. + examples: 'myKey' + - id: kafka.message.offset + type: int + stability: experimental + brief: > + The offset of a record in the corresponding Kafka partition. + examples: 42 + - id: kafka.message.tombstone + type: boolean + stability: experimental + brief: 'A boolean that is true if the message is a tombstone.' + - id: registry.messaging.rabbitmq + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to RabbitMQ. + attributes: - id: rabbitmq.destination.routing_key type: string stability: experimental brief: > RabbitMQ message routing key. examples: 'myKey' - tag: tech-specific-rabbitmq - id: rabbitmq.message.delivery_tag type: int stability: experimental brief: > RabbitMQ message delivery tag examples: 123 - tag: tech-specific-rabbitmq - + - id: registry.messaging.rocketmq + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to RocketMQ. + attributes: - id: rocketmq.client_group type: string stability: experimental brief: > Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. examples: 'myConsumerGroup' - tag: tech-specific-rocketmq - id: rocketmq.consumption_model type: allow_custom_values: false @@ -220,42 +262,36 @@ groups: stability: experimental brief: > Model of message consumption. This only applies to consumer spans. - tag: tech-specific-rocketmq - id: rocketmq.message.delay_time_level type: int stability: experimental brief: > The delay time level for delay message, which determines the message delay time. examples: 3 - tag: tech-specific-rocketmq - id: rocketmq.message.delivery_timestamp type: int stability: experimental brief: > The timestamp in milliseconds that the delay message is expected to be delivered to consumer. examples: 1665987217045 - tag: tech-specific-rocketmq - id: rocketmq.message.group type: string stability: experimental brief: > It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. examples: 'myMessageGroup' - tag: tech-specific-rocketmq - id: rocketmq.message.keys type: string[] stability: experimental brief: > Key(s) of message, another way to mark message besides message id. examples: ['keyA', 'keyB'] - tag: tech-specific-rocketmq - id: rocketmq.message.tag type: string stability: experimental brief: > The secondary classifier of message besides topic. examples: tagA - tag: tech-specific-rocketmq - id: rocketmq.message.type type: allow_custom_values: false @@ -279,90 +315,48 @@ groups: stability: experimental brief: > Type of message. - tag: tech-specific-rocketmq - id: rocketmq.namespace type: string stability: experimental brief: > Namespace of RocketMQ resources, resources in different namespaces are individual. examples: 'myNamespace' - tag: tech-specific-rocketmq + - id: registry.messaging.gcp_pubsub + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to GCP Pub/Sub. + attributes: - id: gcp_pubsub.message.ordering_key type: string stability: experimental brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' - tag: tech-specific-gcp-pubsub - - id: system - brief: > - An identifier for the messaging system being used. See below for a list of well-known identifiers. - type: - allow_custom_values: true - members: - - id: activemq - value: 'activemq' - brief: 'Apache ActiveMQ' - stability: experimental - - id: aws_sqs - value: 'aws_sqs' - brief: 'Amazon Simple Queue Service (SQS)' - stability: experimental - - id: eventgrid - value: 'eventgrid' - brief: 'Azure Event Grid' - stability: experimental - - id: eventhubs - value: 'eventhubs' - brief: 'Azure Event Hubs' - stability: experimental - - id: servicebus - value: 'servicebus' - brief: 'Azure Service Bus' - stability: experimental - - id: gcp_pubsub - value: 'gcp_pubsub' - brief: 'Google Cloud Pub/Sub' - stability: experimental - - id: jms - value: 'jms' - brief: 'Java Message Service' - stability: experimental - - id: kafka - value: 'kafka' - brief: 'Apache Kafka' - stability: experimental - - id: rabbitmq - value: 'rabbitmq' - brief: 'RabbitMQ' - stability: experimental - - id: rocketmq - value: 'rocketmq' - brief: 'Apache RocketMQ' - stability: experimental - stability: experimental - tag: messaging-generic + - id: registry.messaging.servicebus + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Azure Service Bus. + attributes: - id: servicebus.message.delivery_count type: int stability: experimental brief: > Number of deliveries that have been attempted for this message. examples: 2 - tag: tech-specific-servicebus - id: servicebus.message.enqueued_time type: int stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 - tag: tech-specific-servicebus - id: servicebus.destination.subscription_name type: string stability: experimental brief: > The name of the subscription in the topic messages are received from. examples: "mySubscription" - tag: tech-specific-servicebus - id: servicebus.disposition_status brief: > Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). @@ -386,18 +380,21 @@ groups: brief: 'Message is deferred' stability: experimental stability: experimental - tag: tech-specific-servicebus + - id: registry.messaging.eventhubs + prefix: messaging + type: attribute_group + brief: > + This group describes attributes specific to Azure Event Hubs. + attributes: - id: eventhubs.message.enqueued_time type: int stability: experimental brief: > The UTC epoch seconds at which the message has been accepted and stored in the entity. examples: 1701393730 - tag: tech-specific-eventhubs - id: eventhubs.consumer.group type: string stability: experimental brief: > The name of the consumer group the event consumer is associated with. examples: 'indexer' - tag: tech-specific-eventhubs From a28fa9e62eca17c2a470d25a13a49811fa58b29c Mon Sep 17 00:00:00 2001 From: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:32:01 +0200 Subject: [PATCH 466/482] [chore] fix type of registry groups (#957) Co-authored-by: Liudmila Molkova --- model/registry/aws.yaml | 2 +- model/registry/otel.yaml | 2 +- model/registry/peer.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/model/registry/aws.yaml b/model/registry/aws.yaml index 6214375852..90bb10b853 100644 --- a/model/registry/aws.yaml +++ b/model/registry/aws.yaml @@ -315,7 +315,7 @@ groups: examples: ["8", "26"] - id: registry.aws.eks prefix: aws.eks - type: resource + type: attribute_group brief: > This document defines attributes for AWS Elastic Kubernetes Service (EKS). attributes: diff --git a/model/registry/otel.yaml b/model/registry/otel.yaml index 7da6ece282..76286cdc9b 100644 --- a/model/registry/otel.yaml +++ b/model/registry/otel.yaml @@ -25,7 +25,7 @@ groups: stability: stable - id: registry.otel.scope prefix: otel.scope - type: resource + type: attribute_group brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. attributes: - id: name diff --git a/model/registry/peer.yaml b/model/registry/peer.yaml index 58ee700904..a6e38a129d 100644 --- a/model/registry/peer.yaml +++ b/model/registry/peer.yaml @@ -1,6 +1,6 @@ groups: - id: registry.peer - type: span + type: attribute_group prefix: peer brief: > Operations that access some remote service. From 7c09a909b5da756a0823c49da437c4b6a5508d57 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 24 Apr 2024 12:40:31 -0400 Subject: [PATCH 467/482] =?UTF-8?q?(chore)=20Remove=20common=20attributes?= =?UTF-8?q?=20from=20RPC=20documentation=20in=20favor=20of=20f=E2=80=A6=20?= =?UTF-8?q?(#960)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rpc/rpc-spans.md | 103 ++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 387f5b56b1..f38c76f0b7 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -15,8 +15,7 @@ This document defines how to describe remote procedure calls - [Common remote procedure call conventions](#common-remote-procedure-call-conventions) - [Span name](#span-name) - - [Common attributes](#common-attributes) - - [Service name](#service-name) + - [Service name](#service-name) - [Client attributes](#client-attributes) - [Server attributes](#server-attributes) - [Events](#events) @@ -79,14 +78,30 @@ Examples of span names: `MyServiceReference.ICalculator/Add` reported by the client for .NET WCF calls - `MyServiceWithNoPackage/theMethod` -### Common attributes +### Service name - +On the server process receiving and handling the remote procedure call, the service name provided in `rpc.service` does not necessarily have to match the [`service.name`][] resource attribute. +One process can expose multiple RPC endpoints and thus have multiple RPC service names. From a deployment perspective, as expressed by the `service.*` resource attributes, it will be treated as one deployed service with one `service.name`. +Likewise, on clients sending RPC requests to a server, the service name provided in `rpc.service` does not have to match the [`peer.service`][] span attribute. + +As an example, given a process deployed as `QuoteService`, this would be the name that goes into the `service.name` resource attribute which applies to the entire process. +This process could expose two RPC endpoints, one called `CurrencyQuotes` (= `rpc.service`) with a method called `getMeanRate` (= `rpc.method`) and the other endpoint called `StockQuotes` (= `rpc.service`) with two methods `getCurrentBid` and `getLastClose` (= `rpc.method`). +In this example, spans representing client request should have their `peer.service` attribute set to `QuoteService` as well to match the server's `service.name` resource attribute. +Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service name. + +[`service.name`]: /docs/resource/README.md#service +[`peer.service`]: /docs/general/attributes.md#general-remote-service-attributes + +### Client attributes + + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -137,52 +152,70 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -#### Service name - -On the server process receiving and handling the remote procedure call, the service name provided in `rpc.service` does not necessarily have to match the [`service.name`][] resource attribute. -One process can expose multiple RPC endpoints and thus have multiple RPC service names. From a deployment perspective, as expressed by the `service.*` resource attributes, it will be treated as one deployed service with one `service.name`. -Likewise, on clients sending RPC requests to a server, the service name provided in `rpc.service` does not have to match the [`peer.service`][] span attribute. - -As an example, given a process deployed as `QuoteService`, this would be the name that goes into the `service.name` resource attribute which applies to the entire process. -This process could expose two RPC endpoints, one called `CurrencyQuotes` (= `rpc.service`) with a method called `getMeanRate` (= `rpc.method`) and the other endpoint called `StockQuotes` (= `rpc.service`) with two methods `getCurrentBid` and `getLastClose` (= `rpc.method`). -In this example, spans representing client request should have their `peer.service` attribute set to `QuoteService` as well to match the server's `service.name` resource attribute. -Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service name. - -[`service.name`]: /docs/resource/README.md#service -[`peer.service`]: /docs/general/attributes.md#general-remote-service-attributes - -### Client attributes +### Server attributes - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| +| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](../attributes-registry/client.md) | int | Client port number. [5] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - +| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [7] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [8] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [9] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Server attributes +**[1]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. - -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +**[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[3]:** if the port is supported by the network transport used for communication. + +**[4]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[5]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[3]:** The value SHOULD be normalized to lowercase. +**[6]:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[4]:** The value SHOULD be normalized to lowercase. +**[7]:** The value SHOULD be normalized to lowercase. + +**[8]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[9]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`network.transport` 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 | Stability | +|---|---|---| +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`network.type` 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 | Stability | +|---|---|---| +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Events From d1a2d487c1951deecaa39552520a8d4060a59b47 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 10:32:38 -0700 Subject: [PATCH 468/482] Move .NET-specific attributes to the registry (#943) --- .github/CODEOWNERS | 10 +- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 2 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 2 + docs/attributes-registry/aspnetcore.md | 46 ++++++++ docs/attributes-registry/signalr.md | 32 ++++++ docs/dotnet/dotnet-aspnetcore-metrics.md | 22 ++-- docs/dotnet/dotnet-signalr-metrics.md | 8 +- model/metrics/dotnet/dotnet-aspnetcore.yaml | 111 +++----------------- model/metrics/dotnet/dotnet-signalr.yaml | 43 -------- model/registry/aspnetcore.yaml | 90 ++++++++++++++++ model/registry/signalr.yaml | 43 ++++++++ 12 files changed, 251 insertions(+), 160 deletions(-) create mode 100644 docs/attributes-registry/aspnetcore.md create mode 100644 docs/attributes-registry/signalr.md create mode 100644 model/registry/aspnetcore.yaml create mode 100644 model/registry/signalr.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 185fedbfdb..0b1b2e4672 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -76,11 +76,15 @@ # .NET semantic conventions approvers /model/metrics/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers -/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/model/registry/aspnetcore.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/model/registry/signalr.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/attributes-registry/aspnetcore.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers +/docs/attributes-registry/signalr.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers # Gen-AI semantic conventions approvers -/model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers -/model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers +/model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /model/trace/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /docs/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /docs/attributes-registry/llm.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 896738c60c..32e7e1299c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -20,6 +20,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -60,6 +61,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index ca2933bc38..b800c0e341 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -13,6 +13,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -53,6 +54,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 1c1afe1779..08421ab61d 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -22,6 +22,7 @@ body: # DO NOT manually edit it. # Start semconv area list - area:android + - area:aspnetcore - area:aws - area:browser - area:client @@ -62,6 +63,7 @@ body: - area:server - area:service - area:session + - area:signalr - area:source - area:system - area:telemetry diff --git a/docs/attributes-registry/aspnetcore.md b/docs/attributes-registry/aspnetcore.md new file mode 100644 index 0000000000..533eae5635 --- /dev/null +++ b/docs/attributes-registry/aspnetcore.md @@ -0,0 +1,46 @@ +# ASP.NET Core + + + +- [ASP.NET Core Attributes](#aspnet-core-attributes) + + + +## ASP.NET Core Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.request.is_unhandled` | boolean | Flag indicating if request was handled by the application pipeline. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.rate_limiting.result` 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 | Stability | +|---|---|---| +| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.diagnostics.exception.result` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`aspnetcore.routing.match_status` 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 | Stability | +|---|---|---| +| `success` | Match succeeded | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + \ No newline at end of file diff --git a/docs/attributes-registry/signalr.md b/docs/attributes-registry/signalr.md new file mode 100644 index 0000000000..ba2e9e0b7a --- /dev/null +++ b/docs/attributes-registry/signalr.md @@ -0,0 +1,32 @@ +# ASP.NET Core + + + +- [SignalR Attributes](#signalr-attributes) + + + +## SignalR Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`signalr.connection.status` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`signalr.transport` 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 | Stability | +|---|---|---| +| `server_sent_events` | ServerSentEvents protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + \ No newline at end of file diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index edcd0615ef..772d698a1d 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -43,8 +43,8 @@ All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.match_status`](../attributes-registry/aspnetcore.md) | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.is_fallback`](../attributes-registry/aspnetcore.md) | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[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. @@ -75,9 +75,9 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.exception.result`](../attributes-registry/aspnetcore.md) | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.handler.type`](../attributes-registry/aspnetcore.md) | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -134,7 +134,7 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -156,7 +156,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -174,7 +174,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -196,8 +196,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -229,8 +229,8 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index f2c5b73257..1960b681a1 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -32,8 +32,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: @@ -65,8 +65,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.connection.status` MUST be one of the following: diff --git a/model/metrics/dotnet/dotnet-aspnetcore.yaml b/model/metrics/dotnet/dotnet-aspnetcore.yaml index da851f57fb..fd0c2c4d78 100644 --- a/model/metrics/dotnet/dotnet-aspnetcore.yaml +++ b/model/metrics/dotnet/dotnet-aspnetcore.yaml @@ -1,62 +1,11 @@ groups: - - id: aspnetcore - prefix: aspnetcore + - id: aspnetcore.common.rate_limiting.metrics.attributes type: attribute_group - brief: ASP.NET Core attributes + brief: Common ASP.NET Core rate-limiting metrics attributes attributes: - - id: rate_limiting.policy - type: string - brief: Rate limiting policy name. - stability: stable - examples: ["fixed", "sliding", "token"] + - ref: aspnetcore.rate_limiting.policy requirement_level: conditionally_required: if the matched endpoint for the request had a rate-limiting policy. - - id: rate_limiting.result - type: - allow_custom_values: true - members: - - id: acquired - value: 'acquired' - brief: "Lease was acquired" - stability: stable - - id: endpoint_limiter - value: 'endpoint_limiter' - brief: "Lease request was rejected by the endpoint limiter" - stability: stable - - id: global_limiter - value: 'global_limiter' - brief: "Lease request was rejected by the global limiter" - stability: stable - - id: request_canceled - value: 'request_canceled' - brief: "Lease request was canceled" - stability: stable - stability: stable - brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason - examples: ["acquired", "request_canceled"] - requirement_level: required - - id: routing.is_fallback - type: boolean - stability: stable - brief: A value that indicates whether the matched route is a fallback route. - examples: [true] - requirement_level: - conditionally_required: If and only if a route was successfully matched. - - id: diagnostics.handler.type - type: string - stability: stable - brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) - implementation that handled the exception. - examples: ["Contoso.MyHandler"] - requirement_level: - conditionally_required: if and only if the exception was handled by this handler. - - id: request.is_unhandled - type: boolean - stability: stable - brief: Flag indicating if request was handled by the application pipeline. - examples: [true] - requirement_level: - conditionally_required: if and only if the request was not handled. # routing - id: metric.aspnetcore.routing.match_attempts @@ -75,22 +24,8 @@ groups: - ref: aspnetcore.routing.is_fallback requirement_level: conditionally_required: if and only if a route was successfully matched. - - id: aspnetcore.routing.match_status - type: - allow_custom_values: true - members: - - id: success - value: 'success' - brief: 'Match succeeded' - stability: stable - - id: failure - value: 'failure' - brief: 'Match failed' - stability: stable - stability: stable + - ref: aspnetcore.routing.match_status requirement_level: required - brief: Match result - success or failure - examples: ["success", "failure"] # diagnostics - id: metric.aspnetcore.diagnostics.exceptions @@ -108,29 +43,8 @@ groups: examples: ['System.OperationCanceledException', 'Contoso.MyException'] requirement_level: required - ref: aspnetcore.diagnostics.handler.type - - id: aspnetcore.diagnostics.exception.result - type: - members: - - id: handled - value: 'handled' - brief: "Exception was handled by the exception handling middleware." - stability: stable - - id: unhandled - value: 'unhandled' - brief: "Exception was not handled by the exception handling middleware." - stability: stable - - id: skipped - value: 'skipped' - brief: "Exception handling was skipped because the response had started." - stability: stable - - id: aborted - value: 'aborted' - brief: "Exception handling didn't run because the request was aborted." - stability: stable - stability: stable + - ref: aspnetcore.diagnostics.exception.result requirement_level: required - brief: ASP.NET Core exception middleware handling result - examples: ["handled", "unhandled"] # rate_limiting - id: metric.aspnetcore.rate_limiting.active_request_leases @@ -142,8 +56,7 @@ groups: unit: "{request}" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.request_lease.duration type: metric @@ -154,8 +67,7 @@ groups: unit: "s" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.request.time_in_queue type: metric @@ -166,9 +78,10 @@ groups: unit: "s" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + extends: aspnetcore.common.rate_limiting.metrics.attributes attributes: - - ref: aspnetcore.rate_limiting.policy - ref: aspnetcore.rate_limiting.result + requirement_level: required - id: metric.aspnetcore.rate_limiting.queued_requests type: metric @@ -179,8 +92,7 @@ groups: unit: "{request}" note: | Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 - attributes: - - ref: aspnetcore.rate_limiting.policy + extends: aspnetcore.common.rate_limiting.metrics.attributes - id: metric.aspnetcore.rate_limiting.requests type: metric @@ -196,6 +108,7 @@ groups: * Canceled while waiting for the lease. Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 + extends: aspnetcore.common.rate_limiting.metrics.attributes attributes: - - ref: aspnetcore.rate_limiting.policy - ref: aspnetcore.rate_limiting.result + requirement_level: required diff --git a/model/metrics/dotnet/dotnet-signalr.yaml b/model/metrics/dotnet/dotnet-signalr.yaml index e6233fc3cd..f91690e925 100644 --- a/model/metrics/dotnet/dotnet-signalr.yaml +++ b/model/metrics/dotnet/dotnet-signalr.yaml @@ -1,47 +1,4 @@ groups: - - id: signalr.common_attributes - prefix: signalr - type: attribute_group - brief: SignalR attributes - attributes: - - id: connection.status - type: - members: - - id: normal_closure - value: 'normal_closure' - brief: "The connection was closed normally." - stability: stable - - id: timeout - value: 'timeout' - brief: "The connection was closed due to a timeout." - stability: stable - - id: app_shutdown - value: 'app_shutdown' - brief: "The connection was closed because the app is shutting down." - stability: stable - stability: stable - brief: SignalR HTTP connection closure status. - examples: ["app_shutdown", "timeout"] - - id: transport - brief: "[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md)" - type: - allow_custom_values: true - members: - - id: server_sent_events - value: 'server_sent_events' - brief: "ServerSentEvents protocol" - stability: stable - - id: long_polling - value: 'long_polling' - brief: "LongPolling protocol" - stability: stable - - id: web_sockets - value: 'web_sockets' - brief: "WebSockets protocol" - stability: stable - stability: stable - examples: ["web_sockets", "long_polling"] - - id: metric.signalr.server.connection.duration type: metric metric_name: signalr.server.connection.duration diff --git a/model/registry/aspnetcore.yaml b/model/registry/aspnetcore.yaml new file mode 100644 index 0000000000..0c93fc1aee --- /dev/null +++ b/model/registry/aspnetcore.yaml @@ -0,0 +1,90 @@ +groups: + - id: registry.aspnetcore + prefix: aspnetcore + type: attribute_group + brief: ASP.NET Core attributes + attributes: + - id: rate_limiting.policy + type: string + brief: Rate limiting policy name. + stability: stable + examples: ["fixed", "sliding", "token"] + - id: rate_limiting.result + type: + allow_custom_values: true + members: + - id: acquired + value: 'acquired' + brief: "Lease was acquired" + stability: stable + - id: endpoint_limiter + value: 'endpoint_limiter' + brief: "Lease request was rejected by the endpoint limiter" + stability: stable + - id: global_limiter + value: 'global_limiter' + brief: "Lease request was rejected by the global limiter" + stability: stable + - id: request_canceled + value: 'request_canceled' + brief: "Lease request was canceled" + stability: stable + stability: stable + brief: Rate-limiting result, shows whether the lease was acquired or contains a rejection reason + examples: ["acquired", "request_canceled"] + requirement_level: required + - id: routing.is_fallback + type: boolean + stability: stable + brief: A value that indicates whether the matched route is a fallback route. + examples: [true] + - id: diagnostics.handler.type + type: string + stability: stable + brief: Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) + implementation that handled the exception. + examples: ["Contoso.MyHandler"] + requirement_level: + conditionally_required: if and only if the exception was handled by this handler. + - id: request.is_unhandled + type: boolean + stability: stable + brief: Flag indicating if request was handled by the application pipeline. + examples: [true] + - id: routing.match_status + type: + allow_custom_values: true + members: + - id: success + value: 'success' + brief: 'Match succeeded' + stability: stable + - id: failure + value: 'failure' + brief: 'Match failed' + stability: stable + stability: stable + brief: Match result - success or failure + examples: ["success", "failure"] + - id: diagnostics.exception.result + type: + members: + - id: handled + value: 'handled' + brief: "Exception was handled by the exception handling middleware." + stability: stable + - id: unhandled + value: 'unhandled' + brief: "Exception was not handled by the exception handling middleware." + stability: stable + - id: skipped + value: 'skipped' + brief: "Exception handling was skipped because the response had started." + stability: stable + - id: aborted + value: 'aborted' + brief: "Exception handling didn't run because the request was aborted." + stability: stable + stability: stable + brief: ASP.NET Core exception middleware handling result + examples: ["handled", "unhandled"] diff --git a/model/registry/signalr.yaml b/model/registry/signalr.yaml new file mode 100644 index 0000000000..879034e7b3 --- /dev/null +++ b/model/registry/signalr.yaml @@ -0,0 +1,43 @@ +groups: + - id: registry.signalr + prefix: signalr + type: attribute_group + brief: SignalR attributes + attributes: + - id: connection.status + type: + members: + - id: normal_closure + value: 'normal_closure' + brief: "The connection was closed normally." + stability: stable + - id: timeout + value: 'timeout' + brief: "The connection was closed due to a timeout." + stability: stable + - id: app_shutdown + value: 'app_shutdown' + brief: "The connection was closed because the app is shutting down." + stability: stable + stability: stable + brief: SignalR HTTP connection closure status. + examples: ["app_shutdown", "timeout"] + - id: transport + brief: "[SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md)" + type: + allow_custom_values: true + members: + - id: server_sent_events + value: 'server_sent_events' + brief: "ServerSentEvents protocol" + stability: stable + - id: long_polling + value: 'long_polling' + brief: "LongPolling protocol" + stability: stable + - id: web_sockets + value: 'web_sockets' + brief: "WebSockets protocol" + stability: stable + stability: stable + examples: ["web_sockets", "long_polling"] From 3afe2871d14603e2ab107e0b82ac2f76809ccbf0 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 11:53:24 -0700 Subject: [PATCH 469/482] Rename `db.name` to `db.namespace` and generalize it (#911) Co-authored-by: Trask Stalnaker --- .chloggen/911.yaml | 4 + docs/attributes-registry/db.md | 28 ++----- docs/database/cassandra.md | 4 +- docs/database/cosmosdb.md | 6 +- docs/database/database-metrics.md | 5 +- docs/database/database-spans.md | 12 +-- docs/database/hbase.md | 7 +- docs/database/mongodb.md | 15 ++-- docs/database/mssql.md | 15 ++-- docs/database/redis.md | 20 ++--- docs/database/sql.md | 33 ++++++-- model/db-common.yaml | 2 +- model/registry/db.yaml | 48 +++--------- model/registry/deprecated/db.yaml | 18 +++++ model/trace/database.yaml | 123 ++++++++++++++++++++++++++---- schema-next.yaml | 4 + 16 files changed, 226 insertions(+), 118 deletions(-) create mode 100644 .chloggen/911.yaml diff --git a/.chloggen/911.yaml b/.chloggen/911.yaml new file mode 100644 index 0000000000..b132291a62 --- /dev/null +++ b/.chloggen/911.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: db +note: Rename `db.name` and `db.redis.database_index` to `db.namespace`, deprecate `db.mssql.instance_name`. +issues: [ 885 ] diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 57f2d98a46..da0022a380 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -9,8 +9,6 @@ - [Cassandra Attributes](#cassandra-attributes) - [CosmosDB Attributes](#cosmosdb-attributes) - [Elasticsearch Attributes](#elasticsearch-attributes) -- [MSSQL Attributes](#mssql-attributes) -- [Redis Attributes](#redis-attributes) - [Deprecated DB Attributes](#deprecated-db-attributes) - [Deprecated DB Metrics Attributes](#deprecated-db-metrics-attributes) @@ -25,7 +23,7 @@ | `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.name` | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [2] | `customers`; `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.namespace` | string | The name of the database, fully qualified within the server address and port. [2] | `customers`; `test.users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -33,7 +31,8 @@ **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[2]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[3]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. @@ -184,24 +183,6 @@ If a parameter has no name and instead is referenced only by index, then `` **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. -## MSSQL Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.mssql.instance_name` | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [1] | `MSSQLSERVER` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). - - -## Redis Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.redis.database_index` | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - ## Deprecated DB Attributes @@ -213,7 +194,10 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | | `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.mssql.instance_name` | string | Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute. | `MSSQLSERVER` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | +| `db.name` | string | Deprecated, use `db.namespace` instead. | `customers`; `main` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | | `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.redis.database_index` | int | Deprecated, use `db.namespace` instead. | `0`; `1`; `15` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | | `db.sql.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | | `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index b726721e92..52033e0adf 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -18,7 +18,7 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.collection.name`](../attributes-registry/db.md) | string | The name of the Cassandra table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | The keyspace name in Cassandra. [3] | `mykeyspace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The Cassandra keyspace name. [3] | `mykeyspace` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -32,7 +32,7 @@ described on this page. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** For Cassandra the `db.name` should be set to the Cassandra keyspace name. +**[3]:** For commands that switch the keyspace, this SHOULD be set to the target keyspace (even if the command fails). **[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index f6a32606fa..4a7c63d328 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -79,14 +79,14 @@ In addition to Cosmos DB attributes, all spans include | `kind` | `"internal"` | | `az.namespace` | `"Microsoft.DocumentDB"` | | `db.system` | `"cosmosdb"` | -| `db.name` | `"database name"` | +| `db.collection.name` | `"orders"` | +| `db.namespace` | `"ShopDb"` | | `db.operation.name` | `"ReadItemsAsync"` | -| `server.address` | `"account.documents.azure.com"` | +| `server.address` | `"account.documents.azure.com"` | | `db.cosmosdb.client_id` | `3ba4827d-4422-483f-b59f-85b74211c11d` | | `db.cosmosdb.operation_type` | `Read` | | `user_agent.original` | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | | `db.cosmosdb.connection_mode` | `"Direct"` | -| `db.cosmosdb.container` | `"container name"` | | `db.cosmosdb.request_content_length` | `20` | | `db.cosmosdb.status_code` | `201` | | `db.cosmosdb.sub_status_code` | `0` | diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index ccf76a54b1..e8b648820b 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -62,7 +62,7 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -74,7 +74,8 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 15a6080f17..80492ca794 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -55,11 +55,12 @@ The **span name** SHOULD be set to a low cardinality value representing the stat It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation.name` and `db.collection.name` are available. -If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. +` .`, provided that `db.operation.name` and `db.collection.name` are available. +If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. + It is not recommended to attempt any client-side parsing of `db.query.text` just to get these properties, they should only be used if the library being instrumented already provides them. -When it's otherwise impossible to get any meaningful span name, `db.name` or the tech-specific database name MAY be used. +When it's otherwise impossible to get any meaningful span name, `db.namespace` or the tech-specific database name MAY be used. Span that describes database call SHOULD cover the duration of the corresponding call as if it was observed by the caller (such as client application). For example, if a transient issue happened and was retried within this database call, the corresponding span should cover the duration of the logical operation @@ -74,7 +75,7 @@ These attributes will usually be the same for all operations performed over the |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.name`](../attributes-registry/db.md) | string | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [3] | `customers`; `main` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -88,7 +89,8 @@ These attributes will usually be the same for all operations performed over the **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 290525590d..5bd4955583 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -17,9 +17,12 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.name`](../attributes-registry/db.md) | string | The HBase namespace. [1] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The HBase table name. [1] | `mytable`; `ns:table` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The HBase namespace. [2] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** For HBase the `db.name` should be set to the HBase namespace. +**[1]:** If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. + +**[2]:** When performing table-related operations, the instrumentations SHOULD extract the namespace from the table name according to the [HBase table naming conventions](https://hbase.apache.org/book.html#namespace_creation). If namespace is not provided, instrumentation SHOULD set `db.namespace` value to `default`. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index be34d3430a..bc4a08d7b5 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -17,14 +17,17 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.name`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [2] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.namespace`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The MongoDB database name. [2] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [3] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). +**[2]:** -**[3]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[3]:** See [MongoDB database commands](https://www.mongodb.com/docs/manual/reference/command/). + +**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example @@ -38,9 +41,9 @@ described on this page. | `network.peer.address` | `"192.0.2.14"` | | `network.peer.port` | `27017` | | `network.transport` | `"tcp"` | -| `db.name` | `"shopDb"` | +| `db.collection.name` | `"products"` | +| `db.namespace` | `"shopDb"` | | `db.query.text` | not set | | `db.operation.name` | `"findAndModify"` | -| `db.mongodb.collection` | `"products"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/mssql.md b/docs/database/mssql.md index e4c0774857..6a0e7766a3 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,20 +17,21 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.mssql.instance_name`](../attributes-registry/db.md) | string | The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. [5] | `MSSQLSERVER` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `instance1.products`; `customers` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. -In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. +**[3]:** When connecting to a default instance, `db.namespace` SHOULD be set to the name of the database. When connecting to a [named instance](https://learn.microsoft.com/sql/connect/jdbc/building-the-connection-url#named-and-multiple-sql-server-instances), `db.namespace` SHOULD be set to the combination of instance and database name following the `{instance_name}.{database_name}` pattern. +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). -**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[4]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[5]:** If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). +**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/redis.md b/docs/database/redis.md index 052c0a8048..116be54221 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -17,22 +17,25 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.redis.database_index`](../attributes-registry/db.md) | int | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. | `0`; `1`; `15` | `Conditionally Required` If other than the default database (`0`). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [1] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [3] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.namespace`](../attributes-registry/db.md) | string | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). [1] | `0`; `1`; `15` | `Conditionally Required` If and only if it can be captured reliably. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [2] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. +**[1]:** The database index for current connection can be changed by the application dynamically. Instrumentations MAY use the initial database index provided in the connection string and keep track of the currently selected database to capture the `db.namespace`. +Instrumentations SHOULD NOT set this attribute if capturing it would require additional network calls to Redis. +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). -**[2]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[2]:** For **Redis**, the value provided for `db.query.text` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.query.text`. -**[3]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[3]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. + +**[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. ## Example In this example, Redis is connected using a unix domain socket and therefore the connection string is left out. -Furthermore, `db.name` is not specified as there is no database name in Redis and `db.redis.database_index` is set instead. | Key | Value | |:--------------------------| :-------------------------------------------- | @@ -40,9 +43,8 @@ Furthermore, `db.name` is not specified as there is no database name in Redis an | `db.system` | `"redis"` | | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | -| `db.name` | not set | +| `db.namespace` | `"15"` | | `db.query.text` | `"HMSET myhash field1 'Hello' field2 'World"` | | `db.operation.name` | not set | -| `db.redis.database_index` | `15` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/sql.md b/docs/database/sql.md index dcd4d0ba2e..58cfbee159 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,17 +15,38 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. **[2]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. -**[3]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. +**[3]:** If a database system has multiple namespace components, they SHOULD be concatenated +(potentially using database system specific conventions) from most general to most +specific namespace component, and more specific namespaces SHOULD NOT be captured without +the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + +Unless specified by the system-specific semantic convention, the `db.namespace` attribute matches +the name of the database being accessed. + +The database name can usually be obtained with database driver API such as +[JDBC `Connection.getCatalog()`](https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getCatalog--) +or [.NET `SqlConnection.Database`](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.database). + +Some database drivers don't detect when the current database is changed (for example, with SQL `USE database` statement). +Instrumentations that parse SQL statements MAY use the database name provided +in the connection string and keep track of the currently selected database name. + +For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + +If instrumentation cannot reliably determine the current database name, it SHOULD NOT set `db.namespace`. + +**[4]:** This SHOULD be the SQL command such as `SELECT`, `INSERT`, `UPDATE`, `CREATE`, `DROP`. In the case of `EXEC`, this SHOULD be the stored procedure name that is being executed. -**[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. +**[5]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. ## Example @@ -35,15 +56,15 @@ This is an example of attributes for a MySQL database span: | Key | Value | |:-----------------------| :----------------------------------------------------------- | | Span name | `"SELECT ShopDb.orders"` | +| `db.collection.name` | `"orders"` | +| `db.namespace` | `"ShopDb"` | | `db.system` | `"mysql"` | | `server.address` | `"shopdb.example.com"` | | `server.port` | `3306` | | `network.peer.address` | `"192.0.2.12"` | | `network.peer.port` | `3306` | | `network.transport` | `"tcp"` | -| `db.name` | `"ShopDb"` | | `db.query.text` | `"SELECT * FROM orders WHERE order_id = 'o4711'"` | | `db.operation.name` | `"SELECT"` | -| `db.collection.name` | `"orders"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/model/db-common.yaml b/model/db-common.yaml index fdefe67883..faca39e25f 100644 --- a/model/db-common.yaml +++ b/model/db-common.yaml @@ -3,7 +3,7 @@ groups: type: attribute_group brief: 'Database Client attributes' attributes: - - ref: db.name + - ref: db.namespace requirement_level: conditionally_required: If applicable. - ref: db.collection.name diff --git a/model/registry/db.yaml b/model/registry/db.yaml index 293ec073fb..eef192fe1d 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -13,19 +13,20 @@ groups: If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. examples: ['public.users', 'customers'] - - id: name + - id: namespace type: string stability: experimental brief: > - This attribute is used to report the name of the database being accessed. - For commands that switch the database, this should be set to the target database - (even if the command fails). + The name of the database, fully qualified within the server address and port. note: > - In some SQL databases, the database name to be used is called "schema name". - In case there are multiple layers that could be considered for database name - (e.g. Oracle instance name and schema name), - the database name to be used is the more specific layer (e.g. Oracle schema name). - examples: [ 'customers', 'main' ] + If a database system has multiple namespace components, they SHOULD be concatenated + (potentially using database system specific conventions) from most general to most + specific namespace component, and more specific namespaces SHOULD NOT be captured without + the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + + Semantic conventions for individual database systems SHOULD document what `db.namespace` + means in the context of that system. + examples: [ 'customers', 'test.users' ] - id: operation.name type: string stability: experimental @@ -486,32 +487,3 @@ groups: reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] - - id: registry.db.mssql - prefix: db - type: attribute_group - brief: > - This group defines attributes for Microsoft SQL Server. - attributes: - - id: mssql.instance_name - type: string - stability: experimental - note: > - If setting a `db.mssql.instance_name`, `server.port` is no longer - required (but still recommended if non-standard). - brief: > - The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) - connecting to. This name is used to determine the port of a named instance. - examples: 'MSSQLSERVER' - - id: registry.db.redis - prefix: db - type: attribute_group - brief: > - This group defines attributes for Redis. - attributes: - - id: redis.database_index - type: int - stability: experimental - brief: > - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. - To be used instead of the generic `db.name` attribute. - examples: [0, 1, 15] diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index de58225c67..8734714110 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -66,6 +66,24 @@ groups: brief: 'Deprecated, use `db.collection.name` instead.' deprecated: "Replaced by `db.collection.name`." examples: 'mytable' + - id: redis.database_index + type: int + stability: experimental + brief: 'Deprecated, use `db.namespace` instead.' + deprecated: "Replaced by `db.namespace`." + examples: [0, 1, 15] + - id: name + type: string + stability: experimental + brief: 'Deprecated, use `db.namespace` instead.' + deprecated: "Replaced by `db.namespace`." + examples: [ 'customers', 'main' ] + - id: mssql.instance_name + type: string + stability: experimental + brief: 'Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute.' + deprecated: 'Deprecated, no replacement at this time.' + examples: 'MSSQLSERVER' - id: registry.db.metrics.deprecated type: attribute_group diff --git a/model/trace/database.yaml b/model/trace/database.yaml index e0f6aee6c5..f3b59d5a08 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -4,12 +4,48 @@ groups: type: attribute_group brief: This group defines the attributes used to perform database client calls. attributes: + - ref: db.system + requirement_level: required - ref: db.query.text requirement_level: recommended: > SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in + - ref: db.operation.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.operation.name`, then it SHOULD be the first operation name found in the query. + - ref: server.address + brief: > + Name of the database host. + - ref: server.port + requirement_level: + conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. + - ref: db.instance.id + requirement_level: + recommended: If different from the `server.address` + - ref: db.collection.name + requirement_level: + conditionally_required: > + If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture + `db.collection.name`, then it SHOULD be the first collection name found in the query. + - ref: db.namespace + requirement_level: + conditionally_required: If available. + - ref: network.peer.address + brief: Peer address of the database node where the operation was performed. + requirement_level: + recommended: If applicable for this database system. + note: > + Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. + Network peer address and port are useful when the application interacts with individual database nodes directly. + + If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + - ref: network.peer.port + requirement_level: + recommended: if and only if `network.peer.address` is set. - id: db.tech_specific.network.attributes type: attribute_group @@ -37,7 +73,15 @@ groups: brief: > Attributes for Microsoft SQL Server attributes: - - ref: db.mssql.instance_name + - ref: db.namespace + brief: The name of the database, fully qualified within the server address and port. + note: + When connecting to a default instance, `db.namespace` SHOULD be set to the name of + the database. When connecting to a [named instance](https://learn.microsoft.com/sql/connect/jdbc/building-the-connection-url#named-and-multiple-sql-server-instances), + `db.namespace` SHOULD be set to the combination of instance and database name following the `{instance_name}.{database_name}` pattern. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + examples: ["instance1.products", "customers"] tag: tech-specific - id: db.cassandra @@ -46,12 +90,11 @@ groups: brief: > Attributes for Cassandra attributes: - - ref: db.name - tag: tech-specific - brief: > - The keyspace name in Cassandra. + - ref: db.namespace + brief: The Cassandra keyspace name. + note: For commands that switch the keyspace, this SHOULD be set to the target keyspace (even if the command fails). examples: ["mykeyspace"] - note: For Cassandra the `db.name` should be set to the Cassandra keyspace name. + tag: tech-specific - ref: db.cassandra.page_size tag: tech-specific - ref: db.cassandra.consistency_level @@ -74,12 +117,24 @@ groups: brief: > Attributes for HBase attributes: - - ref: db.name - tag: tech-specific - brief: > - The HBase namespace. + - ref: db.namespace + brief: The HBase namespace. + requirement_level: + conditionally_required: If applicable. + note: > + When performing table-related operations, the instrumentations SHOULD extract the namespace from the table name according to + the [HBase table naming conventions](https://hbase.apache.org/book.html#namespace_creation). If namespace is not provided, + instrumentation SHOULD set `db.namespace` value to `default`. examples: ['mynamespace'] - note: For HBase the `db.name` should be set to the HBase namespace. + tag: tech-specific + - ref: db.collection.name + brief: The HBase table name. + requirement_level: + conditionally_required: If applicable. + note: > + If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. + examples: ['mytable', 'ns:table'] + tag: tech-specific - id: db.couchdb type: span @@ -105,9 +160,20 @@ groups: brief: > Attributes for Redis attributes: - - ref: db.redis.database_index + - ref: db.namespace + brief: > + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). requirement_level: - conditionally_required: If other than the default database (`0`). + conditionally_required: If and only if it can be captured reliably. + note: > + The database index for current connection can be changed by the application dynamically. Instrumentations MAY use + the initial database index provided in the connection string and keep track of the currently selected + database to capture the `db.namespace`. + + Instrumentations SHOULD NOT set this attribute if capturing it would require additional network calls to Redis. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + examples: ["0", "1", "15"] tag: tech-specific - ref: db.query.text tag: tech-specific @@ -133,9 +199,14 @@ groups: tag: tech-specific - ref: db.collection.name brief: - The MongoDB collection being accessed within the database stated in `db.name`. + The MongoDB collection being accessed within the database stated in `db.namespace`. requirement_level: required tag: tech-specific + - ref: db.namespace + brief: The MongoDB database name. + note: | + + tag: tech-specific - id: db.elasticsearch type: span @@ -197,8 +268,30 @@ groups: tag: tech-specific - ref: db.collection.name brief: The name of the SQL table that the operation is acting upon. - tag: tech-specific + examples: ['users', 'dbo.products'] + tag: tech-specific + - ref: db.namespace + note: | + If a database system has multiple namespace components, they SHOULD be concatenated + (potentially using database system specific conventions) from most general to most + specific namespace component, and more specific namespaces SHOULD NOT be captured without + the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + Unless specified by the system-specific semantic convention, the `db.namespace` attribute matches + the name of the database being accessed. + + The database name can usually be obtained with database driver API such as + [JDBC `Connection.getCatalog()`](https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getCatalog--) + or [.NET `SqlConnection.Database`](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.database). + + Some database drivers don't detect when the current database is changed (for example, with SQL `USE database` statement). + Instrumentations that parse SQL statements MAY use the database name provided + in the connection string and keep track of the currently selected database name. + + For commands that switch the database, this SHOULD be set to the target database (even if the command fails). + + If instrumentation cannot reliably determine the current database name, it SHOULD NOT set `db.namespace`. + tag: tech-specific - id: db.cosmosdb type: span extends: trace.db.common diff --git a/schema-next.yaml b/schema-next.yaml index 5fc05edea2..85bfa85d72 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -27,6 +27,10 @@ versions: 1.25.0: spans: changes: + # https://github.com/open-telemetry/semantic-conventions/pull/911 + - rename_attributes: + attribute_map: + db.name: db.namespace # https://github.com/open-telemetry/semantic-conventions/pull/870 - rename_attributes: attribute_map: From 387b74f8a78c56d513063828093ef64341cafffb Mon Sep 17 00:00:00 2001 From: Anna Levenberg Date: Wed, 24 Apr 2024 15:00:50 -0400 Subject: [PATCH 470/482] docs(messaging): add gcp_pubsub unary pull example (#634) Co-authored-by: Joao Grassi Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Co-authored-by: Liudmila Molkova --- .chloggen/634.yaml | 25 +++++++++ docs/attributes-registry/messaging.md | 3 + docs/messaging/gcp-pubsub.md | 80 ++++++++++++++++++++++++++- model/registry/messaging.yaml | 22 ++++++++ model/trace/messaging.yaml | 9 ++- 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 .chloggen/634.yaml diff --git a/.chloggen/634.yaml b/.chloggen/634.yaml new file mode 100644 index 0000000000..16b837ff88 --- /dev/null +++ b/.chloggen/634.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: messaging + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add a GCP Pub/Sub unary pull example and the new GCP messaging attributes: +- `messaging.gcp_pubsub.message.ack_deadline`, +- `messaging.gcp_pubsub.message.ack_id`, +- `messaging.gcp_pubsub.message.delivery_attempt`" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [527] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index b41d340165..25bad90a56 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -87,6 +87,9 @@ size should be used. | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| +| `messaging.gcp_pubsub.message.ack_deadline` | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.ack_id` | string | The ack id for a given message. | `ack_id` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.delivery_attempt` | int | The delivery attempt for a given message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index b586668d69..3ed71fdcf1 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -14,12 +14,28 @@ The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pub For Google Cloud Pub/Sub, the following additional attributes are defined: - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_deadline`](../attributes-registry/messaging.md) | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_id`](../attributes-registry/messaging.md) | string | The ack id for a given message. | `ack_id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.delivery_attempt`](../attributes-registry/messaging.md) | int | The delivery attempt for a given message. | `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## Span names + +The span name SHOULD follow the [general messaging span name pattern](../messaging/gcp-pubsub.md): it SHOULD start with the messaging destination name (Topic/Subscription) and contain a low-cardinality name of an operation the span describes: + +- Spans for `settle` operations SHOULD follow the ` ack` or ` nack` pattern. +- Spans names for `publish` operations SHOULD follow the ` send` pattern. +- Spans for `create`, `receive`, and `publish` operations SHOULD follow the general ` ` pattern. + +In addition there are the following operations are GCP specific: + +- Spans that represents the time from after the message was received to when the message is acknowledged, negatively acknowledged, or expire (used by streaming pull) SHOULD follow the ` subscribe` pattern. +- Spans that represent extending the lease for a single message or batch of messages SHOULD follow the` modack` pattern. + ## Examples ### Asynchronous Batch Publish Example @@ -58,4 +74,64 @@ flowchart LR; | `messaging.message.envelope.size` | `1` | `1` | | | `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | -[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md +### Unary Pull Example + +```mermaid +flowchart TD; + subgraph CONSUMER + direction LR + R1[Receive m1] + SM1[Ack m1] + EM1[Modack m1] + end + subgraph PRODUCER + direction LR + CM1[Create m1] + PM1[Publish] + end + %% Link 0 + CM1-. link .-PM1; + %% Link 1 + CM1-. link .-R1; + %% Link 2 + R1-. link .-SM1; + %% Link 3 + R1-. link .-EM1; + + %% Style the node and corresponding link + %% Producer links and nodes + classDef producer fill:green + class PM1,CM1 producer + linkStyle 0 color:green,stroke:green + + %% Consumer links and nodes + classDef consumer fill:#49fcdc + class R1 consumer + linkStyle 1 color:#49fcdc,stroke:#49fcdc + + classDef ack fill:#577eb5 + class SM1 ack + linkStyle 2 color:#577eb5,stroke:#577eb5 + + classDef modack fill:#0560f2 + class EM1 modack + linkStyle 3 color:#0560f2,stroke:#0560f2 +``` + +| Field or Attribute | Span Create A | Span Publish A | Span Receive A | Span Modack A | Span Ack A | +|-|-|-|-|-|-| +| Span name | `T create` | `publish` | `S receive` | `S modack` |`S ack` | +| Parent | | | | | | +| Links | | Span Create A | Span Create A | Span Receive A | Span Receive A | +| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` |`CLIENT` |`CLIENT` | +| Status | `Ok` | `Ok` | `Ok` |`Ok` | `Ok` | +| `messaging.destination.name` | `"T"`| `"T"`| `"S"` | `"S"` |`"S"` | +| `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | +| `messaging.operation` | `"create"` | `"publish"` | `"receive"` | `"extend"` | `"settle"` | +| `messaging.message.id` | `"a1"` | | `"a1"` | | | +| `messaging.message.envelope.size` | `1` | `1` | `1` | | | +| `messaging.gcp_pubsub.message.ack_id` | | | | `"ack_id1"` |`"ack_id1"` | +| `messaging.gcp_pubsub.message.delivery_attempt` | | | | `0` | | +| `messaging.gcp_pubsub.message.ack_deadline` | | | | | `0` | + +[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/model/registry/messaging.yaml b/model/registry/messaging.yaml index 4a2c6a2714..f22f58f155 100644 --- a/model/registry/messaging.yaml +++ b/model/registry/messaging.yaml @@ -333,6 +333,28 @@ groups: brief: > The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. examples: 'ordering_key' + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.ack_id + type: string + stability: experimental + brief: > + The ack id for a given message. + examples: 'ack_id' + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.ack_deadline + type: int + stability: experimental + brief: > + The ack deadline in seconds set for the modify ack deadline request. + examples: 10 + tag: tech-specific-gcp-pubsub + - id: gcp_pubsub.message.delivery_attempt + type: int + stability: experimental + brief: > + The delivery attempt for a given message. + examples: 2 + tag: tech-specific-gcp-pubsub - id: registry.messaging.servicebus prefix: messaging type: attribute_group diff --git a/model/trace/messaging.yaml b/model/trace/messaging.yaml index f12a96b1df..542edec127 100644 --- a/model/trace/messaging.yaml +++ b/model/trace/messaging.yaml @@ -188,14 +188,21 @@ groups: tag: tech-specific - id: messaging.gcp_pubsub type: attribute_group + stability: experimental extends: messaging brief: > Attributes for Google Cloud Pub/Sub attributes: - ref: messaging.gcp_pubsub.message.ordering_key - tag: tech-specific + tag: tech-specific-gcp-pubsub requirement_level: conditionally_required: If the message type has an ordering key set. + - ref: messaging.gcp_pubsub.message.delivery_attempt + tag: tech-specific-gcp-pubsub + - ref: messaging.gcp_pubsub.message.ack_deadline + tag: tech-specific-gcp-pubsub + - ref: messaging.gcp_pubsub.message.ack_id + tag: tech-specific-gcp-pubsub - id: messaging.servicebus type: attribute_group extends: messaging From 4d80b4ce2b17c84856f39c73cef41ae54d087d32 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Wed, 24 Apr 2024 12:17:44 -0700 Subject: [PATCH 471/482] [chore] Disable link check for semconv pulls and issues (#962) --- .markdown_link_check_config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.markdown_link_check_config.json b/.markdown_link_check_config.json index 8ee8073745..ede6fbc5eb 100644 --- a/.markdown_link_check_config.json +++ b/.markdown_link_check_config.json @@ -2,6 +2,9 @@ "ignorePatterns": [ { "pattern": "^https://github\\.com/open-telemetry/opentelemetry-specification/(issues|pull)" + }, + { + "pattern": "^https://github\\.com/open-telemetry/semantic-conventions/(issues|pull)" } ], "replacementPatterns": [ From 37a79422adef2042e2e5915371bdb339a153f783 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 29 Apr 2024 10:16:06 -0700 Subject: [PATCH 472/482] Database: add error.type to span and metric (#975) --- .chloggen/975.yaml | 7 +++++++ docs/database/database-metrics.md | 25 +++++++++++++++-------- docs/database/database-spans.md | 31 ++++++++++++++++++----------- model/db-common.yaml | 9 ++++++++- model/trace/database.yaml | 33 ------------------------------- 5 files changed, 52 insertions(+), 53 deletions(-) create mode 100644 .chloggen/975.yaml diff --git a/.chloggen/975.yaml b/.chloggen/975.yaml new file mode 100644 index 0000000000..f67fc63c34 --- /dev/null +++ b/.chloggen/975.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: db + +note: Add `error.type` attribute to the database span and operation duration metric. + +issues: [975] diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index e8b648820b..2e0dde0db9 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -62,13 +62,14 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. |---|---|---|---|---|---| | [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [7] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. @@ -79,14 +80,16 @@ Semantic conventions for individual database systems SHOULD document what `db.na **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5]:** The `error.type` SHOULD match the error code returned by the database or the client library, the canonical name of exception that occurred, or another low-cardinality error identifier. Instrumentations SHOULD document the list of errors they report. -**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[8]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[9]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. `db.system` 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. @@ -144,6 +147,12 @@ If a database operation involved multiple network calls (for example retries), t | `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Connection pools diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 80492ca794..13e654c5e6 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -77,13 +77,14 @@ These attributes will usually be the same for all operations performed over the | [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [9] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [10] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [10] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. @@ -94,18 +95,20 @@ Semantic conventions for individual database systems SHOULD document what `db.na **[4]:** If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.operation.name`, then it SHOULD be the first operation name found in the query. -**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5]:** The `error.type` SHOULD match the error code returned by the database or the client library, the canonical name of exception that occurred, or another low-cardinality error identifier. Instrumentations SHOULD document the list of errors they report. -**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. +**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[8]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. +**[8]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. + +**[9]:** Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are useful when the application interacts with individual database nodes directly. If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[9]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[10]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[10]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[11]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a parameter has no name and instead is referenced only by index, then `` SHOULD be the 0-based index. `db.system` 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. @@ -164,6 +167,12 @@ If a parameter has no name and instead is referenced only by index, then `` | `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Notes and well-known identifiers for `db.system` diff --git a/model/db-common.yaml b/model/db-common.yaml index faca39e25f..8e2d1210d5 100644 --- a/model/db-common.yaml +++ b/model/db-common.yaml @@ -5,7 +5,7 @@ groups: attributes: - ref: db.namespace requirement_level: - conditionally_required: If applicable. + conditionally_required: If available. - ref: db.collection.name requirement_level: conditionally_required: > @@ -39,3 +39,10 @@ groups: - ref: server.port requirement_level: conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. + - ref: error.type + requirement_level: + conditionally_required: If and only if the operation failed. + note: > + The `error.type` SHOULD match the error code returned by the database or the client library, + the canonical name of exception that occurred, or another low-cardinality error identifier. + Instrumentations SHOULD document the list of errors they report. diff --git a/model/trace/database.yaml b/model/trace/database.yaml index f3b59d5a08..fb3ab09a53 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -4,48 +4,15 @@ groups: type: attribute_group brief: This group defines the attributes used to perform database client calls. attributes: - - ref: db.system - requirement_level: required - ref: db.query.text requirement_level: recommended: > SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in - - ref: db.operation.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.operation.name`, then it SHOULD be the first operation name found in the query. - - ref: server.address - brief: > - Name of the database host. - - ref: server.port - requirement_level: - conditionally_required: If using a port other than the default port for this DBMS and if `server.address` is set. - ref: db.instance.id requirement_level: recommended: If different from the `server.address` - - ref: db.collection.name - requirement_level: - conditionally_required: > - If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture - `db.collection.name`, then it SHOULD be the first collection name found in the query. - - ref: db.namespace - requirement_level: - conditionally_required: If available. - - ref: network.peer.address - brief: Peer address of the database node where the operation was performed. - requirement_level: - recommended: If applicable for this database system. - note: > - Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes are applicable. - Network peer address and port are useful when the application interacts with individual database nodes directly. - - If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. - - ref: network.peer.port - requirement_level: - recommended: if and only if `network.peer.address` is set. - id: db.tech_specific.network.attributes type: attribute_group From b4a04fdb165b4c4a98dc2098fbdf281a1c2c2fe5 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 29 Apr 2024 17:03:12 -0400 Subject: [PATCH 473/482] Move JVM attribtues to registry. (#979) Co-authored-by: Alexandra Konrad <10500694+trisch-me@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + docs/attributes-registry/README.md | 1 + docs/attributes-registry/jvm.md | 44 +++++++++++ docs/runtime/jvm-metrics.md | 28 +++---- model/metrics/jvm-metrics.yaml | 79 ++------------------ model/registry/jvm.yaml | 81 +++++++++++++++++++++ 8 files changed, 149 insertions(+), 87 deletions(-) create mode 100644 docs/attributes-registry/jvm.md create mode 100644 model/registry/jvm.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 32e7e1299c..af486e4502 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -47,6 +47,7 @@ body: - area:heroku - area:host - area:http + - area:jvm - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index b800c0e341..3d00899d2d 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -40,6 +40,7 @@ body: - area:heroku - area:host - area:http + - area:jvm - area:k8s - area:log - area:messaging diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 08421ab61d..3985923373 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -49,6 +49,7 @@ body: - area:heroku - area:host - area:http + - area:jvm - area:k8s - area:log - area:messaging diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index a0f1684213..449246fc77 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -54,6 +54,7 @@ Currently, the following namespaces exist: * [Host](host.md) * [HTTP](http.md) * [iOS](ios.md) +* [JVM](jvm.md) * [K8s](k8s.md) * [Log](log.md) * [Network](network.md) diff --git a/docs/attributes-registry/jvm.md b/docs/attributes-registry/jvm.md new file mode 100644 index 0000000000..57dce510c2 --- /dev/null +++ b/docs/attributes-registry/jvm.md @@ -0,0 +1,44 @@ +# JVM + + + +- [JVM Attributes](#jvm-attributes) + + + +## JVM Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.pool.name` | string | Name of the memory pool. [3] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + +**[2]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +**[3]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + +`jvm.memory.type` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`jvm.thread.state` MUST be one of the following: + +| Value | Description | Stability | +|---|---|---| +| `new` | A thread that has not yet started is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `runnable` | A thread executing in the Java virtual machine is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timed_waiting` | A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `terminated` | A thread that has exited is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index bffa79169d..769a69f859 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -59,8 +59,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -86,8 +86,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -113,8 +113,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -140,8 +140,8 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). @@ -178,8 +178,8 @@ of `[ 0.01, 0.1, 1, 10 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.gc.action`](../attributes-registry/jvm.md) | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.gc.name`](../attributes-registry/jvm.md) | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). @@ -213,8 +213,8 @@ Note that this is the number of platform threads (as opposed to virtual threads) | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.thread.daemon`](../attributes-registry/jvm.md) | boolean | Whether the thread is daemon or not. | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.thread.state`](../attributes-registry/jvm.md) | string | State of the thread. | `runnable`; `blocked` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `jvm.thread.state` MUST be one of the following: @@ -351,8 +351,8 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.memory.pool.name` | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). diff --git a/model/metrics/jvm-metrics.yaml b/model/metrics/jvm-metrics.yaml index 5247f4165e..b0e4224086 100644 --- a/model/metrics/jvm-metrics.yaml +++ b/model/metrics/jvm-metrics.yaml @@ -4,31 +4,11 @@ groups: brief: "Describes JVM memory metric attributes." prefix: jvm.memory attributes: - - id: type - stability: stable - type: - allow_custom_values: false - members: - - id: heap - value: 'heap' - brief: 'Heap memory.' - stability: stable - - id: non_heap - value: 'non_heap' - brief: 'Non-heap memory' - stability: stable + - ref: jvm.memory.type requirement_level: recommended - brief: The type of memory. - examples: ["heap", "non_heap"] - - id: pool.name - stability: stable - type: string + - ref: jvm.memory.pool.name requirement_level: recommended brief: Name of the memory pool. - examples: ["G1 Old Gen", "G1 Eden space", "G1 Survivor Space"] - note: > - Pool names are generally obtained via - [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). - id: metric.jvm.memory.used type: metric @@ -74,24 +54,10 @@ groups: unit: "s" prefix: jvm.gc attributes: - - id: name - stability: stable - type: string + - ref: jvm.gc.name requirement_level: recommended - brief: Name of the garbage collector. - examples: ["G1 Young Generation", "G1 Old Generation"] - note: > - Garbage collector name is generally obtained via - [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). - - id: action - stability: stable - type: string + - ref: jvm.gc.action requirement_level: recommended - brief: Name of the garbage collector action. - examples: ["end of minor GC", "end of major GC"] - note: > - Garbage collector action is generally obtained via - [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). stability: stable - id: metric.jvm.thread.count @@ -101,43 +67,10 @@ groups: instrument: updowncounter unit: "{thread}" attributes: - - id: jvm.thread.daemon - stability: stable - type: boolean + - ref: jvm.thread.daemon requirement_level: recommended - brief: "Whether the thread is daemon or not." - - id: jvm.thread.state - stability: stable + - ref: jvm.thread.state requirement_level: recommended - type: - allow_custom_values: false - members: - - id: new - value: 'new' - brief: 'A thread that has not yet started is in this state.' - stability: stable - - id: runnable - value: 'runnable' - brief: 'A thread executing in the Java virtual machine is in this state.' - stability: stable - - id: blocked - value: 'blocked' - brief: 'A thread that is blocked waiting for a monitor lock is in this state.' - stability: stable - - id: waiting - value: 'waiting' - brief: 'A thread that is waiting indefinitely for another thread to perform a particular action is in this state.' - stability: stable - - id: timed_waiting - value: 'timed_waiting' - brief: 'A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.' - stability: stable - - id: terminated - value: 'terminated' - brief: 'A thread that has exited is in this state.' - stability: stable - brief: "State of the thread." - examples: ["runnable", "blocked"] stability: stable - id: metric.jvm.class.loaded diff --git a/model/registry/jvm.yaml b/model/registry/jvm.yaml new file mode 100644 index 0000000000..071b6c4612 --- /dev/null +++ b/model/registry/jvm.yaml @@ -0,0 +1,81 @@ +groups: + - id: registry.jvm + type: attribute_group + prefix: jvm + brief: > + This document defines Java Virtual machine related attributes. + attributes: + - id: gc.action + stability: stable + type: string + brief: Name of the garbage collector action. + examples: ["end of minor GC", "end of major GC"] + note: > + Garbage collector action is generally obtained via + [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + - id: gc.name + stability: stable + type: string + brief: Name of the garbage collector. + examples: ["G1 Young Generation", "G1 Old Generation"] + note: > + Garbage collector name is generally obtained via + [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + - id: memory.type + stability: stable + type: + allow_custom_values: false + members: + - id: heap + value: 'heap' + brief: 'Heap memory.' + stability: stable + - id: non_heap + value: 'non_heap' + brief: 'Non-heap memory' + stability: stable + brief: The type of memory. + examples: ["heap", "non_heap"] + - id: memory.pool.name + stability: stable + type: string + brief: Name of the memory pool. + examples: ["G1 Old Gen", "G1 Eden space", "G1 Survivor Space"] + note: > + Pool names are generally obtained via + [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). + - id: thread.daemon + stability: stable + type: boolean + brief: "Whether the thread is daemon or not." + - id: thread.state + stability: stable + brief: "State of the thread." + examples: ["runnable", "blocked"] + type: + allow_custom_values: false + members: + - id: new + value: 'new' + brief: 'A thread that has not yet started is in this state.' + stability: stable + - id: runnable + value: 'runnable' + brief: 'A thread executing in the Java virtual machine is in this state.' + stability: stable + - id: blocked + value: 'blocked' + brief: 'A thread that is blocked waiting for a monitor lock is in this state.' + stability: stable + - id: waiting + value: 'waiting' + brief: 'A thread that is waiting indefinitely for another thread to perform a particular action is in this state.' + stability: stable + - id: timed_waiting + value: 'timed_waiting' + brief: 'A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.' + stability: stable + - id: terminated + value: 'terminated' + brief: 'A thread that has exited is in this state.' + stability: stable From 3dc61e15a5cb56fde9bb2c3aa96882aac8aa9a73 Mon Sep 17 00:00:00 2001 From: Povilas Versockas Date: Tue, 30 Apr 2024 05:58:35 +0300 Subject: [PATCH 474/482] feat: add k8s.container.status.last_terminated_reason resource attribute (#968) Co-authored-by: Liudmila Molkova --- .chloggen/k8s-status.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/k8s.md | 3 ++- docs/resource/k8s.md | 3 ++- model/registry/k8s.yaml | 7 ++++++- model/resource/k8s.yaml | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100755 .chloggen/k8s-status.yaml diff --git a/.chloggen/k8s-status.yaml b/.chloggen/k8s-status.yaml new file mode 100755 index 0000000000..cfbbe489ea --- /dev/null +++ b/.chloggen/k8s-status.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: "k8s" + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: add container.status.last_terminated_reason resource attribute + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [922] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index d60f610782..daf25dfb25 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -15,7 +15,8 @@ | `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.status.last_terminated_reason` | string | Last terminated reason of the Container. | `Evicted`; `Error` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/resource/k8s.md b/docs/resource/k8s.md index c26e90b3ee..0ee64504f5 100644 --- a/docs/resource/k8s.md +++ b/docs/resource/k8s.md @@ -114,7 +114,8 @@ to a running container. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`k8s.container.name`](../attributes-registry/k8s.md) | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.restart_count`](../attributes-registry/k8s.md) | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`k8s.container.status.last_terminated_reason`](../attributes-registry/k8s.md) | string | Last terminated reason of the Container. | `Evicted`; `Error` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## ReplicaSet diff --git a/model/registry/k8s.yaml b/model/registry/k8s.yaml index c4bfcd4765..013ede5c03 100644 --- a/model/registry/k8s.yaml +++ b/model/registry/k8s.yaml @@ -98,7 +98,12 @@ groups: Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. - examples: [0, 2] + - id: container.status.last_terminated_reason + type: string + stability: experimental + brief: > + Last terminated reason of the Container. + examples: ["Evicted", "Error"] - id: replicaset.uid type: string stability: experimental diff --git a/model/resource/k8s.yaml b/model/resource/k8s.yaml index e61bf0cad1..d94425e007 100644 --- a/model/resource/k8s.yaml +++ b/model/resource/k8s.yaml @@ -45,6 +45,7 @@ groups: attributes: - ref: k8s.container.name - ref: k8s.container.restart_count + - ref: k8s.container.status.last_terminated_reason - id: k8s.replicaset prefix: k8s.replicaset From 8590a71811155db6ee50157dedfbc31ff5b56887 Mon Sep 17 00:00:00 2001 From: Chris Mark Date: Wed, 1 May 2024 00:21:03 +0300 Subject: [PATCH 475/482] [metrics/system] Remove shared from system.memory.state values (#933) Signed-off-by: ChrsMark --- .chloggen/decouple_shared_memory_metric.yaml | 22 ++++++++++++++++++++ docs/attributes-registry/system.md | 2 +- docs/system/system-metrics.md | 21 +++++++++++++++++-- model/metrics/system-metrics.yaml | 11 ++++++++++ model/registry/system.yaml | 1 + 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100755 .chloggen/decouple_shared_memory_metric.yaml diff --git a/.chloggen/decouple_shared_memory_metric.yaml b/.chloggen/decouple_shared_memory_metric.yaml new file mode 100755 index 0000000000..5f5fb7be4e --- /dev/null +++ b/.chloggen/decouple_shared_memory_metric.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'breaking' + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: system + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Deprecate `shared` from `system.memory.state` values and make it a standalone metric + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [522] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/system.md b/docs/attributes-registry/system.md index 9760a9ee6b..a836fce9a9 100644 --- a/docs/attributes-registry/system.md +++ b/docs/attributes-registry/system.md @@ -52,7 +52,7 @@ |---|---|---| | `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, report shared memory usage with `metric.system.memory.shared` metric | | `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 8a62a0ec7d..91f4606aa9 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -30,6 +30,7 @@ Resource attributes related to a host, SHOULD be reported under the `host.*` nam - [Memory Metrics](#memory-metrics) - [Metric: `system.memory.usage`](#metric-systemmemoryusage) - [Metric: `system.memory.limit`](#metric-systemmemorylimit) + - [Metric: `system.memory.shared`](#metric-systemmemoryshared) - [Metric: `system.memory.utilization`](#metric-systemmemoryutilization) - [Paging/Swap Metrics](#pagingswap-metrics) - [Metric: `system.paging.usage`](#metric-systempagingusage) @@ -202,7 +203,7 @@ available on the system, that is `system.memory.limit`. |---|---|---| | `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, report shared memory usage with `metric.system.memory.shared` metric | | `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -222,6 +223,22 @@ This metric is [opt-in][MetricOptIn]. +### Metric: `system.memory.shared` + +This metric is [opt-in][MetricOptIn]. + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `system.memory.shared` | UpDownCounter | `By` | Shared memory used (mostly by tmpfs). [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Equivalent of `shared` from [`free` command](https://man7.org/linux/man-pages/man1/free.1.html) or +`Shmem` from [`/proc/meminfo`](https://man7.org/linux/man-pages/man5/proc.5.html)" + + + + + ### Metric: `system.memory.utilization` This metric is [recommended][MetricRecommended]. @@ -243,7 +260,7 @@ This metric is [recommended][MetricRecommended]. |---|---|---| | `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `shared` | shared | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | shared | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, report shared memory usage with `metric.system.memory.shared` metric | | `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/metrics/system-metrics.yaml b/model/metrics/system-metrics.yaml index a1e534e379..7d0ab1eb96 100644 --- a/model/metrics/system-metrics.yaml +++ b/model/metrics/system-metrics.yaml @@ -77,6 +77,17 @@ groups: unit: "By" attributes: [] + - id: metric.system.memory.shared + type: metric + metric_name: system.memory.shared + stability: experimental + brief: "Shared memory used (mostly by tmpfs)." + note: | + Equivalent of `shared` from [`free` command](https://man7.org/linux/man-pages/man1/free.1.html) or + `Shmem` from [`/proc/meminfo`](https://man7.org/linux/man-pages/man5/proc.5.html)" + instrument: updowncounter + unit: "By" + - id: metric.system.memory.utilization type: metric metric_name: system.memory.utilization diff --git a/model/registry/system.yaml b/model/registry/system.yaml index 19d3c60964..0766d4c8b2 100644 --- a/model/registry/system.yaml +++ b/model/registry/system.yaml @@ -68,6 +68,7 @@ groups: - id: shared value: 'shared' stability: experimental + deprecated: 'Removed, report shared memory usage with `metric.system.memory.shared` metric' - id: buffers value: 'buffers' stability: experimental From 48f50d7d8c39c9f1ac79543d45c8c8193a813c24 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 1 May 2024 09:33:31 -0700 Subject: [PATCH 476/482] Remove `db.instance.id` (#972) --- .chloggen/972.yaml | 22 ++++++++++++++++++++++ docs/attributes-registry/db.md | 4 ++-- docs/database/database-metrics.md | 1 - docs/database/database-spans.md | 1 - docs/database/elasticsearch.md | 2 +- model/db-common.yaml | 3 --- model/registry/db.yaml | 14 ++++++-------- model/registry/deprecated/db.yaml | 12 ++++++------ model/trace/database.yaml | 5 +---- 9 files changed, 38 insertions(+), 26 deletions(-) create mode 100644 .chloggen/972.yaml diff --git a/.chloggen/972.yaml b/.chloggen/972.yaml new file mode 100644 index 0000000000..9cebfe9f27 --- /dev/null +++ b/.chloggen/972.yaml @@ -0,0 +1,22 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Remove `db.instance.id`. For Elasticsearch, replace with `db.elasticsearch.node.name`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [ 972 ] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index da0022a380..829d9ca4e3 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -22,7 +22,6 @@ | `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.instance.id` | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.namespace` | string | The name of the database, fully qualified within the server address and port. [2] | `customers`; `test.users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -178,6 +177,7 @@ If a parameter has no name and instead is referenced only by index, then `` | Attribute | Type | Description | Examples | Stability | |---|---|---|---|---| | `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. @@ -191,7 +191,7 @@ If a parameter has no name and instead is referenced only by index, then `` | `db.cassandra.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | | `db.cosmosdb.container` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | -| `db.elasticsearch.node.name` | string | Deprecated, use `db.instance.id` instead. | `instance-0000000001` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.instance.id`. | +| `db.instance.id` | string | Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | `mysql-e26b99z.example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | | `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | | `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | | `db.mssql.instance_name` | string | Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute. | `MSSQLSERVER` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 2e0dde0db9..d91554259b 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -66,7 +66,6 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index 13e654c5e6..fb4d4d0bf3 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -79,7 +79,6 @@ These attributes will usually be the same for all operations performed over the | [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` If different from the `server.address` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [9] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index f95b4ffe80..8b09d5bd8d 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -32,7 +32,7 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | `Conditionally Required` when the url has dynamic values | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.instance.id`](../attributes-registry/db.md) | string | An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`. | `mysql-e26b99z.example.com` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.elasticsearch.node.name`](../attributes-registry/db.md) | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.query.text`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/model/db-common.yaml b/model/db-common.yaml index 8e2d1210d5..7cb8a90c18 100644 --- a/model/db-common.yaml +++ b/model/db-common.yaml @@ -11,9 +11,6 @@ groups: conditionally_required: > If readily available. Otherwise, if the instrumentation library parses `db.query.text` to capture `db.collection.name`, then it SHOULD be the first collection name found in the query. - - ref: db.instance.id - requirement_level: - recommended: If different from the `server.address` - ref: db.operation.name requirement_level: conditionally_required: > diff --git a/model/registry/db.yaml b/model/registry/db.yaml index eef192fe1d..612a9d2132 100644 --- a/model/registry/db.yaml +++ b/model/registry/db.yaml @@ -265,14 +265,6 @@ groups: brief: 'Trino' stability: experimental stability: experimental - - id: instance.id - type: string - stability: experimental - brief: > - An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. - This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. - The client may obtain this value in databases like MySQL using queries like `select @@hostname`. - examples: 'mysql-e26b99z.example.com' - id: client.connections.state stability: experimental type: @@ -476,6 +468,12 @@ groups: brief: > Represents the identifier of an Elasticsearch cluster. examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + - id: elasticsearch.node.name + type: string + stability: experimental + brief: > + Represents the human-readable identifier of the node/instance to which a request was routed. + examples: ["instance-0000000001"] - id: elasticsearch.path_parts type: template[string] stability: experimental diff --git a/model/registry/deprecated/db.yaml b/model/registry/deprecated/db.yaml index 8734714110..8e24430d20 100644 --- a/model/registry/deprecated/db.yaml +++ b/model/registry/deprecated/db.yaml @@ -18,12 +18,6 @@ groups: stability: experimental deprecated: 'Removed as not used.' examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] - - id: elasticsearch.node.name - type: string - brief: 'Deprecated, use `db.instance.id` instead.' - deprecated: "Replaced by `db.instance.id`." - stability: experimental - examples: ["instance-0000000001"] - id: operation type: string brief: 'Deprecated, use `db.operation.name` instead.' @@ -84,6 +78,12 @@ groups: brief: 'Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute.' deprecated: 'Deprecated, no replacement at this time.' examples: 'MSSQLSERVER' + - id: instance.id + type: string + stability: experimental + brief: 'Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead.' + deprecated: 'Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead.' + examples: 'mysql-e26b99z.example.com' - id: registry.db.metrics.deprecated type: attribute_group diff --git a/model/trace/database.yaml b/model/trace/database.yaml index fb3ab09a53..9cb433fedd 100644 --- a/model/trace/database.yaml +++ b/model/trace/database.yaml @@ -10,9 +10,6 @@ groups: SHOULD be collected by default only if there is sanitization that excludes sensitive information. - ref: db.query.parameter requirement_level: opt_in - - ref: db.instance.id - requirement_level: - recommended: If different from the `server.address` - id: db.tech_specific.network.attributes type: attribute_group @@ -210,7 +207,7 @@ groups: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. tag: tech-specific - - ref: db.instance.id + - ref: db.elasticsearch.node.name requirement_level: recommended: > When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. From 651d779183ecc7c2f8cfa90bf94e105f7b9d3f5a Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 1 May 2024 14:22:28 -0400 Subject: [PATCH 477/482] Generate Attribute Registry using Weaver (#917) --- .chloggen/917.yaml | 18 + .github/CODEOWNERS | 13 - .markdownlint.yaml | 1 + .prettierignore | 3 + CONTRIBUTING.md | 4 +- Makefile | 30 +- docs/attributes-registry/README.md | 105 ++--- docs/attributes-registry/android.md | 40 +- docs/attributes-registry/aspnetcore.md | 66 +-- docs/attributes-registry/aws.md | 217 +++++----- docs/attributes-registry/browser.md | 19 +- docs/attributes-registry/client.md | 27 +- docs/attributes-registry/cloud.md | 109 ++--- docs/attributes-registry/cloudevents.md | 23 +- docs/attributes-registry/code.md | 25 +- docs/attributes-registry/container.md | 61 ++- docs/attributes-registry/db.md | 378 ++++++++-------- docs/attributes-registry/deployment.md | 19 +- docs/attributes-registry/destination.md | 23 +- docs/attributes-registry/device.md | 19 +- docs/attributes-registry/disk.md | 23 +- docs/attributes-registry/dns.md | 15 +- docs/attributes-registry/enduser.md | 25 +- docs/attributes-registry/error.md | 21 +- docs/attributes-registry/event.md | 12 +- docs/attributes-registry/exception.md | 28 +- docs/attributes-registry/faas.md | 102 ++--- docs/attributes-registry/feature-flag.md | 21 +- docs/attributes-registry/file.md | 21 +- docs/attributes-registry/gcp.md | 52 +-- docs/attributes-registry/gen-ai.md | 35 ++ docs/attributes-registry/graphql.md | 29 +- docs/attributes-registry/heroku.md | 17 +- docs/attributes-registry/host.md | 59 +-- docs/attributes-registry/http.md | 117 +++-- docs/attributes-registry/ios.md | 31 +- docs/attributes-registry/jvm.md | 60 +-- docs/attributes-registry/k8s.md | 86 ++-- docs/attributes-registry/llm.md | 59 --- docs/attributes-registry/log.md | 56 ++- docs/attributes-registry/messaging.md | 289 +++++++------ docs/attributes-registry/network.md | 206 +++++---- docs/attributes-registry/oci.md | 18 +- docs/attributes-registry/opentracing.md | 21 +- docs/attributes-registry/os.md | 48 ++- docs/attributes-registry/otel.md | 69 ++- docs/attributes-registry/peer.md | 11 +- docs/attributes-registry/process.md | 59 +-- docs/attributes-registry/rpc.md | 208 +++++---- docs/attributes-registry/server.md | 23 +- docs/attributes-registry/service.md | 19 +- docs/attributes-registry/session.md | 15 +- docs/attributes-registry/signalr.md | 42 +- docs/attributes-registry/source.md | 23 +- docs/attributes-registry/system.md | 291 +++++++------ docs/attributes-registry/telemetry.md | 61 +-- docs/attributes-registry/thread.md | 17 +- docs/attributes-registry/tls.md | 81 ++-- docs/attributes-registry/url.md | 40 +- docs/attributes-registry/user-agent.md | 21 +- docs/attributes-registry/webengine.md | 15 +- docs/cloud-providers/aws-sdk.md | 18 +- docs/cloudevents/cloudevents-spans.md | 10 +- docs/database/cassandra.md | 22 +- docs/database/cosmosdb.md | 26 +- docs/database/couchdb.md | 2 +- docs/database/database-metrics.md | 38 +- docs/database/database-spans.md | 22 +- docs/database/dynamodb.md | 407 +++++++++++++++--- docs/database/elasticsearch.md | 22 +- docs/database/hbase.md | 4 +- docs/database/mongodb.md | 6 +- docs/database/mssql.md | 6 +- docs/database/redis.md | 8 +- docs/database/sql.md | 6 +- docs/dns/dns-metrics.md | 4 +- docs/dotnet/dotnet-aspnetcore-metrics.md | 28 +- docs/dotnet/dotnet-kestrel-metrics.md | 80 ++-- docs/dotnet/dotnet-signalr-metrics.md | 12 +- docs/exceptions/exceptions-logs.md | 6 +- docs/exceptions/exceptions-spans.md | 12 +- docs/faas/aws-lambda.md | 2 +- docs/faas/faas-metrics.md | 36 +- docs/faas/faas-spans.md | 40 +- docs/feature-flags/feature-flags-logs.md | 8 +- docs/feature-flags/feature-flags-spans.md | 8 +- docs/gen-ai/llm-spans.md | 34 +- docs/general/attributes.md | 68 +-- docs/general/events.md | 2 +- docs/general/logs.md | 12 +- docs/general/session.md | 4 +- docs/general/trace-compatibility.md | 2 +- docs/graphql/graphql-spans.md | 8 +- docs/http/http-metrics.md | 140 +++--- docs/http/http-spans.md | 104 ++--- docs/messaging/azure-messaging.md | 234 +++++++++- docs/messaging/gcp-pubsub.md | 8 +- docs/messaging/kafka.md | 10 +- docs/messaging/messaging-metrics.md | 26 +- docs/messaging/messaging-spans.md | 72 ++-- docs/messaging/rabbitmq.md | 8 +- docs/messaging/rocketmq.md | 22 +- docs/mobile/events.md | 2 - docs/resource/README.md | 18 +- docs/resource/android.md | 2 +- docs/resource/browser.md | 10 +- docs/resource/cloud-provider/aws/ecs.md | 14 +- docs/resource/cloud-provider/aws/eks.md | 2 +- docs/resource/cloud-provider/aws/logs.md | 8 +- docs/resource/cloud-provider/gcp/cloud-run.md | 4 +- docs/resource/cloud-provider/gcp/gce.md | 4 +- docs/resource/cloud-provider/heroku.md | 6 +- docs/resource/cloud.md | 12 +- docs/resource/container.md | 24 +- docs/resource/deployment-environment.md | 2 +- docs/resource/device.md | 8 +- docs/resource/faas.md | 10 +- docs/resource/host.md | 30 +- docs/resource/os.md | 10 +- docs/resource/process.md | 22 +- docs/resource/webengine.md | 6 +- docs/rpc/connect-rpc.md | 8 +- docs/rpc/grpc.md | 8 +- docs/rpc/json-rpc.md | 10 +- docs/rpc/rpc-metrics.md | 14 +- docs/rpc/rpc-spans.md | 52 +-- docs/runtime/jvm-metrics.md | 46 +- docs/system/container-metrics.md | 14 +- docs/system/process-metrics.md | 16 +- docs/system/system-metrics.md | 118 ++--- docs/url/url.md | 10 +- model/registry/exception.yaml | 2 +- templates/registry/markdown/attribute_name.j2 | 2 + .../markdown/attribute_namespace.md.j2 | 45 ++ templates/registry/markdown/attribute_type.j2 | 13 + templates/registry/markdown/examples.j2 | 10 + templates/registry/markdown/notes.j2 | 16 + templates/registry/markdown/readme.md.j2 | 40 ++ templates/registry/markdown/stability.j2 | 7 + templates/registry/markdown/weaver.yaml | 32 ++ 140 files changed, 3339 insertions(+), 2551 deletions(-) create mode 100644 .chloggen/917.yaml create mode 100644 docs/attributes-registry/gen-ai.md delete mode 100644 docs/attributes-registry/llm.md create mode 100644 templates/registry/markdown/attribute_name.j2 create mode 100644 templates/registry/markdown/attribute_namespace.md.j2 create mode 100644 templates/registry/markdown/attribute_type.j2 create mode 100644 templates/registry/markdown/examples.j2 create mode 100644 templates/registry/markdown/notes.j2 create mode 100644 templates/registry/markdown/readme.md.j2 create mode 100644 templates/registry/markdown/stability.j2 create mode 100644 templates/registry/markdown/weaver.yaml diff --git a/.chloggen/917.yaml b/.chloggen/917.yaml new file mode 100644 index 0000000000..b4f7c596bb --- /dev/null +++ b/.chloggen/917.yaml @@ -0,0 +1,18 @@ +change_type: enhancement +component: all + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Migrate Attribute Registry to be completely autogenerated. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [197] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + Migrate to using weaver for markdown generation (snippet + registry). + The entirety of the registry now is generated using weaver with templates + under the `templates/` directory. Snippets still require a hardcoded + command. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0b1b2e4672..132862aac6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -42,13 +42,6 @@ /model/registry/url.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers /model/registry/user-agent.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers /docs/http/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/http.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/server.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/client.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/network.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/error.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/url.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers -/docs/attribute-registry/user-agent.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-http-approvers # System semantic conventions approvers /docs/system/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-system-approvers @@ -62,14 +55,11 @@ # K8s semantic conventions approvers /docs/resource/k8s.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers -/docs/attributes-registry/k8s.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers /model/resource/k8s.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers /model/registry/k8s.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-k8s-approvers # Container semantic conventions approvers /docs/resource/container.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers -/docs/attributes-registry/container.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers -/docs/attributes-registry/oci.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers /model/resource/container.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers /model/registry/container.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers /model/registry/oci.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers @@ -79,14 +69,11 @@ /model/registry/aspnetcore.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers /model/registry/signalr.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers /docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers -/docs/attributes-registry/aspnetcore.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers -/docs/attributes-registry/signalr.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers # Gen-AI semantic conventions approvers /model/registry/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /model/metrics/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /model/trace/gen-ai.yaml @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers /docs/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers -/docs/attributes-registry/llm.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-llm-approvers # TODO - Add semconv area experts diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 61e39a0a22..d68351b3e6 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -12,3 +12,4 @@ ol-prefix: style: ordered no-inline-html: false fenced-code-language: false +no-space-in-code: false diff --git a/.prettierignore b/.prettierignore index 001890f677..c7137972a9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,5 +5,8 @@ /docs/** !/docs/cloud* !/docs/cloud*/** +!/docs/attributes-registry* +!/docs/attributes-registry*/** /model /schemas +CHANGELOG.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 152f6ce462..b3e8f596ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -103,10 +103,10 @@ You can also take examples from past changes inside the `schemas` folder. ### 2. Update the markdown files After updating the YAML file(s), you need to update -the respective markdown files. For this, run the following command: +the respective markdown files. For this, run the following commands: ```bash -make table-generation +make table-generation attribute-registry-generation ``` #### Hugo frontmatter diff --git a/Makefile b/Makefile index df33d8e6aa..fb099e9d45 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ CHLOGGEN_CONFIG := .chloggen/config.yaml # see https://github.com/open-telemetry/build-tools/releases for semconvgen updates # Keep links in model/README.md and .vscode/settings.json in sync! SEMCONVGEN_VERSION=0.24.0 +WEAVER_VERSION=latest # TODO: add `yamllint` step to `all` after making sure it works on Mac. .PHONY: all @@ -95,13 +96,31 @@ yamllint: .PHONY: table-generation table-generation: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec + otel/weaver:${WEAVER_VERSION} registry update-markdown \ + --registry=/source \ + --attribute-registry-base-url="/docs/attributes-registry" \ + /spec + +# Generate attribute registry markdown. +.PHONY: attribute-registry-generation +attribute-registry-generation: + docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec -v $(PWD)/templates:/weaver/templates \ + otel/weaver:${WEAVER_VERSION} registry generate \ + --registry=/source \ + --templates=/weaver/templates \ + markdown \ + /spec/attributes-registry/ + npm run fix:format -# Check if current markdown tables differ from the ones that would be generated from YAML definitions +# Check if current markdown tables differ from the ones that would be generated from YAML definitions (weaver). .PHONY: table-check table-check: docker run --rm -v $(PWD)/model:/source -v $(PWD)/docs:/spec \ - otel/semconvgen:$(SEMCONVGEN_VERSION) -f /source markdown -md /spec --md-check + otel/weaver:${WEAVER_VERSION} registry update-markdown \ + --registry=/source \ + --attribute-registry-base-url="/docs/attributes-registry" \ + --dry-run \ + /spec LATEST_RELEASED_SEMCONV_VERSION := $(shell git describe --tags --abbrev=0 | sed 's/v//g') .PHONY: compatibility-check @@ -122,14 +141,15 @@ fix-format: npm run fix:format # Run all checks in order of speed / likely failure. +# As a last thing, run attribute registry generation and git-diff for differences. .PHONY: check -check: misspell markdownlint check-format markdown-toc compatibility-check markdown-link-check +check: misspell markdownlint check-format markdown-toc compatibility-check markdown-link-check attribute-registry-generation git diff --exit-code ':*.md' || (echo 'Generated markdown Table of Contents is out of date, please run "make markdown-toc" and commit the changes in this PR.' && exit 1) @echo "All checks complete" # Attempt to fix issues / regenerate tables. .PHONY: fix -fix: table-generation misspell-correction fix-format markdown-toc +fix: table-generation attribute-registry-generation misspell-correction fix-format markdown-toc @echo "All autofixes complete" .PHONY: install-tools diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index 449246fc77..66f750c036 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -3,7 +3,10 @@ linkTitle: Registry weight: -2 ---> -# Attributes Registry + + + +# Attribute Registry The attributes registry is the place where attributes are defined. An attribute definition covers the following properties of an attribute: @@ -28,52 +31,58 @@ All registered attributes are listed by namespace in this registry. Currently, the following namespaces exist: -* [Android](android.md) -* [AWS](aws.md) -* [Browser](browser.md) -* [Client](client.md) -* [Cloud](cloud.md) -* [CloudEvents](cloudevents.md) -* [Code](code.md) -* [Container](container.md) -* [DB](db.md) (database) -* [Deployment](deployment.md) -* [Destination](destination.md) -* [Device](device.md) -* [Disk](disk.md) -* [End user](enduser.md) -* [Error](error.md) -* [Event](event.md) -* [Exception](exception.md) -* [FaaS](faas.md) -* [Feature Flag](feature-flag.md) -* [File](file.md) -* [Google Cloud Platform (GCP)](gcp.md) -* [GraphQl](graphql.md) -* [Heroku](heroku.md) -* [Host](host.md) -* [HTTP](http.md) -* [iOS](ios.md) -* [JVM](jvm.md) -* [K8s](k8s.md) -* [Log](log.md) -* [Network](network.md) -* [OCI](oci.md) -* [OpenTelemetry](otel.md) -* [OpenTracing](opentracing.md) -* [OS](os.md) -* [Peer](peer.md) -* [Process](process.md) -* [RPC](rpc.md) -* [Server](server.md) -* [Service](service.md) -* [Session](session.md) -* [Source](source.md) -* [Telemetry](telemetry.md) -* [Thread](thread.md) -* [TLS](tls.md) -* [URL](url.md) -* [User agent](user-agent.md) -* [Webengine](webengine.md) +- [Android](android.md) +- [Aspnetcore](aspnetcore.md) +- [AWS](aws.md) +- [Browser](browser.md) +- [Client](client.md) +- [Cloud](cloud.md) +- [CloudEvents](cloudevents.md) +- [Code](code.md) +- [Container](container.md) +- [Db](db.md) +- [Deployment](deployment.md) +- [Destination](destination.md) +- [Device](device.md) +- [Disk](disk.md) +- [Dns](dns.md) +- [Enduser](enduser.md) +- [Error](error.md) +- [Event](event.md) +- [Exception](exception.md) +- [Faas](faas.md) +- [Feature Flag](feature-flag.md) +- [File](file.md) +- [GCP](gcp.md) +- [Gen AI](gen-ai.md) +- [GraphQL](graphql.md) +- [Heroku](heroku.md) +- [Host](host.md) +- [HTTP](http.md) +- [iOS](ios.md) +- [JVM](jvm.md) +- [K8s](k8s.md) +- [Log](log.md) +- [Messaging](messaging.md) +- [Network](network.md) +- [OCI](oci.md) +- [OpenTracing](opentracing.md) +- [OS](os.md) +- [OTel](otel.md) +- [Peer](peer.md) +- [Process](process.md) +- [RPC](rpc.md) +- [Server](server.md) +- [Service](service.md) +- [Session](session.md) +- [SignalR](signalr.md) +- [Source](source.md) +- [System](system.md) +- [Telemetry](telemetry.md) +- [Thread](thread.md) +- [TLS](tls.md) +- [URL](url.md) +- [User Agent](user-agent.md) +- [Webengine](webengine.md) [developers recommendations]: ../general/attribute-naming.md#recommendations-for-application-developers diff --git a/docs/attributes-registry/android.md b/docs/attributes-registry/android.md index 971f390749..2e93f84293 100644 --- a/docs/attributes-registry/android.md +++ b/docs/attributes-registry/android.md @@ -1,34 +1,36 @@ -# Android + - + + -- [Android Attributes](#android-attributes) -- [Deprecated Android Attributes](#deprecated-android-attributes) +# Android - +- [Android](#android-attributes) +- [Android Deprecated](#android-deprecated-attributes) ## Android Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +The Android platform on which the Android application is running. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------- | | `android.os.api_level` | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -## Deprecated Android Attributes +## Android Deprecated Attributes + +This document defines attributes that represents an occurrence of a lifecycle transition on the Android platform. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `android.state` | string | Deprecated use the `device.app.lifecycle` event definition including `android.state` as a payload field instead. [1] | `created` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| --------------- | ------ | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------- | +| `android.state` | string | Deprecated use the `device.app.lifecycle` event definition including `android.state` as a payload field instead. [1] | `created`; `background`; `foreground` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived. `android.state` 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 | Stability | -|---|---|---| -| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `created` | Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `foreground` | Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file diff --git a/docs/attributes-registry/aspnetcore.md b/docs/attributes-registry/aspnetcore.md index 533eae5635..cde54126ba 100644 --- a/docs/attributes-registry/aspnetcore.md +++ b/docs/attributes-registry/aspnetcore.md @@ -1,46 +1,46 @@ -# ASP.NET Core + - + + -- [ASP.NET Core Attributes](#aspnet-core-attributes) +# Aspnetcore - +## Aspnetcore Attributes -## ASP.NET Core Attributes +ASP.NET Core attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.request.is_unhandled` | boolean | Flag indicating if request was handled by the application pipeline. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `True` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------- | +| `aspnetcore.diagnostics.exception.result` | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled`; `skipped` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.policy` | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.rate_limiting.result` | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `endpoint_limiter`; `global_limiter` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.request.is_unhandled` | boolean | Flag indicating if request was handled by the application pipeline. | `true` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.is_fallback` | boolean | A value that indicates whether the matched route is a fallback route. | `true` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aspnetcore.routing.match_status` | string | Match result - success or failure | `success`; `failure` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`aspnetcore.rate_limiting.result` 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. +`aspnetcore.diagnostics.exception.result` 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 | Stability | -|---|---|---| -| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| ----------- | ---------------------------------------------------------------- | ---------------------------------------------------------- | +| `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`aspnetcore.diagnostics.exception.result` MUST be one of the following: +`aspnetcore.rate_limiting.result` 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 | Stability | -|---|---|---| -| `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| ------------------ | -------------------------------------------------- | ---------------------------------------------------------- | +| `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `aspnetcore.routing.match_status` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| --------- | --------------- | ---------------------------------------------------------- | | `success` | Match succeeded | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - \ No newline at end of file +| `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/aws.md b/docs/attributes-registry/aws.md index 824b0f95ff..1d8cac0f66 100644 --- a/docs/attributes-registry/aws.md +++ b/docs/attributes-registry/aws.md @@ -1,130 +1,140 @@ + + + + + # AWS - +- [Aws](#aws-attributes) +- [Aws Dynamodb](#aws-dynamodb-attributes) +- [Aws Ecs](#aws-ecs-attributes) +- [Aws Eks](#aws-eks-attributes) +- [Aws Lambda](#aws-lambda-attributes) +- [Aws Log](#aws-log-attributes) +- [Aws S3](#aws-s3-attributes) -- [AWS Generic Attributes](#aws-generic-attributes) -- [AWS DynamoDB Attributes](#aws-dynamodb-attributes) -- [AWS ECS Attributes](#aws-ecs-attributes) -- [AWS EKS Attributes](#aws-eks-attributes) -- [AWS Lambda Attributes](#aws-lambda-attributes) -- [AWS Logs Attributes](#aws-logs-attributes) -- [AWS S3 Attributes](#aws-s3-attributes) +## Aws Attributes - +This document defines generic attributes for AWS services. -## AWS Generic Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------- | | `aws.request_id` | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## AWS DynamoDB Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## AWS ECS Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Aws Dynamodb Attributes + +This document defines attributes for AWS DynamoDB. + +| Attribute | Type | Description | Examples | Stability | +| --------------------------------------------- | -------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `aws.dynamodb.attribute_definitions` | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `{ "AttributeName": "string", "AttributeType": "string" }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.attributes_to_get` | string[] | The value of the `AttributesToGet` request parameter. | `lives`; `id` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consistent_read` | boolean | The value of the `ConsistentRead` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.consumed_capacity` | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.count` | int | The value of the `Count` response parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.exclusive_start_table` | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_index_updates` | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.global_secondary_indexes` | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.index_name` | string | The value of the `IndexName` request parameter. | `name_to_group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.item_collection_metrics` | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.limit` | int | The value of the `Limit` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.local_secondary_indexes` | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.projection` | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_read_capacity` | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.provisioned_write_capacity` | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scan_forward` | boolean | The value of the `ScanIndexForward` request parameter. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.scanned_count` | int | The value of the `ScannedCount` response parameter. | `50` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.segment` | int | The value of the `Segment` request parameter. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.select` | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_count` | int | The number of items in the `TableNames` response parameter. | `20` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.table_names` | string[] | The keys in the `RequestItems` object field. | `Users`; `Cats` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.dynamodb.total_segments` | int | The value of the `TotalSegments` request parameter. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Aws Ecs Attributes + +This document defines attributes for AWS Elastic Container Service (ECS). + +| Attribute | Type | Description | Examples | Stability | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `aws.ecs.cluster.arn` | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.container.arn` | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.launchtype` | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2`; `fargate` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.arn` | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.family` | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.id` | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.ecs.task.revision` | string | The revision for the task definition used to create the ECS task. | `8`; `26` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `aws.ecs.launchtype` 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 | Stability | -|---|---|---| -| `ec2` | ec2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `fargate` | fargate | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Value | Description | Stability | +| --------- | ----------- | ---------------------------------------------------------------- | +| `ec2` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fargate` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Aws Eks Attributes + +This document defines attributes for AWS Elastic Kubernetes Service (EKS). -## AWS EKS Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | -------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------- | | `aws.eks.cluster.arn` | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -## AWS Lambda Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Aws Lambda Attributes + +This document defines attributes for AWS Lambda. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------- | | `aws.lambda.invoked_arn` | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This may be different from `cloud.resource_id` if an alias is involved. - - -## AWS Logs Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). - -**[2]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. - -**[3]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. - - -## AWS S3 Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [1] | `some-bucket-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [2] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [3] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [4] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [5] | `3456` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [6] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. + +## Aws Log Attributes + +This document defines attributes for AWS Logs. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | -------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `aws.log.group.arns` | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [2] | `arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.group.names` | string[] | The name(s) of the AWS log group(s) an application is writing to. [3] | `/aws/lambda/my-function`; `opentelemetry-service` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.arns` | string[] | The ARN(s) of the AWS log stream(s). [4] | `arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.log.stream.names` | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `logs/main/10838bed-421f-43ef-870a-f43feacbbb5b` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[2]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + +**[3]:** Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + +**[4]:** See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + +## Aws S3 Attributes + +This document defines attributes for AWS S3. + +| Attribute | Type | Description | Examples | Stability | +| -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `aws.s3.bucket` | string | The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [5] | `some-bucket-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.copy_source` | string | The source object (in the form `bucket`/`key`) for the copy operation. [6] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.delete` | string | The delete request container that specifies the objects to be deleted. [7] | `Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.key` | string | The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. [8] | `someFile.yml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.part_number` | int | The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. [9] | `3456` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws.s3.upload_id` | string | Upload ID that identifies the multipart upload. [10] | `dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[5]:** The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations except `list-buckets`. -**[2]:** The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter +**[6]:** The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). This applies in particular to the following operations: - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) -**[3]:** The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. +**[7]:** The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. The `delete` attribute corresponds to the `--delete` parameter of the [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). -**[4]:** The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. +**[8]:** The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. This applies in particular to the following operations: - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) @@ -141,12 +151,12 @@ This applies in particular to the following operations: - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) -**[5]:** The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +**[9]:** The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. The `part_number` attribute corresponds to the `--part-number` parameter of the [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). -**[6]:** The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter +**[10]:** The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. This applies in particular to the following operations: @@ -155,4 +165,3 @@ This applies in particular to the following operations: - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) - \ No newline at end of file diff --git a/docs/attributes-registry/browser.md b/docs/attributes-registry/browser.md index fd51f5bf79..b41fd19074 100644 --- a/docs/attributes-registry/browser.md +++ b/docs/attributes-registry/browser.md @@ -1,17 +1,21 @@ + + + # Browser ## Browser Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +The web browser attributes + +| Attribute | Type | Description | Examples | Stability | +| ------------------ | -------- | ----------------------------------------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------- | +| `browser.brands` | string[] | Array of brand name and version separated by a space [1] | ` Not A;Brand 99`; `Chromium 99`; `Chrome 99` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.language` | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.mobile` | boolean | A boolean that is true if the browser is running on a mobile device [3] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `browser.platform` | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). @@ -21,4 +25,3 @@ **[4]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. - diff --git a/docs/attributes-registry/client.md b/docs/attributes-registry/client.md index f09e3b672b..5b72bfbba3 100644 --- a/docs/attributes-registry/client.md +++ b/docs/attributes-registry/client.md @@ -1,23 +1,20 @@ -# Client Attributes + + -These attributes may be used to describe the client in a connection-based network interaction -where there is one side that initiates the connection (the client is the side that initiates the connection). -This covers all TCP network interactions since TCP is connection-based and one side initiates the -connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the -protocol / API does not expose a clear notion of client and server). -This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. +# Client - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Client Attributes + +These attributes may be used to describe the client in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------- | | `client.address` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `client.port` | int | Client port number. [2] | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `client.port` | int | Client port number. [2] | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. - +**[2]:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. diff --git a/docs/attributes-registry/cloud.md b/docs/attributes-registry/cloud.md index 76176b3c93..1eac23995a 100644 --- a/docs/attributes-registry/cloud.md +++ b/docs/attributes-registry/cloud.md @@ -1,19 +1,23 @@ + + + # Cloud ## Cloud Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +A cloud environment (e.g. GCP, Azure, AWS). + +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `cloud.account.id` | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.availability_zone` | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.platform` | string | The cloud platform in use. [2] | `alibaba_cloud_ecs`; `alibaba_cloud_fc`; `alibaba_cloud_openshift` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.provider` | string | Name of the cloud provider. | `alibaba_cloud`; `aws`; `azure` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.region` | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloud.resource_id` | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. @@ -27,60 +31,59 @@ so it may be necessary to set `cloud.resource_id` as a span attribute instead. The exact value to use for `cloud.resource_id` depends on the cloud provider. The following well-known definitions MUST be used if you set this attribute and they apply: -* **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). +- **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). Take care not to use the "invoked ARN" directly but replace any [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) with the resolved function version, as the same runtime instance may be invokable with multiple different aliases. -* **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -* **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form +- **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) +- **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, + _not_ the function app, having the form `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share a TracerProvider. `cloud.platform` 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 | Stability | -|---|---|---| -| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_ec2` | AWS Elastic Compute Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_ecs` | AWS Elastic Container Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_eks` | AWS Elastic Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_lambda` | AWS Lambda | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_app_runner` | AWS App Runner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_vm` | Azure Virtual Machines | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_container_apps` | Azure Container Apps | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_container_instances` | Azure Container Instances | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_aks` | Azure Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_functions` | Azure Functions | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_app_service` | Azure App Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure_openshift` | Azure Red Hat OpenShift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_cloud_run` | Google Cloud Run | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_cloud_functions` | Google Cloud Functions (GCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_app_engine` | Google Cloud App Engine (GAE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_openshift` | Red Hat OpenShift on Google Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| --------------------------- | ---------------------------------------------- | ---------------------------------------------------------------- | +| `alibaba_cloud_ecs` | Alibaba Cloud Elastic Compute Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_fc` | Alibaba Cloud Function Compute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `alibaba_cloud_openshift` | Red Hat OpenShift on Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ec2` | AWS Elastic Compute Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_ecs` | AWS Elastic Container Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_eks` | AWS Elastic Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_lambda` | AWS Lambda | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_elastic_beanstalk` | AWS Elastic Beanstalk | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_app_runner` | AWS App Runner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_openshift` | Red Hat OpenShift on AWS (ROSA) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_vm` | Azure Virtual Machines | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_apps` | Azure Container Apps | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_container_instances` | Azure Container Instances | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_aks` | Azure Kubernetes Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_functions` | Azure Functions | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_app_service` | Azure App Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure_openshift` | Azure Red Hat OpenShift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_bare_metal_solution` | Google Bare Metal Solution (BMS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_compute_engine` | Google Cloud Compute Engine (GCE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_run` | Google Cloud Run | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_kubernetes_engine` | Google Cloud Kubernetes Engine (GKE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_cloud_functions` | Google Cloud Functions (GCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_app_engine` | Google Cloud App Engine (GAE) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_openshift` | Red Hat OpenShift on Google Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud_openshift` | Red Hat OpenShift on IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_cvm` | Tencent Cloud Cloud Virtual Machine (CVM) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_eks` | Tencent Cloud Elastic Kubernetes Service (EKS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud_scf` | Tencent Cloud Serverless Cloud Function (SCF) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `cloud.provider` 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 | Stability | -|---|---|---| -| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `heroku` | Heroku Platform as a Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ibm_cloud` | IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| Value | Description | Stability | +| --------------- | ---------------------------- | ---------------------------------------------------------------- | +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku` | Heroku Platform as a Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ibm_cloud` | IBM Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/cloudevents.md b/docs/attributes-registry/cloudevents.md index f7a7204310..86868e920f 100644 --- a/docs/attributes-registry/cloudevents.md +++ b/docs/attributes-registry/cloudevents.md @@ -1,16 +1,19 @@ + + + # CloudEvents -## CloudEvents Attributes +## Cloudevents Attributes + +This document defines attributes for CloudEvents. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Attribute | Type | Description | Examples | Stability | +| -------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `cloudevents.event_id` | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_source` | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_spec_version` | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_subject` | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudevents.event_type` | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/code.md b/docs/attributes-registry/code.md index de298c4526..752171c68b 100644 --- a/docs/attributes-registry/code.md +++ b/docs/attributes-registry/code.md @@ -1,19 +1,20 @@ -# Code + + -These attributes allow to report this unit of code and therefore to provide more context about the telemetry data. +# Code ## Code Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `code.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +These attributes allow to report this unit of code and therefore to provide more context about the span. + +| Attribute | Type | Description | Examples | Stability | +| ----------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | +| `code.column` | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.filepath` | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.function` | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.lineno` | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.namespace` | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `code.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index 2459f17e24..eb62fd417f 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -1,32 +1,32 @@ -# Container - - + + -- [Container Attributes](#container-attributes) -- [Deprecated Container Attributes](#deprecated-container-attributes) +# Container - +- [Container](#container-attributes) +- [Container Deprecated](#container-deprecated-attributes) ## Container Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.cpu.state` | string | The CPU state for this data point. | `user`; `kernel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.label.` | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +A container instance. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `container.command` | string | The command used to run the container (i.e. the command name). [1] | `otelcontribcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `otelcontribcol, --config, config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.command_line` | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.cpu.state` | string | The CPU state for this data point. | `user`; `system`; `kernel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.id` | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [2] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.name` | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [3] | `example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb`; `internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.image.tags` | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `v1.27.1`; `3.5.7-0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.label.` | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.name` | string | Container name used by container runtime. | `opentelemetry-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.runtime` | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. @@ -38,17 +38,16 @@ The ID is assigned by the container runtime and can vary in different environmen `container.cpu.state` 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 | Stability | -|---|---|---| -| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| -------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `user` | When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | When CPU is used by the system (host OS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `kernel` | When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -## Deprecated Container Attributes +## Container Deprecated Attributes + +Describes deprecated container attributes. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | ------ | ------------------------------------------ | --------------------------- | --------------------------------------------------------------------------------------------- | | `container.labels.` | string | Deprecated, use `container.label` instead. | `container.label.app=nginx` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `container.label`. | - diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 829d9ca4e3..2f0f35303e 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -1,32 +1,32 @@ -# Database + + - +# Db -- [Generic Database Attributes](#generic-database-attributes) -- [Cassandra Attributes](#cassandra-attributes) -- [CosmosDB Attributes](#cosmosdb-attributes) -- [Elasticsearch Attributes](#elasticsearch-attributes) -- [Deprecated DB Attributes](#deprecated-db-attributes) -- [Deprecated DB Metrics Attributes](#deprecated-db-metrics-attributes) +- [Db](#db-attributes) +- [Db Cassandra](#db-cassandra-attributes) +- [Db Cosmosdb](#db-cosmosdb-attributes) +- [Db Deprecated](#db-deprecated-attributes) +- [Db Elasticsearch](#db-elasticsearch-attributes) +- [Db Metrics Deprecated](#db-metrics-deprecated-attributes) - +## Db Attributes -## Generic Database Attributes +This group defines the attributes used to describe telemetry in the context of databases. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.client.connections.state` | string | The state of a connection in the pool | `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.namespace` | string | The name of the database, fully qualified within the server address and port. [2] | `customers`; `test.users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| --------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `db.client.connections.pool.name` | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connections.state` | string | The state of a connection in the pool | `idle`; `used` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.collection.name` | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.namespace` | string | The name of the database, fully qualified within the server address and port. [2] | `customers`; `test.users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.operation.name` | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.parameter.` | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [3] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.query.text` | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.system` | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. @@ -38,182 +38,182 @@ If a parameter has no name and instead is referenced only by index, then `` `db.client.connections.state` 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 | Stability | -|---|---|---| -| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------ | ----------- | ---------------------------------------------------------------- | +| `idle` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `db.system` 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 | Stability | -|---|---|---| -| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Cassandra Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`db.cassandra.consistency_level` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `all` | all | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `each_quorum` | each_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `quorum` | quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `local_quorum` | local_quorum | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `one` | one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `two` | two | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `three` | three | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `local_one` | local_one | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `any` | any | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `serial` | serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `local_serial` | local_serial | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## CosmosDB Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`db.cosmosdb.connection_mode` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --------------- | -------------------------------------------------- | ---------------------------------------------------------------- | +| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Db Cassandra Attributes + +This group defines attributes for Cassandra. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------- | +| `db.cassandra.consistency_level` | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all`; `each_quorum`; `quorum` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.coordinator.dc` | string | The data center of the coordinating node for a query. | `us-west-2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.coordinator.id` | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.idempotence` | boolean | Whether or not the query is idempotent. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.page_size` | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cassandra.speculative_execution_count` | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`db.cassandra.consistency_level` 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 | Stability | +| -------------- | ----------- | ---------------------------------------------------------------- | +| `all` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `each_quorum` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `quorum` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_quorum` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `one` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `two` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `three` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_one` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `any` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `serial` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `local_serial` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Db Cosmosdb Attributes + +This group defines attributes for Azure Cosmos DB. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------------ | ------ | --------------------------------- | -------------------------------------- | ---------------------------------------------------------------- | +| `db.cosmosdb.client_id` | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.connection_mode` | string | Cosmos client connection mode. | `gateway`; `direct` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.operation_type` | string | CosmosDB Operation Type. | `Invalid`; `Create`; `Patch` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.request_charge` | double | RU consumed for that operation | `46.18`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.request_content_length` | int | Request payload size in bytes | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.status_code` | int | Cosmos DB status code. | `200`; `201` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.cosmosdb.sub_status_code` | int | Cosmos DB sub status code. | `1000`; `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`db.cosmosdb.connection_mode` 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 | Stability | +| --------- | ------------------------------- | ---------------------------------------------------------------- | | `gateway` | Gateway (HTTP) connections mode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `direct` | Direct connection. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `direct` | Direct connection. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `db.cosmosdb.operation_type` 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 | Stability | -|---|---|---| -| `Invalid` | invalid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Create` | create | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Patch` | patch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ReadFeed` | read_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Replace` | replace | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Execute` | execute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Query` | query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Head` | head | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `HeadFeed` | head_feed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Upsert` | upsert | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `Batch` | batch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `QueryPlan` | query_plan | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ExecuteJavaScript` | execute_javascript | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Elasticsearch Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [1] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. - - -## Deprecated DB Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `db.cassandra.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | -| `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | -| `db.cosmosdb.container` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | -| `db.instance.id` | string | Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | `mysql-e26b99z.example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | -| `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | -| `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | -| `db.mssql.instance_name` | string | Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute. | `MSSQLSERVER` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | -| `db.name` | string | Deprecated, use `db.namespace` instead. | `customers`; `main` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | -| `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | -| `db.redis.database_index` | int | Deprecated, use `db.namespace` instead. | `0`; `1`; `15` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | -| `db.sql.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | -| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | -| `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | - - -## Deprecated DB Metrics Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Value | Description | Stability | +| ------------------- | ----------- | ---------------------------------------------------------------- | +| `Invalid` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Create` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Patch` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Read` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ReadFeed` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Delete` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Replace` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Execute` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Query` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Head` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `HeadFeed` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Upsert` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `Batch` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `QueryPlan` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ExecuteJavaScript` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Db Deprecated Attributes + +"Describes deprecated db attributes." + +| Attribute | Type | Description | Examples | Stability | +| -------------------------- | ------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `db.cassandra.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.connection_string` | string | Deprecated, use `server.address`, `server.port` attributes instead. | `Server=(localdb)\v11.0;Integrated Security=true;` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
"Replaced by `server.address` and `server.port`." | +| `db.cosmosdb.container` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.instance.id` | string | Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | `mysql-e26b99z.example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. | +| `db.jdbc.driver_classname` | string | Removed, no replacement at this time. | `org.postgresql.Driver`; `com.microsoft.sqlserver.jdbc.SQLServerDriver` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed as not used. | +| `db.mongodb.collection` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.mssql.instance_name` | string | Deprecated, SQL Server instance is now populated as a part of `db.namespace` attribute. | `MSSQLSERVER` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Deprecated, no replacement at this time. | +| `db.name` | string | Deprecated, use `db.namespace` instead. | `customers`; `main` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | +| `db.operation` | string | Deprecated, use `db.operation.name` instead. | `findAndModify`; `HMSET`; `SELECT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.operation.name`. | +| `db.redis.database_index` | int | Deprecated, use `db.namespace` instead. | `0`; `1`; `15` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | +| `db.sql.table` | string | Deprecated, use `db.collection.name` instead. | `mytable` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.collection.name`. | +| `db.statement` | string | The database statement being executed. | `SELECT * FROM wuser_table`; `SET mykey "WuValue"` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.query.text`. | +| `db.user` | string | Deprecated, no replacement at this time. | `readonly_user`; `reporting_user` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | + +## Db Elasticsearch Attributes + +This group defines attributes for Elasticsearch. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------- | ------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `db.elasticsearch.cluster.name` | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.node.name` | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[4]:** Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names. + +## Db Metrics Deprecated Attributes + +"Describes deprecated db metrics attributes." + +| Attribute | Type | Description | Examples | Stability | +| ----------- | ------ | ---------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------- | | `pool.name` | string | Deprecated, use `db.client.connections.pool.name` instead. | `myDataSource` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.pool.name`. | -| `state` | string | Deprecated, use `db.client.connections.state` instead. | `idle` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.state`. | +| `state` | string | Deprecated, use `db.client.connections.state` instead. | `idle`; `used` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.client.connections.state`. | `state` 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 | Stability | -|---|---|---| -| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| Value | Description | Stability | +| ------ | ----------- | ---------------------------------------------------------------- | +| `idle` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `used` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/deployment.md b/docs/attributes-registry/deployment.md index a29d864de4..97c68f3ebf 100644 --- a/docs/attributes-registry/deployment.md +++ b/docs/attributes-registry/deployment.md @@ -1,9 +1,17 @@ + + + + + # Deployment ## Deployment Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| + +This document defines attributes for software deployments. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------ | ----------------------- | ---------------------------------------------------------------- | | `deployment.environment` | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** `deployment.environment` does not affect the uniqueness constraints defined through @@ -11,6 +19,5 @@ the `service.namespace`, `service.name` and `service.instance.id` resource attri This implies that resources carrying the following attribute combinations MUST be considered to be identifying the same service: -* `service.name=frontend`, `deployment.environment=production` -* `service.name=frontend`, `deployment.environment=staging`. - +- `service.name=frontend`, `deployment.environment=production` +- `service.name=frontend`, `deployment.environment=staging`. diff --git a/docs/attributes-registry/destination.md b/docs/attributes-registry/destination.md index b20874d107..23b35bbcd1 100644 --- a/docs/attributes-registry/destination.md +++ b/docs/attributes-registry/destination.md @@ -1,21 +1,18 @@ -# Destination Attributes + + -These attributes may be used to describe the receiver of a network exchange/packet. These should be used -when there is no client/server relationship between the two sides, or when that relationship is unknown. -This covers low-level network interactions (e.g. packet tracing) where you don't know if -there was a connection or which side initiated it. -This also covers unidirectional UDP flows and peer-to-peer communication where the -"user-facing" surface of the protocol / API does not expose a clear notion of client and server. +# Destination - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Destination Attributes + +These attributes may be used to describe the receiver of a network exchange/packet. These should be used when there is no client/server relationship between the two sides, or when that relationship is unknown. This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server. + +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------- | | `destination.address` | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `destination.port` | int | Destination port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `destination.port` | int | Destination port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. - diff --git a/docs/attributes-registry/device.md b/docs/attributes-registry/device.md index c52d23f5fa..3ce6b15385 100644 --- a/docs/attributes-registry/device.md +++ b/docs/attributes-registry/device.md @@ -1,17 +1,21 @@ + + + # Device ## Device Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Describes device attributes. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | ----------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------- | +| `device.id` | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.manufacturer` | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.model.identifier` | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `device.model.name` | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. @@ -20,4 +24,3 @@ **[3]:** It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. **[4]:** It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. - diff --git a/docs/attributes-registry/disk.md b/docs/attributes-registry/disk.md index b52b79af0f..1dfa838a62 100644 --- a/docs/attributes-registry/disk.md +++ b/docs/attributes-registry/disk.md @@ -1,19 +1,22 @@ + + + # Disk ## Disk Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `disk.io.direction` | string | The disk IO operation direction. | `read` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +These attributes may be used for any disk related operation. + +| Attribute | Type | Description | Examples | Stability | +| ------------------- | ------ | -------------------------------- | --------------- | ---------------------------------------------------------------- | +| `disk.io.direction` | string | The disk IO operation direction. | `read`; `write` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | -|---|---|---| -| `read` | read | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `write` | write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Value | Description | Stability | +| ------- | ----------- | ---------------------------------------------------------------- | +| `read` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `write` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/dns.md b/docs/attributes-registry/dns.md index 59079ab01e..6345d59240 100644 --- a/docs/attributes-registry/dns.md +++ b/docs/attributes-registry/dns.md @@ -1,14 +1,17 @@ -# DNS + + -## DNS Attributes +# Dns - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Dns Attributes + +This document defines the shared attributes used to report a DNS query. + +| Attribute | Type | Description | Examples | Stability | +| ------------------- | ------ | --------------------------- | ------------------------------------- | ---------------------------------------------------------------- | | `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. - \ No newline at end of file diff --git a/docs/attributes-registry/enduser.md b/docs/attributes-registry/enduser.md index 616c7f89ad..9fa388eeac 100644 --- a/docs/attributes-registry/enduser.md +++ b/docs/attributes-registry/enduser.md @@ -1,10 +1,17 @@ -# End User - -## End User Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + + + + +# Enduser + +## Enduser Attributes + +This document defines attributes for operations with an authenticated and/or authorized enduser. + +| Attribute | Type | Description | Examples | Stability | +| --------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------- | +| `enduser.id` | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `enduser.role` | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `enduser.scope` | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/error.md b/docs/attributes-registry/error.md index a97583c0f4..d74465057f 100644 --- a/docs/attributes-registry/error.md +++ b/docs/attributes-registry/error.md @@ -1,14 +1,18 @@ + + + # Error ## Error Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `error.type` | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +This document defines the shared attributes used to report an error. + +| Attribute | Type | Description | Examples | Stability | +| ------------ | ------ | -------------------------------------------------------- | -------- | ---------------------------------------------------------- | +| `error.type` | string | Describes a class of error the operation ended with. [1] | `_OTHER` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -27,12 +31,11 @@ If the operation has completed successfully, instrumentations SHOULD NOT set `er If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to: -* Use a domain-specific attribute -* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. +- Use a domain-specific attribute +- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. `error.type` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| -------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - \ No newline at end of file diff --git a/docs/attributes-registry/event.md b/docs/attributes-registry/event.md index c377cf5068..049ae6066f 100644 --- a/docs/attributes-registry/event.md +++ b/docs/attributes-registry/event.md @@ -1,15 +1,17 @@ + + + # Event ## Event Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +Attributes for Events represented using Log Records. + +| Attribute | Type | Description | Examples | Stability | +| ------------ | ------ | ----------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------- | | `event.name` | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. - diff --git a/docs/attributes-registry/exception.md b/docs/attributes-registry/exception.md index 22f4bfc5c6..7bc639e34a 100644 --- a/docs/attributes-registry/exception.md +++ b/docs/attributes-registry/exception.md @@ -1,17 +1,21 @@ -# Exceptions + + + +# Exception ## Exception Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +This document defines the shared attributes used to report a single exception associated with a span or log. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | +| `exception.escaped` | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [1] | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.message` | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.stacktrace` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `exception.type` | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** An exception is considered to have escaped (or left) the scope of a span, if that span is ended while the exception is still logically "in flight". @@ -23,15 +27,9 @@ It is usually not possible to determine at the point where an exception is throw whether it will escape the scope of a span. However, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span, -as done in the [example for recording span exceptions](#recording-an-exception). +as done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, since the event might have been recorded at a time where it was not clear whether the exception will escape. - - -### Recording An Exception - -The `exception.escaped` attribute has special semantics in the context of -a span. Please read the [details here](../exceptions/exceptions-spans.md#recording-an-exception). diff --git a/docs/attributes-registry/faas.md b/docs/attributes-registry/faas.md index ec0a9a61c2..fd7a4bcd0d 100644 --- a/docs/attributes-registry/faas.md +++ b/docs/attributes-registry/faas.md @@ -1,32 +1,35 @@ -# FaaS - -## FaaS Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [1] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.invoked_name` | string | The name of the invoked function. [2] | `my-function` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.invoked_provider` | string | The cloud provider of the invoked function. [3] | `alibaba_cloud` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.invoked_region` | string | The cloud region of the invoked function. [4] | `eu-central-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [5] | `134217728` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.name` | string | The name of the single function that this runtime instance executes. [6] | `my-function`; `myazurefunctionapp/some-function-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `faas.version` | string | The immutable version of the function being executed. [7] | `26`; `pinkfroid-00002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** * **AWS Lambda:** Use the (full) log stream name. + + + +# Faas + +## Faas Attributes + +FaaS attributes + +| Attribute | Type | Description | Examples | Stability | +| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------- | +| `faas.coldstart` | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.cron` | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.collection` | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.name` | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.operation` | string | Describes the type of the operation that was performed on the data. | `insert`; `edit`; `delete` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.document.time` | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.instance` | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [1] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invocation_id` | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_name` | string | The name of the invoked function. [2] | `my-function` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_provider` | string | The cloud provider of the invoked function. [3] | `alibaba_cloud`; `aws`; `azure` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.invoked_region` | string | The cloud region of the invoked function. [4] | `eu-central-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.max_memory` | int | The amount of memory available to the serverless function converted to Bytes. [5] | `134217728` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.name` | string | The name of the single function that this runtime instance executes. [6] | `my-function`; `myazurefunctionapp/some-function-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.time` | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.trigger` | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `faas.version` | string | The immutable version of the function being executed. [7] | `26`; `pinkfroid-00002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** \* **AWS Lambda:** Use the (full) log stream name. **[2]:** SHOULD be equal to the `faas.name` resource attribute of the invoked function. @@ -46,7 +49,7 @@ For some cloud providers, the above definition is ambiguous. The following definition of function name MUST be used for this attribute (and consequently the span name) for the listed cloud providers/products: -* **Azure:** The full name `/`, i.e., function app name +- **Azure:** The full name `/`, i.e., function app name followed by a forward slash followed by the function name (this form can also be seen in the resource JSON for the function). This means that a span attribute MUST be used, as an Azure function @@ -55,39 +58,38 @@ definition of function name MUST be used for this attribute **[7]:** Depending on the cloud provider and platform, use: -* **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) +- **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) (an integer represented as a decimal string). -* **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) +- **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) (i.e., the function name plus the revision suffix). -* **Google Cloud Functions:** The value of the +- **Google Cloud Functions:** The value of the [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). -* **Azure Functions:** Not applicable. Do not set this attribute. +- **Azure Functions:** Not applicable. Do not set this attribute. `faas.document.operation` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| -------- | ----------------------------- | ---------------------------------------------------------------- | | `insert` | When a new object is created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `edit` | When an object is modified. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `delete` | When an object is deleted. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edit` | When an object is modified. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | When an object is deleted. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.invoked_provider` 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 | Stability | -|---|---|---| -| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| --------------- | --------------------- | ---------------------------------------------------------------- | +| `alibaba_cloud` | Alibaba Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws` | Amazon Web Services | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `azure` | Microsoft Azure | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp` | Google Cloud Platform | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tencent_cloud` | Tencent Cloud | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| ------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | | `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/feature-flag.md b/docs/attributes-registry/feature-flag.md index cad407b363..e752cc6172 100644 --- a/docs/attributes-registry/feature-flag.md +++ b/docs/attributes-registry/feature-flag.md @@ -1,12 +1,20 @@ + + + + + # Feature Flag ## Feature Flag Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +This document defines attributes for Feature Flags. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------- | +| `feature_flag.key` | string | The unique identifier of the feature flag. | `logo-color` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `feature_flag.provider_name` | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `feature_flag.variant` | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can @@ -16,4 +24,3 @@ For example, the variant `red` maybe be used for the value `#c05543`. A stringified version of the value can be used in situations where a semantic identifier is unavailable. String representation of the value should be determined by the implementer. - diff --git a/docs/attributes-registry/file.md b/docs/attributes-registry/file.md index d2d83591ca..eb9a4140dc 100644 --- a/docs/attributes-registry/file.md +++ b/docs/attributes-registry/file.md @@ -1,18 +1,21 @@ + + + # File ## File Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `file.directory` | string | Directory where the file is located. It should include the drive letter, when appropriate. | `/home/user`; `C:\Program Files\MyApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `file.extension` | string | File extension, excluding the leading dot. [1] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `file.name` | string | Name of the file including the extension, without the directory. | `example.png` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `file.path` | string | Full path to the file, including the file name. It should include the drive letter, when appropriate. | `/home/alice/example.png`; `C:\Program Files\MyApp\myapp.exe` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `file.size` | int | File size in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Describes file attributes. + +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------- | +| `file.directory` | string | Directory where the file is located. It should include the drive letter, when appropriate. | `/home/user`; `C:\Program Files\MyApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.extension` | string | File extension, excluding the leading dot. [1] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.name` | string | Name of the file including the extension, without the directory. | `example.png` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.path` | string | Full path to the file, including the file name. It should include the drive letter, when appropriate. | `/home/alice/example.png`; `C:\Program Files\MyApp\myapp.exe` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.size` | int | File size in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). - diff --git a/docs/attributes-registry/gcp.md b/docs/attributes-registry/gcp.md index ea0a4a200e..66bb310a3d 100644 --- a/docs/attributes-registry/gcp.md +++ b/docs/attributes-registry/gcp.md @@ -1,24 +1,28 @@ -# Google Cloud Platform - - - -- [Google Compute Engine Attributes](#google-compute-engine-attributes) -- [Google Cloud Run Attributes](#google-cloud-run-attributes) - - - -## Google Compute Engine Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Google Cloud Run Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + + + + + +# GCP + +- [Gcp Cloud Run](#gcp-cloud-run-attributes) +- [Gcp Gce](#gcp-gce-attributes) + +## Gcp Cloud Run Attributes + +This document defines attributes for Google Cloud Run. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | ---------------------------------------------------------------- | +| `gcp.cloud_run.job.execution` | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.cloud_run.job.task_index` | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Gcp Gce Attributes + +This document defines attributes for Google Compute Engine (GCE). + +| Attribute | Type | Description | Examples | Stability | +| --------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `gcp.gce.instance.hostname` | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp.gce.instance.name` | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/gen-ai.md b/docs/attributes-registry/gen-ai.md new file mode 100644 index 0000000000..e5853b5363 --- /dev/null +++ b/docs/attributes-registry/gen-ai.md @@ -0,0 +1,35 @@ + + + + + +# Gen AI + +## Gen Ai Attributes + +This document defines the attributes used to describe telemetry in the context of LLM (Large Language Models) requests and responses. + +| Attribute | Type | Description | Examples | Stability | +| -------------------------------- | -------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `gen_ai.completion` | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.prompt` | string | The full prompt sent to an LLM. [2] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.max_tokens` | int | The maximum number of tokens the LLM generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.model` | string | The name of the LLM a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.temperature` | double | The temperature setting for the LLM request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.top_p` | double | The top_p sampling setting for the LLM request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `stop` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.model` | string | The name of the LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.system` | string | The name of the LLM foundation model vendor. | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) +**[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) + +`gen_ai.system` 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 | Stability | +| -------- | ----------- | ---------------------------------------------------------------- | +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/graphql.md b/docs/attributes-registry/graphql.md index 4beae15f1d..5561a1b31a 100644 --- a/docs/attributes-registry/graphql.md +++ b/docs/attributes-registry/graphql.md @@ -1,24 +1,27 @@ + + + # GraphQL -## GraphQL Attributes +## Graphql Attributes + +This document defines attributes for GraphQL. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | ------ | ----------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------- | +| `graphql.document` | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.name` | string | The name of the operation being executed. | `findBookById` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `graphql.operation.type` | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value may be sanitized to exclude sensitive information. -`graphql.operation.type` MUST be one of the following: +`graphql.operation.type` 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 | Stability | -|---|---|---| -| `query` | GraphQL query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `mutation` | GraphQL mutation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| -------------- | -------------------- | ---------------------------------------------------------------- | +| `query` | GraphQL query | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mutation` | GraphQL mutation | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `subscription` | GraphQL subscription | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file diff --git a/docs/attributes-registry/heroku.md b/docs/attributes-registry/heroku.md index b84139462e..e8773409c3 100644 --- a/docs/attributes-registry/heroku.md +++ b/docs/attributes-registry/heroku.md @@ -1,14 +1,17 @@ + + + # Heroku ## Heroku Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +This document defines attributes for the Android platform on which the Android application is running. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------- | ------ | ------------------------------------- | --------------------------------------- | ---------------------------------------------------------------- | +| `heroku.app.id` | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.commit` | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `heroku.release.creation_timestamp` | string | Time and date the release was created | `2022-10-23T18:00:42Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/host.md b/docs/attributes-registry/host.md index dc571c70cd..3f51db07dc 100644 --- a/docs/attributes-registry/host.md +++ b/docs/attributes-registry/host.md @@ -1,28 +1,32 @@ + + + # Host ## Host Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `host.arch` | string | The CPU architecture the host system is running on. | `amd64` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.stepping` | string | Stepping or core revisions. | `1`; `r1p1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [2] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [3] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +A host is defined as a computing instance. For example, physical servers, virtual machines, switches or disk array. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------- | +| `host.arch` | string | The CPU architecture the host system is running on. | `amd64`; `arm32`; `arm64` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.cache.l2.size` | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.family` | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.model.id` | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.model.name` | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.stepping` | string | Stepping or core revisions. | `1`; `r1p1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.cpu.vendor.id` | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.id` | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.id` | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.name` | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.image.version` | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.ip` | string[] | Available IP addresses of the host, excluding loopback interfaces. [2] | `192.168.1.140`; `fe80::abc2:4a28:737a:609e` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.mac` | string[] | Available MAC addresses of the host, excluding loopback interfaces. [3] | `AC-DE-48-23-45-67`; `AC-DE-48-23-45-67-01-9F` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.name` | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `host.type` | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. @@ -32,14 +36,13 @@ `host.arch` 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 | Stability | -|---|---|---| -| `amd64` | AMD64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `arm32` | ARM32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `arm64` | ARM64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ia64` | Itanium | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ppc32` | 32-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ppc64` | 64-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------- | ------------------ | ---------------------------------------------------------------- | +| `amd64` | AMD64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm32` | ARM32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `arm64` | ARM64 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ia64` | Itanium | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc32` | 32-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ppc64` | 64-bit PowerPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `s390x` | IBM z/Architecture | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `x86` | 32-bit x86 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| `x86` | 32-bit x86 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/http.md b/docs/attributes-registry/http.md index c3d92a7b33..5877bc0421 100644 --- a/docs/attributes-registry/http.md +++ b/docs/attributes-registry/http.md @@ -1,32 +1,32 @@ -# HTTP + + - +# HTTP -- [HTTP Attributes](#http-attributes) -- [Deprecated HTTP Attributes](#deprecated-http-attributes) +- [Http](#http-attributes) +- [Http Deprecated](#http-deprecated-attributes) - +## Http Attributes -## HTTP Attributes +This document defines semantic convention attributes in the HTTP namespace. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http.request.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.request.size` | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http.response.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.response.size` | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `http.connection.state` | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.request.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.request.header.` | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [1] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.method` | string | HTTP request method. [2] | `CONNECT`; `DELETE`; `GET` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.resend_count` | int | The ordinal number of request resending attempt (for any reason, including redirects). [3] | `3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.request.size` | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.body.size` | 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` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.header.` | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [4] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.response.size` | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `http.route` | string | The matched route, that is, the path template in the format used by the respective server framework. [5] | `/users/:userID?`; `{controller}/{action}/{id?}` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. The `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. @@ -58,50 +58,49 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin `http.connection.state` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| -------- | ------------- | ---------------------------------------------------------------- | | `active` | active state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `idle` | idle state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | idle state. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `http.request.method` 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 | Stability | -|---|---|---| -| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - - -## Deprecated HTTP Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | -| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.method`. | -| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.header.content-length`. | -| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.header.content-length`. | -| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.scheme` instead. | -| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.status_code`. | -| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `url.path` and `url.query. | -| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.full`. | -| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `user_agent.original`. | +| Value | Description | Stability | +| --------- | ------------------------------------------------------------------- | ---------------------------------------------------------- | +| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +## Http Deprecated Attributes + +Describes deprecated HTTP attributes. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | ------ | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `http.flavor` | string | Deprecated, use `network.protocol.name` instead. | `1.0`; `1.1`; `2.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | +| `http.method` | string | Deprecated, use `http.request.method` instead. | `GET`; `POST`; `HEAD` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.method`. | +| `http.request_content_length` | int | Deprecated, use `http.request.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.request.header.content-length`. | +| `http.response_content_length` | int | Deprecated, use `http.response.header.content-length` instead. | `3495` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.header.content-length`. | +| `http.scheme` | string | Deprecated, use `url.scheme` instead. | `http`; `https` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.scheme` instead. | +| `http.status_code` | int | Deprecated, use `http.response.status_code` instead. | `200` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `http.response.status_code`. | +| `http.target` | string | Deprecated, use `url.path` and `url.query` instead. | `/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `url.path` and `url.query. | +| `http.url` | string | Deprecated, use `url.full` instead. | `https://www.foo.bar/search?q=OpenTelemetry#SemConv` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `url.full`. | +| `http.user_agent` | string | Deprecated, use `user_agent.original` instead. | `CERN-LineMode/2.15 libwww/2.17b3`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `user_agent.original`. | `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 | Stability | -|---|---|---| -| `1.0` | HTTP/1.0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `1.1` | HTTP/1.1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `2.0` | HTTP/2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `3.0` | HTTP/3 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------ | -------------- | ---------------------------------------------------------------- | +| `1.0` | HTTP/1.0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `1.1` | HTTP/1.1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `2.0` | HTTP/2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `3.0` | HTTP/3 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `SPDY` | SPDY protocol. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `QUIC` | QUIC protocol. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/ios.md b/docs/attributes-registry/ios.md index b867deac8e..11e2b8e1a9 100644 --- a/docs/attributes-registry/ios.md +++ b/docs/attributes-registry/ios.md @@ -1,30 +1,27 @@ -# iOS - - + + -- [Deprecated iOS Attributes](#deprecated-ios-attributes) +# iOS - +## Ios Deprecated Attributes -## Deprecated iOS Attributes +The iOS platform on which the iOS application is running. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `ios.state` | string | Deprecated use the `device.app.lifecycle` event definition including `ios.state` as a payload field instead. [1] | `active` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Moved to a payload field of `device.app.lifecycle`. | +| Attribute | Type | Description | Examples | Stability | +| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| `ios.state` | string | Deprecated use the `device.app.lifecycle` event definition including `ios.state` as a payload field instead. [1] | `active`; `inactive`; `background` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Moved to a payload field of `device.app.lifecycle`. | **[1]:** The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived. `ios.state` 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 | Stability | -|---|---|---| -| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------ | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `active` | The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inactive` | The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `background` | The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `foreground` | The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| `terminate` | The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/jvm.md b/docs/attributes-registry/jvm.md index 57dce510c2..9e438896bb 100644 --- a/docs/attributes-registry/jvm.md +++ b/docs/attributes-registry/jvm.md @@ -1,44 +1,44 @@ -# JVM + - + + -- [JVM Attributes](#jvm-attributes) +# JVM - +## Jvm Attributes -## JVM Attributes +This document defines Java Virtual machine related attributes. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.pool.name` | string | Name of the memory pool. [3] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `jvm.thread.state` | string | State of the thread. | `runnable`; `blocked` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------- | ----------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------- | +| `jvm.gc.action` | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.gc.name` | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.pool.name` | string | Name of the memory pool. [3] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.memory.type` | string | The type of memory. | `heap`; `non_heap` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.thread.daemon` | boolean | Whether the thread is daemon or not. | | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `jvm.thread.state` | string | State of the thread. | `new`; `runnable`; `blocked` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). +**[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](). -**[2]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). +**[2]:** Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](). -**[3]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). +**[3]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | -|---|---|---| -| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| ---------- | --------------- | ---------------------------------------------------------- | +| `heap` | Heap memory. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `non_heap` | Non-heap memory | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`jvm.thread.state` MUST be one of the following: +`jvm.thread.state` 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 | Stability | -|---|---|---| -| `new` | A thread that has not yet started is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `runnable` | A thread executing in the Java virtual machine is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| --------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| `new` | A thread that has not yet started is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `runnable` | A thread executing in the Java virtual machine is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `blocked` | A thread that is blocked waiting for a monitor lock is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `waiting` | A thread that is waiting indefinitely for another thread to perform a particular action is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `timed_waiting` | A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `terminated` | A thread that has exited is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - +| `terminated` | A thread that has exited is in this state. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/k8s.md b/docs/attributes-registry/k8s.md index daf25dfb25..b9bc225333 100644 --- a/docs/attributes-registry/k8s.md +++ b/docs/attributes-registry/k8s.md @@ -1,41 +1,44 @@ -# Kubernetes + - + + -- [Kubernetes Attributes](#kubernetes-attributes) -- [Deprecated Kubernetes Attributes](#deprecated-kubernetes-attributes) +# K8s - +- [K8s](#k8s-attributes) +- [K8s Deprecated](#k8s-deprecated-attributes) -## Kubernetes Attributes +## K8s Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.container.status.last_terminated_reason` | string | Last terminated reason of the Container. | `Evicted`; `Error` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.node.name` | string | The name of the Node. | `node-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.pod.label.` | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Kubernetes resource attributes. + +| Attribute | Type | Description | Examples | Stability | +| --------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `k8s.cluster.name` | string | The name of the cluster. | `opentelemetry-cluster` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cluster.uid` | string | A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.name` | string | The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). | `redis` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.restart_count` | int | Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.container.status.last_terminated_reason` | string | Last terminated reason of the Container. | `Evicted`; `Error` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cronjob.name` | string | The name of the CronJob. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.cronjob.uid` | string | The UID of the CronJob. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.daemonset.name` | string | The name of the DaemonSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.daemonset.uid` | string | The UID of the DaemonSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.deployment.name` | string | The name of the Deployment. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.deployment.uid` | string | The UID of the Deployment. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.job.name` | string | The name of the Job. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.job.uid` | string | The UID of the Job. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.namespace.name` | string | The name of the namespace that the pod is running in. | `default` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.node.name` | string | The name of the Node. | `node-1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.node.uid` | string | The UID of the Node. | `1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.annotation.` | string | The annotation key-value pairs placed on the Pod, the `` being the annotation name, the value being the annotation value. | `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets=true`; `k8s.pod.annotation.mycompany.io/arch=x64`; `k8s.pod.annotation.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.label.` | string | The label key-value pairs placed on the Pod, the `` being the label name, the value being the label value. | `k8s.pod.label.app=my-app`; `k8s.pod.label.mycompany.io/arch=x64`; `k8s.pod.label.data=` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.name` | string | The name of the Pod. | `opentelemetry-pod-autoconf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.pod.uid` | string | The UID of the Pod. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.replicaset.name` | string | The name of the ReplicaSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.replicaset.uid` | string | The UID of the ReplicaSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.statefulset.name` | string | The name of the StatefulSet. | `opentelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `k8s.statefulset.uid` | string | The UID of the StatefulSet. | `275ecb36-5aa8-4c2a-9c47-d8bb681b9aff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the `k8s.cluster.uid` through the @@ -53,18 +56,17 @@ UUIDs as standardized by Which states: > If generated according to one of the mechanisms defined in Rec. - ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be - different from all other UUIDs generated before 3603 A.D., or is - extremely likely to be different (depending on the mechanism chosen). +> ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be +> different from all other UUIDs generated before 3603 A.D., or is +> extremely likely to be different (depending on the mechanism chosen). Therefore, UIDs between clusters should be extremely unlikely to conflict. - -## Deprecated Kubernetes Attributes +## K8s Deprecated Attributes + +Describes deprecated k8s attributes. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | ---------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------- | | `k8s.pod.labels.` | string | Deprecated, use `k8s.pod.label` instead. | `k8s.pod.label.app=my-app` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `k8s.pod.label`. | - \ No newline at end of file diff --git a/docs/attributes-registry/llm.md b/docs/attributes-registry/llm.md deleted file mode 100644 index 9a20ed6199..0000000000 --- a/docs/attributes-registry/llm.md +++ /dev/null @@ -1,59 +0,0 @@ - - -# Large Language Model - - - -- [Generic LLM Attributes](#generic-llm-attributes) - - [Request Attributes](#request-attributes) - - [Response Attributes](#response-attributes) - - [Event Attributes](#event-attributes) - - - -## Generic LLM Attributes - -### Request Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gen_ai.request.max_tokens` | int | The maximum number of tokens the LLM generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.model` | string | The name of the LLM a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.temperature` | double | The temperature setting for the LLM request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.top_p` | double | The top_p sampling setting for the LLM request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.system` | string | The name of the LLM foundation model vendor. | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`gen_ai.system` 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 | Stability | -|---|---|---| -| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -### Response Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `[stop]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.response.model` | string | The name of the LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -### Event Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `gen_ai.completion` | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.prompt` | string | The full prompt sent to an LLM. [2] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - -**[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - \ No newline at end of file diff --git a/docs/attributes-registry/log.md b/docs/attributes-registry/log.md index 89c5145c1b..e829babffd 100644 --- a/docs/attributes-registry/log.md +++ b/docs/attributes-registry/log.md @@ -1,52 +1,48 @@ -# Log - - + + -- [Log Attributes](#log-attributes) - - [Generic log attributes](#generic-log-attributes) - - [File log attributes](#file-log-attributes) - - [Record log attributes](#record-log-attributes) +# Log - +- [Log](#log-attributes) +- [Log File](#log-file-attributes) +- [Log Record](#log-record-attributes) ## Log Attributes -### Generic log attributes +This document defines log attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| -------------- | ------ | ------------------------------------------------------------------------------ | ------------------ | ---------------------------------------------------------------- | +| `log.iostream` | string | The stream associated with the log. See below for a list of well-known values. | `stdout`; `stderr` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `log.iostream` 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 | Stability | -|---|---|---| -| `stdout` | Logs from stdout stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| -------- | ------------------------- | ---------------------------------------------------------------- | +| `stdout` | Logs from stdout stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `stderr` | Events from stderr stream | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -### File log attributes +## Log File Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `log.file.name` | string | The basename of the file. | `audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Attributes for a file to which log was emitted. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------ | ------ | -------------------------------------------------- | -------------------------- | ---------------------------------------------------------------- | +| `log.file.name` | string | The basename of the file. | `audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.name_resolved` | string | The basename of the file, with symlinks resolved. | `uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `log.file.path` | string | The full path to the file. | `/var/log/mysql/audit.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `log.file.path_resolved` | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -### Record log attributes +## Log Record Attributes + +This document defines the generic attributes that may be used in any Log Record. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | ------------------------------------------- | ---------------------------- | ---------------------------------------------------------------- | | `log.record.uid` | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. - \ No newline at end of file diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 25bad90a56..0ff400f546 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -1,42 +1,42 @@ + + + # Messaging - - -- [Generic Messaging Attributes](#generic-messaging-attributes) -- [GCP Pub/Sub Attributes](#gcp-pubsub-attributes) -- [Kafka Attributes](#kafka-attributes) -- [RabbitMQ Attributes](#rabbitmq-attributes) -- [RocketMQ Attributes](#rocketmq-attributes) -- [Azure Event Hubs Attributes](#azure-event-hubs-attributes) -- [Azure Service Bus Attributes](#azure-service-bus-attributes) -- [Deprecated Messaging Attributes](#deprecated-messaging-attributes) - - - -## Generic Messaging Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.message.body.size` | int | The size of the message body in bytes. [5] | `1439` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.operation.name` | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.operation.type` | string | A string identifying the type of the messaging operation. [7] | `publish` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +- [Messaging](#messaging-attributes) +- [Messaging Deprecated](#messaging-deprecated-attributes) +- [Messaging Eventhubs](#messaging-eventhubs-attributes) +- [Messaging Gcp Pubsub](#messaging-gcp-pubsub-attributes) +- [Messaging Kafka](#messaging-kafka-attributes) +- [Messaging Rabbitmq](#messaging-rabbitmq-attributes) +- [Messaging Rocketmq](#messaging-rocketmq-attributes) +- [Messaging Servicebus](#messaging-servicebus-attributes) + +## Messaging Attributes + +Attributes describing telemetry around messaging systems and messaging activities. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | ---------------------------------------------------------------- | +| `messaging.batch.message_count` | int | The number of messages sent, received, or processed in the scope of the batching operation. [1] | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.client_id` | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.anonymous` | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.name` | string | The message destination name [2] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.partition.id` | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.template` | string | Low cardinality representation of the messaging destination name [3] | `/customers/{customerId}` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination.temporary` | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination_publish.anonymous` | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.destination_publish.name` | string | The name of the original destination the message was published to [4] | `MyQueue`; `MyTopic` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.body.size` | int | The size of the message body in bytes. [5] | `1439` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.conversation_id` | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.envelope.size` | int | The size of the message body and metadata in bytes. [6] | `2738` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.message.id` | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.operation.name` | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.operation.type` | string | A string identifying the type of the messaging operation. [7] | `publish`; `create`; `receive` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.system` | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. @@ -58,129 +58,128 @@ size should be used. `messaging.operation.type` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.system` 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 | Stability | -|---|---|---| -| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## GCP Pub/Sub Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.gcp_pubsub.message.ack_deadline` | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.gcp_pubsub.message.ack_id` | string | The ack id for a given message. | `ack_id` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.gcp_pubsub.message.delivery_attempt` | int | The delivery attempt for a given message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Kafka Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [1] | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. - - -## RabbitMQ Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rabbitmq.message.delivery_tag` | int | RabbitMQ message delivery tag | `123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## RocketMQ Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.message.type` | string | Type of message. | `normal` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`messaging.rocketmq.consumption_model` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `clustering` | Clustering consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------ | --------------------------------- | ---------------------------------------------------------------- | +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Messaging Deprecated Attributes + +Describes deprecated messaging attributes. + +| Attribute | Type | Description | Examples | Stability | +| --------------------------------------- | ------ | ------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | +| `messaging.kafka.destination.partition` | int | Deprecated, use `messaging.destination.partition.id` instead. | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | +| `messaging.operation` | string | Deprecated, use `messaging.operation.type` instead. | `publish`; `create`; `process` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.operation.type`. | + +## Messaging Eventhubs Attributes + +This group describes attributes specific to Azure Event Hubs. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------------------- | ------ | -------------------------------------------------------------------------------------- | ------------ | ---------------------------------------------------------------- | +| `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Messaging Gcp Pubsub Attributes + +This group describes attributes specific to GCP Pub/Sub. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------- | +| `messaging.gcp_pubsub.message.ack_deadline` | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.ack_id` | string | The ack id for a given message. | `ack_id` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.delivery_attempt` | int | The delivery attempt for a given message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.gcp_pubsub.message.ordering_key` | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Messaging Kafka Attributes + +This group describes attributes specific to Apache Kafka. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | ---------------------------------------------------------------- | +| `messaging.kafka.consumer.group` | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.key` | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [8] | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.offset` | int | The offset of a record in the corresponding Kafka partition. | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.kafka.message.tombstone` | boolean | A boolean that is true if the message is a tombstone. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[8]:** If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. + +## Messaging Rabbitmq Attributes + +This group describes attributes specific to RabbitMQ. + +| Attribute | Type | Description | Examples | Stability | +| -------------------------------------------- | ------ | ----------------------------- | -------- | ---------------------------------------------------------------- | +| `messaging.rabbitmq.destination.routing_key` | string | RabbitMQ message routing key. | `myKey` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rabbitmq.message.delivery_tag` | int | RabbitMQ message delivery tag | `123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Messaging Rocketmq Attributes + +This group describes attributes specific to RocketMQ. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | ---------------------------------------------------------------- | +| `messaging.rocketmq.client_group` | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.consumption_model` | string | Model of message consumption. This only applies to consumer spans. | `clustering`; `broadcasting` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.delay_time_level` | int | The delay time level for delay message, which determines the message delay time. | `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.delivery_timestamp` | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.group` | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.keys` | string[] | Key(s) of message, another way to mark message besides message id. | `keyA`; `keyB` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.tag` | string | The secondary classifier of message besides topic. | `tagA` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.message.type` | string | Type of message. | `normal`; `fifo`; `delay` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.rocketmq.namespace` | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.rocketmq.consumption_model` 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 | Stability | +| -------------- | ------------------------------ | ---------------------------------------------------------------- | +| `clustering` | Clustering consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `broadcasting` | Broadcasting consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`messaging.rocketmq.message.type` MUST be one of the following: +`messaging.rocketmq.message.type` 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 | Stability | -|---|---|---| -| `normal` | Normal message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `fifo` | FIFO message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `delay` | Delay message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------- | ------------------- | ---------------------------------------------------------------- | +| `normal` | Normal message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fifo` | FIFO message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delay` | Delay message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `transaction` | Transaction message | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -## Azure Event Hubs Attributes +## Messaging Servicebus Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.eventhubs.consumer.group` | string | The name of the consumer group the event consumer is associated with. | `indexer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.eventhubs.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +This group describes attributes specific to Azure Service Bus. -## Azure Service Bus Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.servicebus.disposition_status` | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| ---------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ---------------------------------------------------------------- | +| `messaging.servicebus.destination.subscription_name` | string | The name of the subscription in the topic messages are received from. | `mySubscription` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.disposition_status` | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete`; `abandon`; `dead_letter` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.message.delivery_count` | int | Number of deliveries that have been attempted for this message. | `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `messaging.servicebus.message.enqueued_time` | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `messaging.servicebus.disposition_status` 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 | Stability | -|---|---|---| -| `complete` | Message is completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `abandon` | Message is abandoned | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------- | ------------------------------------ | ---------------------------------------------------------------- | +| `complete` | Message is completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `abandon` | Message is abandoned | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `dead_letter` | Message is sent to dead letter queue | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `defer` | Message is deferred | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Deprecated Messaging Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `messaging.kafka.destination.partition` | int | Deprecated, use `messaging.destination.partition.id` instead. | `2` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.partition.id`. | -| `messaging.operation` | string | Deprecated, use `messaging.operation.type` instead. | `publish`; `create`; `process` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.operation.type`. | - \ No newline at end of file +| `defer` | Message is deferred | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/network.md b/docs/attributes-registry/network.md index 48dabc6512..9d038e5e0a 100644 --- a/docs/attributes-registry/network.md +++ b/docs/attributes-registry/network.md @@ -1,40 +1,37 @@ -# Network - -These attributes may be used for any network related operation. - - + + -- [Network Attributes](#network-attributes) -- [Deprecated Network Attributes](#deprecated-network-attributes) +# Network - +- [Network](#network-attributes) +- [Network Deprecated](#network-deprecated-attributes) ## Network Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.connection.type` | string | The internet connection type. | `wifi` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.io.direction` | string | The network IO operation direction. | `transmit` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.local.port` | int | Local port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.peer.port` | int | Peer port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.protocol.version` | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +These attributes may be used for any network related operation. -**[1]:** The value SHOULD be normalized to lowercase. +| Attribute | Type | Description | Examples | Stability | +| ---------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------- | +| `network.carrier.icc` | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.mcc` | string | The mobile carrier country code. | `310` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.mnc` | string | The mobile carrier network code. | `001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.carrier.name` | string | The name of the mobile carrier. | `sprint` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.connection.subtype` | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `gprs`; `edge`; `umts` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.connection.type` | string | The internet connection type. | `wifi`; `wired`; `cell` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.io.direction` | string | The network IO operation direction. | `transmit`; `receive` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `network.local.address` | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.local.port` | int | Local port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.peer.address` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.peer.port` | int | Peer port number of the network connection. | `65123` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.protocol.name` | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.protocol.version` | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.transport` | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp`; `pipe` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `network.type` | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +**[1]:** The value SHOULD be normalized to lowercase. **[2]:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. **[3]:** The value SHOULD be normalized to lowercase. @@ -47,100 +44,97 @@ different processes could be listening on TCP port 12345 and UDP port 12345. `network.connection.subtype` 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 | Stability | -|---|---|---| -| `gprs` | GPRS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `edge` | EDGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `umts` | UMTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cdma` | CDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `evdo_0` | EVDO Rel. 0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `evdo_a` | EVDO Rev. A | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cdma2000_1xrtt` | CDMA2000 1XRTT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hsdpa` | HSDPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hsupa` | HSUPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hspa` | HSPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `iden` | IDEN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `evdo_b` | EVDO Rev. B | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `lte` | LTE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ehrpd` | EHRPD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hspap` | HSPAP | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gsm` | GSM | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `td_scdma` | TD-SCDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `iwlan` | IWLAN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `nr` | 5G NR (New Radio) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `lte_ca` | LTE CA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ---------------- | ----------------------------------- | ---------------------------------------------------------------- | +| `gprs` | GPRS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edge` | EDGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `umts` | UMTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma` | CDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_0` | EVDO Rel. 0 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_a` | EVDO Rev. A | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cdma2000_1xrtt` | CDMA2000 1XRTT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsdpa` | HSDPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsupa` | HSUPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspa` | HSPA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iden` | IDEN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `evdo_b` | EVDO Rev. B | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte` | LTE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ehrpd` | EHRPD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hspap` | HSPAP | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gsm` | GSM | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `td_scdma` | TD-SCDMA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iwlan` | IWLAN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nr` | 5G NR (New Radio) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nrnsa` | 5G NRNSA (New Radio Non-Standalone) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `lte_ca` | LTE CA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.connection.type` 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 | Stability | -|---|---|---| -| `wifi` | wifi | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `wired` | wired | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cell` | cell | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------------- | ----------- | ---------------------------------------------------------------- | +| `wifi` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `wired` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cell` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | -|---|---|---| -| `transmit` | transmit | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `receive` | receive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `transmit` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.transport` 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 | Stability | -|---|---|---| -| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| ------ | ------------------------ | ---------------------------------------------------------- | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `network.type` 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 | Stability | -|---|---|---| -| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - - -## Deprecated Network Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | -| `net.host.port` | int | Deprecated, use `server.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port`. | -| `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address` on client spans and `client.address` on server spans. | -| `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port` on client spans and `client.port` on server spans. | -| `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | -| `net.protocol.version` | string | Deprecated, use `network.protocol.version`. | `3.1.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.version`. | -| `net.sock.family` | string | Deprecated, use `network.transport` and `network.type`. | `inet` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `network.transport` and `network.type`. | -| `net.sock.host.addr` | string | Deprecated, use `network.local.address`. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.address`. | -| `net.sock.host.port` | int | Deprecated, use `network.local.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.port`. | -| `net.sock.peer.addr` | string | Deprecated, use `network.peer.address`. | `192.168.0.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.address`. | -| `net.sock.peer.name` | string | Deprecated, no replacement at this time. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | -| `net.sock.peer.port` | int | Deprecated, use `network.peer.port`. | `65531` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.port`. | -| `net.transport` | string | Deprecated, use `network.transport`. | `ip_tcp` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.transport`. | +| Value | Description | Stability | +| ------ | ----------- | ---------------------------------------------------------- | +| `ipv4` | IPv4 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ipv6` | IPv6 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +## Network Deprecated Attributes + +These attributes may be used for any network related operation. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | -------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `net.host.name` | string | Deprecated, use `server.address`. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address`. | +| `net.host.port` | int | Deprecated, use `server.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port`. | +| `net.peer.name` | string | Deprecated, use `server.address` on client spans and `client.address` on server spans. | `example.com` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.address` on client spans and `client.address` on server spans. | +| `net.peer.port` | int | Deprecated, use `server.port` on client spans and `client.port` on server spans. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `server.port` on client spans and `client.port` on server spans. | +| `net.protocol.name` | string | Deprecated, use `network.protocol.name`. | `amqp`; `http`; `mqtt` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.name`. | +| `net.protocol.version` | string | Deprecated, use `network.protocol.version`. | `3.1.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.protocol.version`. | +| `net.sock.family` | string | Deprecated, use `network.transport` and `network.type`. | `inet`; `inet6`; `unix` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Split to `network.transport` and `network.type`. | +| `net.sock.host.addr` | string | Deprecated, use `network.local.address`. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.address`. | +| `net.sock.host.port` | int | Deprecated, use `network.local.port`. | `8080` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.local.port`. | +| `net.sock.peer.addr` | string | Deprecated, use `network.peer.address`. | `192.168.0.1` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.address`. | +| `net.sock.peer.name` | string | Deprecated, no replacement at this time. | `/var/my.sock` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed. | +| `net.sock.peer.port` | int | Deprecated, use `network.peer.port`. | `65531` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.peer.port`. | +| `net.transport` | string | Deprecated, use `network.transport`. | `ip_tcp`; `ip_udp`; `pipe` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `network.transport`. | `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 | Stability | -|---|---|---| -| `inet` | IPv4 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `inet6` | IPv6 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unix` | Unix domain socket path | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| ------- | ----------------------- | ---------------------------------------------------------------- | +| `inet` | IPv4 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inet6` | IPv6 address | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unix` | Unix domain socket path | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `net.transport` 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 | Stability | -|---|---|---| -| `ip_tcp` | ip_tcp | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ip_udp` | ip_udp | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `pipe` | Named or anonymous pipe. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `inproc` | In-process communication. [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `other` | Something else (non IP-based). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** Signals that there is only in-process communication not using a "real" network protocol in cases where network attributes would normally be expected. Usually all other network attributes can be left out in that case. - +| Value | Description | Stability | +| -------- | ------------------------------ | ---------------------------------------------------------------- | +| `ip_tcp` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ip_udp` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pipe` | Named or anonymous pipe. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `inproc` | In-process communication. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | Something else (non IP-based). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/oci.md b/docs/attributes-registry/oci.md index 839aa4da9e..b5102b7e7e 100644 --- a/docs/attributes-registry/oci.md +++ b/docs/attributes-registry/oci.md @@ -1,14 +1,18 @@ -# Open Container Initiative (OCI) + -The [Open Container Initiative](https://opencontainers.org/) defines open industry standards around container formats and runtimes. + + -## OCI Image Manifest +# OCI - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Oci Manifest Attributes + +An OCI image manifest. + +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `oci.manifest.digest` | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [1] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). An example can be found in [Example Image Manifest](https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest). - \ No newline at end of file diff --git a/docs/attributes-registry/opentracing.md b/docs/attributes-registry/opentracing.md index 727271b544..83d11b4f4e 100644 --- a/docs/attributes-registry/opentracing.md +++ b/docs/attributes-registry/opentracing.md @@ -1,21 +1,24 @@ + + + # OpenTracing -## OpenTracing Attributes +## Opentracing Attributes + +Attributes used by the OpenTracing Shim layer. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | ------------------------------- | -------------------------- | ---------------------------------------------------------------- | +| `opentracing.ref_type` | string | Parent-child Reference type [1] | `child_of`; `follows_from` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The causal relationship between a child Span and a parent Span. `opentracing.ref_type` 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 | Stability | -|---|---|---| -| `child_of` | The parent Span depends on the child Span in some capacity | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| -------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `child_of` | The parent Span depends on the child Span in some capacity | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `follows_from` | The parent Span doesn't depend in any way on the result of the child Span | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/os.md b/docs/attributes-registry/os.md index aff35e76e8..a2ff3e6c4a 100644 --- a/docs/attributes-registry/os.md +++ b/docs/attributes-registry/os.md @@ -1,33 +1,35 @@ + + + # OS -## Operating System Attributes +## Os Attributes + +The operating system (OS) on which the process represented by this resource is running. - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- | +| `os.build_id` | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `os.description` | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `os.type` | string | The operating system type. | `windows` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.name` | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.type` | string | The operating system type. | `windows`; `linux`; `darwin` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `os.version` | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `os.type` 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 | Stability | -|---|---|---| -| `windows` | Microsoft Windows | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `linux` | Linux | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `darwin` | Apple Darwin | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `freebsd` | FreeBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `netbsd` | NetBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `openbsd` | OpenBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `dragonflybsd` | DragonFly BSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hpux` | HP-UX (Hewlett Packard Unix) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aix` | AIX (Advanced Interactive eXecutive) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `solaris` | SunOS, Oracle Solaris | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `z_os` | IBM z/OS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| Value | Description | Stability | +| -------------- | ------------------------------------ | ---------------------------------------------------------------- | +| `windows` | Microsoft Windows | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `linux` | Linux | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `darwin` | Apple Darwin | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `freebsd` | FreeBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netbsd` | NetBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `openbsd` | OpenBSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dragonflybsd` | DragonFly BSD | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hpux` | HP-UX (Hewlett Packard Unix) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aix` | AIX (Advanced Interactive eXecutive) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `solaris` | SunOS, Oracle Solaris | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `z_os` | IBM z/OS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/otel.md b/docs/attributes-registry/otel.md index a064129e90..7bb1afb800 100644 --- a/docs/attributes-registry/otel.md +++ b/docs/attributes-registry/otel.md @@ -1,46 +1,45 @@ -# OpenTelemetry + + - +# OTel -- [General Attributes](#general-attributes) -- [Scope Attributes](#scope-attributes) -- [Deprecated OpenTelemetry Attributes](#deprecated-opentelemetry-attributes) +- [Otel](#otel-attributes) +- [Otel Library Deprecated](#otel-library-deprecated-attributes) +- [Otel Scope](#otel-scope-attributes) - +## Otel Attributes -## General Attributes +Attributes reserved for OpenTelemetry - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | -------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------- | +| `otel.status_code` | string | Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. | `OK`; `ERROR` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `otel.status_description` | string | Description of the Status if it has a value, otherwise not set. | `resource not found` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `otel.status_code` 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 | Stability | -|---|---|---| -| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `ERROR` | The operation contains an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - - -## Scope Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - - -## Deprecated OpenTelemetry Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `otel.library.name` | string | None | `io.opentelemetry.contrib.mongodb` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.name` attribute. | -| `otel.library.version` | string | None | `1.0.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.version` attribute. | - \ No newline at end of file +| Value | Description | Stability | +| ------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| `OK` | The operation has been validated by an Application developer or Operator to have completed successfully. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ERROR` | The operation contains an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +## Otel Library Deprecated Attributes + +Describes deprecated otel.library attributes. + +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | ----------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------ | +| `otel.library.name` | string | | `io.opentelemetry.contrib.mongodb` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.name` attribute. | +| `otel.library.version` | string | | `1.0.0` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
use the `otel.scope.version` attribute. | + +## Otel Scope Attributes + +Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +| Attribute | Type | Description | Examples | Stability | +| -------------------- | ------ | ------------------------------------------------------------------------------------ | ---------------------------------- | ---------------------------------------------------------- | +| `otel.scope.name` | string | The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). | `io.opentelemetry.contrib.mongodb` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `otel.scope.version` | string | The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). | `1.0.0` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/peer.md b/docs/attributes-registry/peer.md index e83991a403..69dd589473 100644 --- a/docs/attributes-registry/peer.md +++ b/docs/attributes-registry/peer.md @@ -1,12 +1,15 @@ + + + # Peer ## Peer Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +Operations that access some remote service. + +| Attribute | Type | Description | Examples | Stability | +| -------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ---------------------------------------------------------------- | | `peer.service` | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file diff --git a/docs/attributes-registry/process.md b/docs/attributes-registry/process.md index 0d0e005b66..0c46dd2e78 100644 --- a/docs/attributes-registry/process.md +++ b/docs/attributes-registry/process.md @@ -1,37 +1,40 @@ + + + # Process ## Process Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.creation.time` | string | The date and time the process was created, in ISO 8601 format. | `2023-11-21T09:25:34.853Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.exit.code` | int | The exit code of the process. | `127` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.exit.time` | string | The date and time the process exited, in ISO 8601 format. | `2023-11-21T09:26:12.315Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.group_leader.pid` | int | The PID of the process's group leader. This is also the process group ID (PGID) of the process. | `23` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.interactive` | boolean | Whether the process is connected to an interactive shell. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.owner` | string | The username of the user that owns the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.pid` | int | Process identifier (PID). | `1234` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.real_user.id` | int | The real user ID (RUID) of the process. | `1000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.real_user.name` | string | The username of the real user of the process. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.saved_user.id` | int | The saved user ID (SUID) of the process. | `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.saved_user.name` | string | The username of the saved user. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.session_leader.pid` | int | The PID of the process's session leader. This is also the session ID (SID) of the process. | `14` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.user.id` | int | The effective user ID (EUID) of the process. | `1001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.user.name` | string | The username of the effective user of the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `process.vpid` | int | Virtual process identifier. [1] | `12` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +An operating system process. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------- | +| `process.command` | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.command_args` | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `cmd/otecol`; `--config=config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.command_line` | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.creation.time` | string | The date and time the process was created, in ISO 8601 format. | `2023-11-21T09:25:34.853Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.executable.name` | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.executable.path` | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.exit.code` | int | The exit code of the process. | `127` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.exit.time` | string | The date and time the process exited, in ISO 8601 format. | `2023-11-21T09:26:12.315Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.group_leader.pid` | int | The PID of the process's group leader. This is also the process group ID (PGID) of the process. | `23` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.interactive` | boolean | Whether the process is connected to an interactive shell. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.owner` | string | The username of the user that owns the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.parent_pid` | int | Parent Process identifier (PPID). | `111` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.pid` | int | Process identifier (PID). | `1234` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.real_user.id` | int | The real user ID (RUID) of the process. | `1000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.real_user.name` | string | The username of the real user of the process. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.description` | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.name` | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.runtime.version` | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.saved_user.id` | int | The saved user ID (SUID) of the process. | `1002` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.saved_user.name` | string | The username of the saved user. | `operator` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.session_leader.pid` | int | The PID of the process's session leader. This is also the session ID (SID) of the process. | `14` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.user.id` | int | The effective user ID (EUID) of the process. | `1001` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.user.name` | string | The username of the effective user of the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process.vpid` | int | Virtual process identifier. [1] | `12` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. - diff --git a/docs/attributes-registry/rpc.md b/docs/attributes-registry/rpc.md index f8d8e67844..feaddc5927 100644 --- a/docs/attributes-registry/rpc.md +++ b/docs/attributes-registry/rpc.md @@ -1,39 +1,37 @@ + + + # RPC - - -- [RPC Attributes](#rpc-attributes) -- [Deprecated RPC Attributes](#deprecated-rpc-attributes) - - - -## RPC Attributes - -RPC attributes are intended to be used in the context of events related to remote procedure calls (RPC). - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.message.compressed_size` | int | Compressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [5] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.message.type` | string | Whether this is a received or sent message. | `SENT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +- [Rpc](#rpc-attributes) +- [Rpc Deprecated](#rpc-deprecated-attributes) + +## Rpc Attributes + +This document defines attributes for remote procedure calls. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `rpc.connect_rpc.error_code` | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled`; `unknown`; `invalid_argument` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.connect_rpc.request.metadata.` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.connect_rpc.response.metadata.` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.request.metadata.` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.response.metadata.` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.grpc.status_code` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `2` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.error_code` | int | `error.code` property of response if it is an error response. | `-32700`; `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.error_message` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.request_id` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.jsonrpc.version` | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.compressed_size` | int | Compressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.id` | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [5] | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.type` | string | Whether this is a received or sent message. | `SENT`; `RECEIVED` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.message.uncompressed_size` | int | Uncompressed size of the message in bytes. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.method` | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.service` | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rpc.system` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. @@ -44,86 +42,84 @@ RPC attributes are intended to be used in the context of events related to remot **[4]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. **[5]:** This way we guarantee that the values will be consistent between different implementations. - **[6]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). **[7]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -`rpc.connect_rpc.error_code` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `cancelled` | cancelled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unknown` | unknown | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `invalid_argument` | invalid_argument | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `deadline_exceeded` | deadline_exceeded | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `not_found` | not_found | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `already_exists` | already_exists | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `permission_denied` | permission_denied | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `resource_exhausted` | resource_exhausted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `failed_precondition` | failed_precondition | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `aborted` | aborted | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `out_of_range` | out_of_range | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unimplemented` | unimplemented | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `internal` | internal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unavailable` | unavailable | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `data_loss` | data_loss | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `unauthenticated` | unauthenticated | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`rpc.grpc.status_code` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `0` | OK | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `1` | CANCELLED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `2` | UNKNOWN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `3` | INVALID_ARGUMENT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `4` | DEADLINE_EXCEEDED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `5` | NOT_FOUND | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `6` | ALREADY_EXISTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `7` | PERMISSION_DENIED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `8` | RESOURCE_EXHAUSTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `9` | FAILED_PRECONDITION | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `10` | ABORTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `11` | OUT_OF_RANGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `12` | UNIMPLEMENTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `13` | INTERNAL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `14` | UNAVAILABLE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `15` | DATA_LOSS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `16` | UNAUTHENTICATED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`rpc.message.type` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `SENT` | sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `RECEIVED` | received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +`rpc.connect_rpc.error_code` 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 | Stability | +| --------------------- | ----------- | ---------------------------------------------------------------- | +| `cancelled` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unknown` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `invalid_argument` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `deadline_exceeded` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `not_found` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `already_exists` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `permission_denied` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `resource_exhausted` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `failed_precondition` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aborted` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out_of_range` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unimplemented` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `internal` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unavailable` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `data_loss` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `unauthenticated` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`rpc.grpc.status_code` 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 | Stability | +| ----- | ------------------- | ---------------------------------------------------------------- | +| `0` | OK | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `1` | CANCELLED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `2` | UNKNOWN | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `3` | INVALID_ARGUMENT | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `4` | DEADLINE_EXCEEDED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `5` | NOT_FOUND | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `6` | ALREADY_EXISTS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `7` | PERMISSION_DENIED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `8` | RESOURCE_EXHAUSTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `9` | FAILED_PRECONDITION | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `10` | ABORTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `11` | OUT_OF_RANGE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `12` | UNIMPLEMENTED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `13` | INTERNAL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `14` | UNAVAILABLE | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `15` | DATA_LOSS | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `16` | UNAUTHENTICATED | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`rpc.message.type` 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 | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `SENT` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `RECEIVED` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `rpc.system` 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 | Stability | -|---|---|---| -| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| -------------- | ------------ | ---------------------------------------------------------------- | +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Deprecated RPC Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `message.compressed_size` | int | Deprecated, use `rpc.message.compressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.compressed_size`. | -| `message.id` | int | Deprecated, use `rpc.message.id` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.id`. | -| `message.type` | string | Deprecated, use `rpc.message.type` instead. | `SENT` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.type`. | -| `message.uncompressed_size` | int | Deprecated, use `rpc.message.uncompressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.uncompressed_size`. | - -`message.type` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `SENT` | sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `RECEIVED` | received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## Rpc Deprecated Attributes + +Deprecated rpc message attributes. + +| Attribute | Type | Description | Examples | Stability | +| --------------------------- | ------ | -------------------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------- | +| `message.compressed_size` | int | Deprecated, use `rpc.message.compressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.compressed_size`. | +| `message.id` | int | Deprecated, use `rpc.message.id` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.id`. | +| `message.type` | string | Deprecated, use `rpc.message.type` instead. | `SENT`; `RECEIVED` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.type`. | +| `message.uncompressed_size` | int | Deprecated, use `rpc.message.uncompressed_size` instead. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.uncompressed_size`. | + +`message.type` 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 | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `SENT` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `RECEIVED` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/server.md b/docs/attributes-registry/server.md index f455e8611e..d2994ae49a 100644 --- a/docs/attributes-registry/server.md +++ b/docs/attributes-registry/server.md @@ -1,23 +1,20 @@ -# Server Attributes + + -These attributes may be used to describe the server in a connection-based network interaction -where there is one side that initiates the connection (the client is the side that initiates the connection). -This covers all TCP network interactions since TCP is connection-based and one side initiates the -connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the -protocol / API does not expose a clear notion of client and server). -This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. +# Server - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Server Attributes + +These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------------------------------------------------------- | | `server.address` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `server.port` | int | Server port number. [2] | `80`; `8080`; `443` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. **[2]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. - \ No newline at end of file diff --git a/docs/attributes-registry/service.md b/docs/attributes-registry/service.md index ea291b8ac1..6cbaf663b7 100644 --- a/docs/attributes-registry/service.md +++ b/docs/attributes-registry/service.md @@ -1,17 +1,21 @@ + + + # Service ## Service Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `service.name` | string | Logical name of the service. [2] | `shoppingcart` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `service.namespace` | string | A namespace for `service.name`. [3] | `Shop` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +A service instance. + +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | -------------------------------------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------- | +| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.name` | string | Logical name of the service. [2] | `shoppingcart` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `service.namespace` | string | A namespace for `service.name`. [3] | `Shop` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to @@ -43,4 +47,3 @@ port. **[2]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. **[3]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. - diff --git a/docs/attributes-registry/session.md b/docs/attributes-registry/session.md index cd166d5a70..f17586ea09 100644 --- a/docs/attributes-registry/session.md +++ b/docs/attributes-registry/session.md @@ -1,13 +1,18 @@ + + + # Session ## Session Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Session is defined as the period of time encompassing all activities performed by the application and the actions executed by the end user. +Consequently, a Session is represented as a collection of Logs, Events, and Spans emitted by the Client Application throughout the Session's duration. Each Session is assigned a unique identifier, which is included as an attribute in the Logs, Events, and Spans generated during the Session's lifecycle. +When a session reaches end of life, typically due to user inactivity or session timeout, a new session identifier will be assigned. The previous session identifier may be provided by the instrumentation so that telemetry backends can link the two sessions. + +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | ---------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------- | +| `session.id` | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `session.previous_id` | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - diff --git a/docs/attributes-registry/signalr.md b/docs/attributes-registry/signalr.md index ba2e9e0b7a..3bd984e04c 100644 --- a/docs/attributes-registry/signalr.md +++ b/docs/attributes-registry/signalr.md @@ -1,32 +1,32 @@ -# ASP.NET Core + - + + -- [SignalR Attributes](#signalr-attributes) +# SignalR - +## Signalr Attributes -## SignalR Attributes +SignalR attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Attribute | Type | Description | Examples | Stability | +| --------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------- | +| `signalr.connection.status` | string | SignalR HTTP connection closure status. | `normal_closure`; `timeout`; `app_shutdown` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `server_sent_events`; `long_polling`; `web_sockets` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`signalr.connection.status` MUST be one of the following: +`signalr.connection.status` 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 | Stability | -|---|---|---| -| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| Value | Description | Stability | +| ---------------- | ----------------------------------------------------------- | ---------------------------------------------------------- | +| `normal_closure` | The connection was closed normally. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `timeout` | The connection was closed due to a timeout. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `app_shutdown` | The connection was closed because the app is shutting down. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `signalr.transport` 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 | Stability | -|---|---|---| +| Value | Description | Stability | +| -------------------- | ------------------------- | ---------------------------------------------------------- | | `server_sent_events` | ServerSentEvents protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - \ No newline at end of file +| `long_polling` | LongPolling protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `web_sockets` | WebSockets protocol | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/source.md b/docs/attributes-registry/source.md index d16285965f..abb52a5fdc 100644 --- a/docs/attributes-registry/source.md +++ b/docs/attributes-registry/source.md @@ -1,21 +1,18 @@ -# Source Attributes + + -These attributes may be used to describe the sender of a network exchange/packet. These should be used -when there is no client/server relationship between the two sides, or when that relationship is unknown. -This covers low-level network interactions (e.g. packet tracing) where you don't know if -there was a connection or which side initiated it. -This also covers unidirectional UDP flows and peer-to-peer communication where the -"user-facing" surface of the protocol / API does not expose a clear notion of client and server. +# Source - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +## Source Attributes + +These attributes may be used to describe the sender of a network exchange/packet. These should be used when there is no client/server relationship between the two sides, or when that relationship is unknown. This covers low-level network interactions (e.g. packet tracing) where you don't know if there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server. + +| Attribute | Type | Description | Examples | Stability | +| ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------- | | `source.address` | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `source.port` | int | Source port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `source.port` | int | Source port number | `3389`; `2888` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. - \ No newline at end of file diff --git a/docs/attributes-registry/system.md b/docs/attributes-registry/system.md index a836fce9a9..180d62d803 100644 --- a/docs/attributes-registry/system.md +++ b/docs/attributes-registry/system.md @@ -1,178 +1,183 @@ + + + + + # System - +- [System](#system-attributes) +- [System Cpu](#system-cpu-attributes) +- [System Deprecated](#system-deprecated-attributes) +- [System Filesystem](#system-filesystem-attributes) +- [System Memory](#system-memory-attributes) +- [System Network](#system-network-attributes) +- [System Paging](#system-paging-attributes) +- [System Process](#system-process-attributes) -- [CPU attributes](#cpu-attributes) -- [Memory attributes](#memory-attributes) -- [Paging attributes](#paging-attributes) -- [Filesystem attributes](#filesystem-attributes) -- [Network attributes](#network-attributes) -- [Process attributes](#process-attributes) -- [Deprecated System Attributes](#deprecated-system-attributes) +## System Attributes - +Describes System attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +| Attribute | Type | Description | Examples | Stability | +| --------------- | ------ | --------------------- | -------------- | ---------------------------------------------------------------- | | `system.device` | string | The device identifier | `(identifier)` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -## CPU attributes +## System Cpu Attributes + +Describes System CPU attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.cpu.state` | string | The state of the CPU | `idle`; `interrupt` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| --------------------------- | ------ | ------------------------------- | ------------------------ | ---------------------------------------------------------------- | +| `system.cpu.logical_number` | int | The logical CPU number [0..n-1] | `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.cpu.state` | string | The state of the CPU | `user`; `system`; `nice` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.cpu.state` 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 | Stability | -|---|---|---| -| `user` | user | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system` | system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `nice` | nice | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `iowait` | iowait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `interrupt` | interrupt | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `steal` | steal | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Value | Description | Stability | +| ----------- | ----------- | ---------------------------------------------------------------- | +| `user` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `nice` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `idle` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `iowait` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interrupt` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `steal` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## Memory attributes +## System Deprecated Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.memory.state` | string | The memory state | `free`; `cached` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Deprecated system attributes. -`system.memory.state` 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. +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | ------------------------------------------------ | -------------------------------- | --------------------------------------------------------------------------------------------------- | +| `system.processes.status` | string | Deprecated, use `system.process.status` instead. | `running`; `sleeping`; `stopped` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `system.process.status`. | + +`system.processes.status` 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 | Stability | -|---|---|---| -| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `shared` | shared | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, report shared memory usage with `metric.system.memory.shared` metric | -| `buffers` | buffers | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `cached` | cached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Value | Description | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `running` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sleeping` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stopped` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defunct` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -## Paging attributes +## System Filesystem Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.paging.direction` | string | The paging access direction | `in` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.paging.state` | string | The memory paging state | `free` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.paging.type` | string | The memory paging type | `minor` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Describes Filesystem attributes -`system.paging.direction` MUST be one of the following: +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | ------ | ------------------------- | -------------------------- | ---------------------------------------------------------------- | +| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.state` | string | The filesystem state | `used`; `free`; `reserved` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.filesystem.type` | string | The filesystem type | `fat32`; `exfat`; `ntfs` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Value | Description | Stability | -|---|---|---| -| `in` | in | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `out` | out | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +`system.filesystem.state` 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. -`system.paging.state` MUST be one of the following: +| Value | Description | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `used` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `reserved` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Value | Description | Stability | -|---|---|---| -| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +`system.filesystem.type` 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. -`system.paging.type` MUST be one of the following: +| Value | Description | Stability | +| --------- | ----------- | ---------------------------------------------------------------- | +| `fat32` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `exfat` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ntfs` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `refs` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hfsplus` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ext4` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Value | Description | Stability | -|---|---|---| -| `major` | major | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `minor` | minor | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +## System Memory Attributes -## Filesystem attributes +Describes System Memory attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.filesystem.mode` | string | The filesystem mode | `rw, ro` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.mountpoint` | string | The filesystem mount path | `/mnt/data` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.state` | string | The filesystem state | `used` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `system.filesystem.type` | string | The filesystem type | `ext4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | ---------------- | ------------------------ | ---------------------------------------------------------------- | +| `system.memory.state` | string | The memory state | `used`; `free`; `shared` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.state` MUST be one of the following: +`system.memory.state` 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 | Stability | -|---|---|---| -| `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `free` | free | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `reserved` | reserved | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| Value | Description | Stability | +| --------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `used` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `shared` | none | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, report shared memory usage with `metric.system.memory.shared` metric | +| `buffers` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cached` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.type` 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. +## System Network Attributes -| Value | Description | Stability | -|---|---|---| -| `fat32` | fat32 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `exfat` | exfat | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ntfs` | ntfs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `refs` | refs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `hfsplus` | hfsplus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `ext4` | ext4 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Network attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close_wait` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -`system.network.state` MUST be one of the following: - -| Value | Description | Stability | -|---|---|---| -| `close` | close | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `close_wait` | close_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `closing` | closing | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `delete` | delete | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `established` | established | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `fin_wait_1` | fin_wait_1 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `fin_wait_2` | fin_wait_2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `last_ack` | last_ack | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `listen` | listen | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `syn_recv` | syn_recv | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `syn_sent` | syn_sent | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `time_wait` | time_wait | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - -## Process attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +Describes Network attributes -`system.process.status` 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. +| Attribute | Type | Description | Examples | Stability | +| ---------------------- | ------ | ------------------------------------------------ | -------------------------------- | ---------------------------------------------------------------- | +| `system.network.state` | string | A stateless protocol MUST NOT set this attribute | `close`; `close_wait`; `closing` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| Value | Description | Stability | -|---|---|---| -| `running` | running | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `sleeping` | sleeping | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `stopped` | stopped | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `defunct` | defunct | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +`system.network.state` 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. -## Deprecated System Attributes +| Value | Description | Stability | +| ------------- | ----------- | ---------------------------------------------------------------- | +| `close` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `close_wait` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `closing` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `delete` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `established` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_1` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `fin_wait_2` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `last_ack` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `listen` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_recv` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `syn_sent` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `time_wait` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `system.processes.status` | string | Deprecated, use `system.process.status` instead. | `running` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `system.process.status`. | +## System Paging Attributes -`system.processes.status` 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. +Describes System Memory Paging attributes + +| Attribute | Type | Description | Examples | Stability | +| ------------------------- | ------ | --------------------------- | ---------------- | ---------------------------------------------------------------- | +| `system.paging.direction` | string | The paging access direction | `in`; `out` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.paging.state` | string | The memory paging state | `used`; `free` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `system.paging.type` | string | The memory paging type | `major`; `minor` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.direction` 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 | Stability | +| ----- | ----------- | ---------------------------------------------------------------- | +| `in` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `out` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.state` 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 | Stability | +| ------ | ----------- | ---------------------------------------------------------------- | +| `used` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `free` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.paging.type` 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 | Stability | +| ------- | ----------- | ---------------------------------------------------------------- | +| `major` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `minor` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +## System Process Attributes + +Describes System Process attributes + +| Attribute | Type | Description | Examples | Stability | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------- | +| `system.process.status` | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running`; `sleeping`; `stopped` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`system.process.status` 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 | Stability | -|---|---|---| -| `running` | running | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `sleeping` | sleeping | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `stopped` | stopped | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `defunct` | defunct | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| Value | Description | Stability | +| ---------- | ----------- | ---------------------------------------------------------------- | +| `running` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sleeping` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `stopped` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defunct` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/telemetry.md b/docs/attributes-registry/telemetry.md index 1df6c8d1ff..bb46108eb6 100644 --- a/docs/attributes-registry/telemetry.md +++ b/docs/attributes-registry/telemetry.md @@ -1,43 +1,46 @@ -# Telemetry SDK + + -## Telemetry SDK Attributes +# Telemetry - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [2] | `parts-unlimited-java` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## Telemetry Attributes -**[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. +This document defines attributes for telemetry SDK. + +| Attribute | Type | Description | Examples | Stability | +| -------------------------- | ------ | ------------------------------------------------------------------------------ | ------------------------- | ---------------------------------------------------------------- | +| `telemetry.distro.name` | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `telemetry.distro.version` | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `telemetry.sdk.language` | string | The language of the telemetry SDK. | `cpp`; `dotnet`; `erlang` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.name` | string | The name of the telemetry SDK as defined above. [2] | `opentelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `telemetry.sdk.version` | string | The version string of the telemetry SDK. | `1.2.3` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to +a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. + +**[2]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the `telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point or another suitable identifier depending on the language. The identifier `opentelemetry` is reserved and MUST NOT be used in this case. All custom identifiers SHOULD be stable across different versions of an implementation. -**[2]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to -a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. - `telemetry.sdk.language` 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 | Stability | -|---|---|---| -| `cpp` | cpp | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `dotnet` | dotnet | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `erlang` | erlang | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `go` | go | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `java` | java | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `nodejs` | nodejs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `php` | php | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `python` | python | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `ruby` | ruby | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `rust` | rust | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `swift` | swift | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `webjs` | webjs | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - +| Value | Description | Stability | +| -------- | ----------- | ---------------------------------------------------------- | +| `cpp` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `dotnet` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `erlang` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `go` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `java` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `nodejs` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `php` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `python` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `ruby` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `rust` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `swift` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `webjs` | none | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/attributes-registry/thread.md b/docs/attributes-registry/thread.md index 4e503b99c2..c09ca1d632 100644 --- a/docs/attributes-registry/thread.md +++ b/docs/attributes-registry/thread.md @@ -1,15 +1,16 @@ -# Thread + + -These attributes may be used for any operation to store information about a thread. +# Thread ## Thread Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `thread.name` | string | Current thread name. | `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +These attributes may be used for any operation to store information about a thread that started a span. + +| Attribute | Type | Description | Examples | Stability | +| ------------- | ------ | --------------------------------------------------------- | -------- | ---------------------------------------------------------------- | +| `thread.id` | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `thread.name` | string | Current thread name. | `main` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/tls.md b/docs/attributes-registry/tls.md index 081192af6b..32a4fb4506 100644 --- a/docs/attributes-registry/tls.md +++ b/docs/attributes-registry/tls.md @@ -1,49 +1,52 @@ + + + # TLS -## TLS Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `tls.cipher` | string | String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. [1] | `TLS_RSA_WITH_3DES_EDE_CBC_SHA`; `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.certificate` | string | PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.ja3` | string | A hash that identifies clients based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.not_after` | string | Date/Time indicating when client certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.not_before` | string | Date/Time indicating when client certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.server_name` | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.subject` | string | Distinguished name of subject of the x.509 certificate presented by the client. | `CN=myclient, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.client.supported_ciphers` | string[] | Array of ciphers offered by the client during the client hello. | `["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.curve` | string | String indicating the curve used for the given cipher, when applicable | `secp256r1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.established` | boolean | Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. | `True` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.next_protocol` | string | String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. | `http/1.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.protocol.name` | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.protocol.version` | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.resumed` | boolean | Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. | `True` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.certificate` | string | PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. | `[MII..., MI...]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.ja3s` | string | A hash that identifies servers based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.not_after` | string | Date/Time indicating when server certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.not_before` | string | Date/Time indicating when server certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls.server.subject` | string | Distinguished name of subject of the x.509 certificate presented by the server. | `CN=myserver, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## Tls Attributes + +This document defines semantic convention attributes in the TLS namespace. + +| Attribute | Type | Description | Examples | Stability | +| ------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `tls.cipher` | string | String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. [1] | `TLS_RSA_WITH_3DES_EDE_CBC_SHA`; `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.certificate` | string | PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. | `MII...`; `MI...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.ja3` | string | A hash that identifies clients based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.not_after` | string | Date/Time indicating when client certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.not_before` | string | Date/Time indicating when client certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.server_name` | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.subject` | string | Distinguished name of subject of the x.509 certificate presented by the client. | `CN=myclient, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.client.supported_ciphers` | string[] | Array of ciphers offered by the client during the client hello. | `"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "..."` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.curve` | string | String indicating the curve used for the given cipher, when applicable | `secp256r1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.established` | boolean | Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. | `true` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.next_protocol` | string | String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. | `http/1.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.protocol.name` | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl`; `tls` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.protocol.version` | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.resumed` | boolean | Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. | `true` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.certificate` | string | PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. | `MII...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.certificate_chain` | string[] | Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. | `MII...`; `MI...` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.md5` | string | Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.sha1` | string | Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `9E393D93138888D288266C2D915214D1D1CCEB2A` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.hash.sha256` | string | Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. | `0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.issuer` | string | Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. | `CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.ja3s` | string | A hash that identifies servers based on how they perform an SSL/TLS handshake. | `d4e5b18d6b55c71272893221c96ba240` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.not_after` | string | Date/Time indicating when server certificate is no longer considered valid. | `2021-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.not_before` | string | Date/Time indicating when server certificate is first considered valid. | `1970-01-01T00:00:00.000Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls.server.subject` | string | Distinguished name of subject of the x.509 certificate presented by the server. | `CN=myserver, OU=Documentation Team, DC=example, DC=com` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). `tls.protocol.name` 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 | Stability | -|---|---|---| -| `ssl` | ssl | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `tls` | tls | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - \ No newline at end of file +| Value | Description | Stability | +| ----- | ----------- | ---------------------------------------------------------------- | +| `ssl` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `tls` | none | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/attributes-registry/url.md b/docs/attributes-registry/url.md index 69ca3fb8f3..3594692af9 100644 --- a/docs/attributes-registry/url.md +++ b/docs/attributes-registry/url.md @@ -1,26 +1,29 @@ + + + # URL -## URL Attributes - - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `url.domain` | string | Domain extracted from the `url.full`, such as "opentelemetry.io". [1] | `www.foo.bar`; `opentelemetry.io`; `3.12.167.2`; `[1080:0:0:0:8:800:200C:417A]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.extension` | string | The file extension extracted from the `url.full`, excluding the leading dot. [2] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [5] | `/search` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `url.port` | int | Port extracted from the `url.full` | `443` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## Url Attributes + +Attributes describing URL. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `url.domain` | string | Domain extracted from the `url.full`, such as "opentelemetry.io". [1] | `www.foo.bar`; `opentelemetry.io`; `3.12.167.2`; `[1080:0:0:0:8:800:200C:417A]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.extension` | string | The file extension extracted from the `url.full`, excluding the leading dot. [2] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.fragment` | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.full` | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.original` | string | Unmodified original URL as seen in the event source. [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `search?q=OpenTelemetry` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.path` | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [5] | `/search` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.port` | int | Port extracted from the `url.full` | `443` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.query` | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [6] | `q=OpenTelemetry` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.registered_domain` | string | The highest registered url domain, stripped of the subdomain. [7] | `example.com`; `foo.co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `url.subdomain` | string | The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. [8] | `east`; `sub2.sub1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `url.top_level_domain` | string | The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. [9] | `com`; `co.uk` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. @@ -42,4 +45,3 @@ linkTitle: URL **[8]:** The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. **[9]:** This value can be determined precisely with the [public suffix list](http://publicsuffix.org). - diff --git a/docs/attributes-registry/user-agent.md b/docs/attributes-registry/user-agent.md index cc0cd35a0c..34b0c71f89 100644 --- a/docs/attributes-registry/user-agent.md +++ b/docs/attributes-registry/user-agent.md @@ -1,18 +1,21 @@ -# User agent + + -## User agent Attributes +# User Agent - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| -| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name. [1] | `Safari`; `YourApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `user_agent.original` | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2`; `1.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +## User Agent Attributes + +Describes user-agent attributes. + +| Attribute | Type | Description | Examples | Stability | +| --------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `user_agent.name` | string | Name of the user-agent extracted from original. Usually refers to the browser's name. [1] | `Safari`; `YourApp` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `user_agent.original` | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `user_agent.version` | string | Version of the user-agent extracted from original. Usually refers to the browser's version [2] | `14.1.2`; `1.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [Example](https://www.whatsmyua.info) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version` **[2]:** [Example](https://www.whatsmyua.info) of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align with `user_agent.name` - diff --git a/docs/attributes-registry/webengine.md b/docs/attributes-registry/webengine.md index 784d7adc94..be5955444e 100644 --- a/docs/attributes-registry/webengine.md +++ b/docs/attributes-registry/webengine.md @@ -1,14 +1,17 @@ + + + # Webengine ## Webengine Attributes - -| Attribute | Type | Description | Examples | Stability | -|---|---|---|---|---| +This document defines the attributes used to describe the packaged software running the application code. + +| Attribute | Type | Description | Examples | Stability | +| ----------------------- | ------ | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- | | `webengine.description` | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `webengine.name` | string | The name of the web engine. | `WildFly` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `webengine.version` | string | The version of the web engine. | `21.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - +| `webengine.name` | string | The name of the web engine. | `WildFly` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `webengine.version` | string | The version of the web engine. | `21.0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/cloud-providers/aws-sdk.md b/docs/cloud-providers/aws-sdk.md index 487ae23a9b..e5374766b8 100644 --- a/docs/cloud-providers/aws-sdk.md +++ b/docs/cloud-providers/aws-sdk.md @@ -27,14 +27,24 @@ with the naming guidelines for RPC client spans. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.system`](../attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.request_id`](../attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). **[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/cloudevents/cloudevents-spans.md b/docs/cloudevents/cloudevents-spans.md index 4e75370331..31193046c1 100644 --- a/docs/cloudevents/cloudevents-spans.md +++ b/docs/cloudevents/cloudevents-spans.md @@ -202,11 +202,11 @@ The following attributes are applicable to creation and processing Spans. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`cloudevents.event_id`](../attributes-registry/cloudevents.md) | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloudevents.event_source`](../attributes-registry/cloudevents.md) | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloudevents.event_spec_version`](../attributes-registry/cloudevents.md) | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloudevents.event_subject`](../attributes-registry/cloudevents.md) | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloudevents.event_type`](../attributes-registry/cloudevents.md) | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_id`](/docs/attributes-registry/cloudevents.md) | string | The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. | `123e4567-e89b-12d3-a456-426614174000`; `0001` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_source`](/docs/attributes-registry/cloudevents.md) | string | The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. | `https://github.com/cloudevents`; `/cloudevents/spec/pull/123`; `my-service` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_spec_version`](/docs/attributes-registry/cloudevents.md) | string | The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_subject`](/docs/attributes-registry/cloudevents.md) | string | The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). | `mynewfile.jpg` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudevents.event_type`](/docs/attributes-registry/cloudevents.md) | string | The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. | `com.github.pull_request.opened`; `com.example.object.deleted.v2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 52033e0adf..c83fb73b9a 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -17,16 +17,16 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the Cassandra table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The Cassandra keyspace name. [3] | `mykeyspace` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.consistency_level`](../attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.coordinator.dc`](../attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.coordinator.id`](../attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.idempotence`](../attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.page_size`](../attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cassandra.speculative_execution_count`](../attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of the Cassandra table that the operation is acting upon. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The Cassandra keyspace name. [3] | `mykeyspace` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.consistency_level`](/docs/attributes-registry/db.md) | string | The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). | `all`; `each_quorum`; `quorum` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.coordinator.dc`](/docs/attributes-registry/db.md) | string | The data center of the coordinating node for a query. | `us-west-2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.coordinator.id`](/docs/attributes-registry/db.md) | string | The ID of the coordinating node for a query. | `be13faa2-8574-4d71-926d-27f16cf8a7af` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.idempotence`](/docs/attributes-registry/db.md) | boolean | Whether or not the query is idempotent. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.page_size`](/docs/attributes-registry/db.md) | int | The fetch size used for paging, i.e. how many rows will be returned at once. | `5000` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cassandra.speculative_execution_count`](/docs/attributes-registry/db.md) | int | The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. | `0`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. @@ -36,7 +36,7 @@ described on this page. **[4]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -`db.cassandra.consistency_level` MUST be one of the following: +`db.cassandra.consistency_level` 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 | Stability | |---|---|---| diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 4a7c63d328..5e38a20aa4 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -20,27 +20,23 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | Cosmos DB container name. [1] | `public.users`; `customers` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.connection_mode`](../attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway` | `Conditionally Required` if not `direct` (or pick gw as default) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.operation_type`](../attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.request_charge`](../attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1.0` | `Conditionally Required` when available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.status_code`](../attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | `Conditionally Required` if response was received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.sub_status_code`](../attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.client_id`](../attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.cosmosdb.request_content_length`](../attributes-registry/db.md) | int | Request payload size in bytes | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [4] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | Cosmos DB container name. [1] | `public.users`; `customers` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.connection_mode`](/docs/attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway`; `direct` | `Conditionally Required` if not `direct` (or pick gw as default) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.operation_type`](/docs/attributes-registry/db.md) | string | CosmosDB Operation Type. | `Invalid`; `Create`; `Patch` | `Conditionally Required` when performing one of the operations in this list | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.request_charge`](/docs/attributes-registry/db.md) | double | RU consumed for that operation | `46.18`; `1` | `Conditionally Required` when available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.status_code`](/docs/attributes-registry/db.md) | int | Cosmos DB status code. | `200`; `201` | `Conditionally Required` if response was received | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.sub_status_code`](/docs/attributes-registry/db.md) | int | Cosmos DB sub status code. | `1000`; `1002` | `Conditionally Required` when response was received and contained sub-code. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.client_id`](/docs/attributes-registry/db.md) | string | Unique Cosmos client instance id. | `3ba4827d-4422-483f-b59f-85b74211c11d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.cosmosdb.request_content_length`](/docs/attributes-registry/db.md) | int | Request payload size in bytes | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [2] | `cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. -**[2]:** when performing one of the operations in this list - -**[3]:** when response was received and contained sub-code. - -**[4]:** The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. +**[2]:** The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). Default value is "NS". -`db.cosmosdb.connection_mode` MUST be one of the following: +`db.cosmosdb.connection_mode` 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 | Stability | |---|---|---| diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 6c3ad89c72..f520448637 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -17,7 +17,7 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation.name`](../attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** In **CouchDB**, `db.operation.name` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation.name` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index d91554259b..dbace71ea0 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -60,15 +60,15 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.system`](/docs/attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [8] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. @@ -171,8 +171,8 @@ This metric is [required][MetricRequired]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.client.connections.state`](../attributes-registry/db.md) | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.state`](/docs/attributes-registry/db.md) | string | The state of a connection in the pool | `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `db.client.connections.state` 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. @@ -194,7 +194,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.idle.min` @@ -210,7 +210,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.max` @@ -226,7 +226,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.pending_requests` @@ -242,7 +242,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.timeouts` @@ -258,7 +258,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.create_time` @@ -274,7 +274,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.wait_time` @@ -290,7 +290,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `db.client.connections.use_time` @@ -306,7 +306,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.client.connections.pool.name`](../attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index fb4d4d0bf3..eaded43c6e 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -73,17 +73,17 @@ These attributes will usually be the same for all operations performed over the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](../attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.text`](../attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [9] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [10] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.parameter.`](../attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.system`](/docs/attributes-registry/db.md) | string | An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. | `other_sql`; `mssql`; `mssqlcompact` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [1] | `public.users`; `customers` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Conditionally Required` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [9] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [10] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | The query parameters used in `db.query.text`, with `` being the parameter name, and the attribute value being the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. diff --git a/docs/database/dynamodb.md b/docs/database/dynamodb.md index a7b6f048a3..099db4d1a7 100644 --- a/docs/database/dynamodb.md +++ b/docs/database/dynamodb.md @@ -19,7 +19,64 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.system`](../attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.system`](/docs/attributes-registry/db.md) | string | The value `dynamodb`. | `dynamodb` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`db.system` 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 | Stability | +|---|---|---| +| `other_sql` | Some other SQL database. Fallback only. See notes. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssql` | Microsoft SQL Server | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mssqlcompact` | Microsoft SQL Server Compact | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mysql` | MySQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `oracle` | Oracle Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db2` | IBM Db2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `postgresql` | PostgreSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redshift` | Amazon Redshift | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hive` | Apache Hive | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudscape` | Cloudscape | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hsqldb` | HyperSQL DataBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `progress` | Progress Database | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `maxdb` | SAP MaxDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hanadb` | SAP HANA | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `ingres` | Ingres | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firstsql` | FirstSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `edb` | EnterpriseDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cache` | InterSystems Caché | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `adabas` | Adabas (Adaptable Database System) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `firebird` | Firebird | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `derby` | Apache Derby | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `filemaker` | FileMaker | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `informix` | Informix | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `instantdb` | InstantDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `interbase` | InterBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mariadb` | MariaDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `netezza` | Netezza | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pervasive` | Pervasive PSQL | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pointbase` | PointBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sqlite` | SQLite | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `sybase` | Sybase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `teradata` | Teradata | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `vertica` | Vertica | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `h2` | H2 | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `coldfusion` | ColdFusion IMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cassandra` | Apache Cassandra | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `hbase` | Apache HBase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `mongodb` | MongoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `redis` | Redis | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchbase` | Couchbase | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `couchdb` | CouchDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cosmosdb` | Microsoft Azure Cosmos DB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dynamodb` | Amazon DynamoDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `neo4j` | Neo4j | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `geode` | Apache Geode | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `elasticsearch` | Elasticsearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `memcached` | Memcached | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cockroachdb` | CockroachDB | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `opensearch` | OpenSearch | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `clickhouse` | ClickHouse | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `spanner` | Cloud Spanner | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `trino` | Trino | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.BatchGetItem @@ -27,8 +84,26 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `Users`; `Cats` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.BatchWriteItem @@ -36,9 +111,27 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](/docs/attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `Users`; `Cats` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.CreateTable @@ -46,13 +139,31 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.global_secondary_indexes`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `[{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.local_secondary_indexes`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `[{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.provisioned_read_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.provisioned_write_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.global_secondary_indexes`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field | `{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](/docs/attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.local_secondary_indexes`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. | `{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_read_capacity`](/docs/attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_write_capacity`](/docs/attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteItem @@ -60,9 +171,27 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](/docs/attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DeleteTable @@ -70,7 +199,25 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.DescribeTable @@ -78,7 +225,25 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.GetItem @@ -86,10 +251,28 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](/docs/attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](/docs/attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.ListTables @@ -97,9 +280,27 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.exclusive_start_table`](../attributes-registry/aws.md) | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_count`](../attributes-registry/aws.md) | int | The number of items in the `TableNames` response parameter. | `20` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.exclusive_start_table`](/docs/attributes-registry/aws.md) | string | The value of the `ExclusiveStartTableName` request parameter. | `Users`; `CatsTable` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](/docs/attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_count`](/docs/attributes-registry/aws.md) | int | The number of items in the `TableNames` response parameter. | `20` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.PutItem @@ -107,9 +308,27 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `[Users, Cats]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](/docs/attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | The keys in the `RequestItems` object field. | `Users`; `Cats` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Query @@ -117,15 +336,33 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.attributes_to_get`](../attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.index_name`](../attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.scan_forward`](../attributes-registry/aws.md) | boolean | The value of the `ScanIndexForward` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.select`](../attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attributes_to_get`](/docs/attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `lives`; `id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](/docs/attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.index_name`](/docs/attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](/docs/attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](/docs/attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.scan_forward`](/docs/attributes-registry/aws.md) | boolean | The value of the `ScanIndexForward` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.select`](/docs/attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.Scan @@ -133,18 +370,36 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.attributes_to_get`](../attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `[lives, id]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consistent_read`](../attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.count`](../attributes-registry/aws.md) | int | The value of the `Count` response parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.index_name`](../attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.limit`](../attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.projection`](../attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.scanned_count`](../attributes-registry/aws.md) | int | The value of the `ScannedCount` response parameter. | `50` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.segment`](../attributes-registry/aws.md) | int | The value of the `Segment` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.select`](../attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.total_segments`](../attributes-registry/aws.md) | int | The value of the `TotalSegments` request parameter. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attributes_to_get`](/docs/attributes-registry/aws.md) | string[] | The value of the `AttributesToGet` request parameter. | `lives`; `id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consistent_read`](/docs/attributes-registry/aws.md) | boolean | The value of the `ConsistentRead` request parameter. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.count`](/docs/attributes-registry/aws.md) | int | The value of the `Count` response parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.index_name`](/docs/attributes-registry/aws.md) | string | The value of the `IndexName` request parameter. | `name_to_group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.limit`](/docs/attributes-registry/aws.md) | int | The value of the `Limit` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.projection`](/docs/attributes-registry/aws.md) | string | The value of the `ProjectionExpression` request parameter. | `Title`; `Title, Price, Color`; `Title, Description, RelatedItems, ProductReviews` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.scanned_count`](/docs/attributes-registry/aws.md) | int | The value of the `ScannedCount` response parameter. | `50` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.segment`](/docs/attributes-registry/aws.md) | int | The value of the `Segment` request parameter. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.select`](/docs/attributes-registry/aws.md) | string | The value of the `Select` request parameter. | `ALL_ATTRIBUTES`; `COUNT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.total_segments`](/docs/attributes-registry/aws.md) | int | The value of the `TotalSegments` request parameter. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateItem @@ -152,9 +407,27 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.item_collection_metrics`](../attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.item_collection_metrics`](/docs/attributes-registry/aws.md) | string | The JSON-serialized value of the `ItemCollectionMetrics` response field. | `{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## DynamoDB.UpdateTable @@ -162,12 +435,30 @@ These attributes are filled in for all DynamoDB request types. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.dynamodb.attribute_definitions`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `[{ "AttributeName": "string", "AttributeType": "string" }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.consumed_capacity`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `[{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.global_secondary_index_updates`](../attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `[{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.provisioned_read_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.provisioned_write_capacity`](../attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1.0`; `2.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.dynamodb.table_names`](../attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `[Users]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | The value `aws-api`. | `aws-api` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.attribute_definitions`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `AttributeDefinitions` request field. | `{ "AttributeName": "string", "AttributeType": "string" }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.consumed_capacity`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `ConsumedCapacity` response field. | `{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": "string", "WriteCapacityUnits": number }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.global_secondary_index_updates`](/docs/attributes-registry/aws.md) | string[] | The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. | `{ "Create": { "IndexName": "string", "KeySchema": [ { "AttributeName": "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": number } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_read_capacity`](/docs/attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. | `1`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.provisioned_write_capacity`](/docs/attributes-registry/aws.md) | double | The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. | `1`; `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.dynamodb.table_names`](/docs/attributes-registry/aws.md) | string[] | A single-element array with the value of the TableName request parameter. | `Users` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.request_id`](/docs/attributes-registry/aws.md) | string | The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. | `79b9da39-b7ae-508a-a6bc-864b2829c622`; `C9ER4AJX75574TDJ` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the operation corresponding to the request, as returned by the AWS SDK [1] | `GetItem`; `PutItem` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The name of the service to which a request is made, as returned by the AWS SDK. [2] | `DynamoDB`; `S3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + +**[2]:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + +`rpc.system` 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 | Stability | +|---|---|---| +| `grpc` | gRPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `java_rmi` | Java RMI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dotnet_wcf` | .NET WCF | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `apache_dubbo` | Apache Dubbo | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `connect_rpc` | Connect RPC | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 8b09d5bd8d..cb4aa286ff 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -26,17 +26,17 @@ If the endpoint id is not available, the span name SHOULD be the `http.request.m | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `search`; `ml.close_job`; `cat.aliases` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://localhost:9200/index/_search?q=user.id:kimchy` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.elasticsearch.path_parts.`](../attributes-registry/db.md) | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | `Conditionally Required` when the url has dynamic values | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.elasticsearch.cluster.name`](../attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.elasticsearch.node.name`](../attributes-registry/db.md) | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [1] | `search`; `ml.close_job`; `cat.aliases` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](/docs/attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [3] | `https://localhost:9200/index/_search?q=user.id:kimchy` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.elasticsearch.path_parts.`](/docs/attributes-registry/db.md) | string | A dynamic value in the url path. [4] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | `Conditionally Required` when the url has dynamic values | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.elasticsearch.cluster.name`](/docs/attributes-registry/db.md) | string | Represents the identifier of an Elasticsearch cluster. | `e9106fc68e3044f0b1475b04bf4ffd5f` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.elasticsearch.node.name`](/docs/attributes-registry/db.md) | string | Represents the human-readable identifier of the node/instance to which a request was routed. | `instance-0000000001` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** This SHOULD be the endpoint identifier for the request. diff --git a/docs/database/hbase.md b/docs/database/hbase.md index 5bd4955583..40fd9be549 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -17,8 +17,8 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The HBase table name. [1] | `mytable`; `ns:table` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The HBase namespace. [2] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The HBase table name. [1] | `mytable`; `ns:table` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The HBase namespace. [2] | `mynamespace` | `Conditionally Required` If applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index bc4a08d7b5..7d874c3f09 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -17,9 +17,9 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.namespace`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The MongoDB database name. [2] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the command being executed. [3] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The MongoDB collection being accessed within the database stated in `db.namespace`. [1] | `public.users`; `customers` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The MongoDB database name. [2] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the command being executed. [3] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 6a0e7766a3..c27cc54f2d 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -17,9 +17,9 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `instance1.products`; `customers` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `instance1.products`; `customers` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. diff --git a/docs/database/redis.md b/docs/database/redis.md index 116be54221..ec3c6cd77e 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -17,10 +17,10 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.namespace`](../attributes-registry/db.md) | string | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). [1] | `0`; `1`; `15` | `Conditionally Required` If and only if it can be captured reliably. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.query.text`](../attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [2] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select). [1] | `0`; `1`; `15` | `Conditionally Required` If and only if it can be captured reliably. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [2] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the database node where the operation was performed. [4] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The database index for current connection can be changed by the application dynamically. Instrumentations MAY use the initial database index provided in the connection string and keep track of the currently selected database to capture the `db.namespace`. Instrumentations SHOULD NOT set this attribute if capturing it would require additional network calls to Redis. diff --git a/docs/database/sql.md b/docs/database/sql.md index 58cfbee159..84c1021c37 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -15,9 +15,9 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`db.collection.name`](../attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](../attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.operation.name`](../attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of the SQL table that the operation is acting upon. [1] | `users`; `dbo.products` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. [3] | `customers`; `test.users` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `SELECT`; `INSERT`; `UPDATE`; `DELETE`; `CREATE`; `mystoredproc` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. diff --git a/docs/dns/dns-metrics.md b/docs/dns/dns-metrics.md index 292e351749..e940ab4a9b 100644 --- a/docs/dns/dns-metrics.md +++ b/docs/dns/dns-metrics.md @@ -36,8 +36,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`dns.question.name`](../attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `dot.net` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](../attributes-registry/error.md) | string | Describes the error the DNS lookup failed with. [2] | `host_not_found`; `no_recovery`; `java.net.UnknownHostException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`dns.question.name`](/docs/attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `dot.net` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes the error the DNS lookup failed with. [2] | `host_not_found`; `no_recovery`; `java.net.UnknownHostException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. diff --git a/docs/dotnet/dotnet-aspnetcore-metrics.md b/docs/dotnet/dotnet-aspnetcore-metrics.md index 772d698a1d..3ff1cebb4b 100644 --- a/docs/dotnet/dotnet-aspnetcore-metrics.md +++ b/docs/dotnet/dotnet-aspnetcore-metrics.md @@ -43,9 +43,9 @@ All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.routing.match_status`](../attributes-registry/aspnetcore.md) | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`aspnetcore.routing.is_fallback`](../attributes-registry/aspnetcore.md) | boolean | A value that indicates whether the matched route is a fallback route. | `True` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.match_status`](/docs/attributes-registry/aspnetcore.md) | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.routing.is_fallback`](/docs/attributes-registry/aspnetcore.md) | boolean | A value that indicates whether the matched route is a fallback route. | `true` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](/docs/attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[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](/docs/http/http-spans.md#http-server-definitions) if there is one. @@ -75,9 +75,9 @@ Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.diagnostics.exception.result`](../attributes-registry/aspnetcore.md) | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`aspnetcore.diagnostics.handler.type`](../attributes-registry/aspnetcore.md) | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.exception.result`](/docs/attributes-registry/aspnetcore.md) | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.diagnostics.handler.type`](/docs/attributes-registry/aspnetcore.md) | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -101,7 +101,7 @@ it's RECOMMENDED to: **[2]:** if and only if the exception was handled by this handler. -`aspnetcore.diagnostics.exception.result` MUST be one of the following: +`aspnetcore.diagnostics.exception.result` 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 | Stability | |---|---|---| @@ -134,7 +134,7 @@ All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](/docs/attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -156,7 +156,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](/docs/attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -174,7 +174,7 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](/docs/attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -196,8 +196,8 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](/docs/attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](/docs/attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. @@ -229,8 +229,8 @@ Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aspnetcore.rate_limiting.result`](../attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`aspnetcore.rate_limiting.policy`](../attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.result`](/docs/attributes-registry/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`aspnetcore.rate_limiting.policy`](/docs/attributes-registry/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** if the matched endpoint for the request had a rate-limiting policy. diff --git a/docs/dotnet/dotnet-kestrel-metrics.md b/docs/dotnet/dotnet-kestrel-metrics.md index c25638eb7b..29456e409e 100644 --- a/docs/dotnet/dotnet-kestrel-metrics.md +++ b/docs/dotnet/dotnet-kestrel-metrics.md @@ -43,10 +43,10 @@ In case instrumentation does not recognize `EndPoint` implementation, it sets th | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -94,14 +94,14 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [2] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`tls.protocol.version`](/docs/attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Captures the exception type when a connection fails. @@ -158,10 +158,10 @@ Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -205,10 +205,10 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -252,12 +252,12 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `http`; `web_sockets` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -307,10 +307,10 @@ Meter name: `Microsoft.AspNetCore.Server.Kestrel`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -358,12 +358,12 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](../attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`tls.protocol.version`](../attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`tls.protocol.version`](/docs/attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Captures the exception type when a TLS handshake fails. @@ -415,10 +415,10 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `unix` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` if the transport is `tcp` or `udp` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/dotnet/dotnet-signalr-metrics.md b/docs/dotnet/dotnet-signalr-metrics.md index 1960b681a1..c9c1e99974 100644 --- a/docs/dotnet/dotnet-signalr-metrics.md +++ b/docs/dotnet/dotnet-signalr-metrics.md @@ -32,10 +32,10 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](/docs/attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](/docs/attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`signalr.connection.status` MUST be one of the following: +`signalr.connection.status` 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 | Stability | |---|---|---| @@ -65,10 +65,10 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`signalr.connection.status`](../attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`signalr.transport`](../attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.connection.status`](/docs/attributes-registry/signalr.md) | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`signalr.transport`](/docs/attributes-registry/signalr.md) | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`signalr.connection.status` MUST be one of the following: +`signalr.connection.status` 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 | Stability | |---|---|---| diff --git a/docs/exceptions/exceptions-logs.md b/docs/exceptions/exceptions-logs.md index 6f1d98f92c..ba4f9b1ea6 100644 --- a/docs/exceptions/exceptions-logs.md +++ b/docs/exceptions/exceptions-logs.md @@ -38,9 +38,9 @@ The table below indicates which attributes should be added to the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.message`](/docs/attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](/docs/attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.stacktrace`](/docs/attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Required if `exception.type` is not set, recommended otherwise. diff --git a/docs/exceptions/exceptions-spans.md b/docs/exceptions/exceptions-spans.md index 0dbb2e7313..5c744f2c12 100644 --- a/docs/exceptions/exceptions-spans.md +++ b/docs/exceptions/exceptions-spans.md @@ -44,14 +44,14 @@ The table below indicates which attributes should be added to the `Event` and their types. -The event name MUST be `exception`. +The event name MUST be `exception` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`exception.message`](../attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.type`](../attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.escaped`](../attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [3] | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`exception.stacktrace`](../attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.message`](/docs/attributes-registry/exception.md) | string | The exception message. | `Division by zero`; `Can't convert 'int' object to str implicitly` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.type`](/docs/attributes-registry/exception.md) | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. | `java.net.ConnectException`; `OSError` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.escaped`](/docs/attributes-registry/exception.md) | boolean | SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. [3] | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`exception.stacktrace`](/docs/attributes-registry/exception.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Required if `exception.type` is not set, recommended otherwise. @@ -67,7 +67,7 @@ It is usually not possible to determine at the point where an exception is throw whether it will escape the scope of a span. However, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span, -as done in the [example for recording span exceptions](#recording-an-exception). +as done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, diff --git a/docs/faas/aws-lambda.md b/docs/faas/aws-lambda.md index 0719970912..c7bd757411 100644 --- a/docs/faas/aws-lambda.md +++ b/docs/faas/aws-lambda.md @@ -47,7 +47,7 @@ and the [cloud resource conventions][cloud]. The following AWS Lambda-specific a | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.lambda.invoked_arn`](../attributes-registry/aws.md) | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.lambda.invoked_arn`](/docs/attributes-registry/aws.md) | string | The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). [1] | `arn:aws:lambda:us-east-1:123456:function:myfunction:myalias` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This may be different from `cloud.resource_id` if an alias is involved. diff --git a/docs/faas/faas-metrics.md b/docs/faas/faas-metrics.md index 8e0d1adf69..104b34c9bd 100644 --- a/docs/faas/faas-metrics.md +++ b/docs/faas/faas-metrics.md @@ -58,9 +58,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -88,9 +88,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -114,9 +114,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -140,9 +140,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -166,9 +166,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -192,9 +192,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -218,9 +218,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -248,9 +248,9 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -274,9 +274,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| diff --git a/docs/faas/faas-spans.md b/docs/faas/faas-spans.md index 8c39ede149..afa1516c86 100644 --- a/docs/faas/faas-spans.md +++ b/docs/faas/faas-spans.md @@ -41,9 +41,9 @@ If Spans following this convention are produced, a Resource of type `faas` MUST | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.invocation_id`](../attributes-registry/faas.md) | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [2] | `datasource` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.resource_id`](/docs/attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [1] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invocation_id`](/docs/attributes-registry/faas.md) | string | The invocation ID of the current function invocation. | `af9d5aa4-a685-4c5f-a22b-444f80b3cc28` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [2] | `datasource`; `http`; `pubsub` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary to set `cloud.resource_id` as a span attribute instead. @@ -73,7 +73,7 @@ trigger that corresponding incoming would have (i.e., this has nothing to do with the underlying transport used to make the API call to invoke the lambda, which is often HTTP). -`faas.trigger` MUST be one of the following: +`faas.trigger` 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 | Stability | |---|---|---| @@ -122,8 +122,8 @@ For incoming FaaS spans, the span kind MUST be `Server`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.trigger`](../attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [1] | `datasource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.coldstart`](../attributes-registry/faas.md) | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.trigger`](/docs/attributes-registry/faas.md) | string | Type of the trigger which caused this function invocation. [1] | `datasource`; `http`; `pubsub` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.coldstart`](/docs/attributes-registry/faas.md) | boolean | A boolean that is true if the serverless function is executed for the first time (aka cold-start). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** For the server/consumer span on the incoming side, `faas.trigger` MUST be set. @@ -134,6 +134,16 @@ the event type. If clients set it, it should be the same as the trigger that corresponding incoming would have (i.e., this has nothing to do with the underlying transport used to make the API call to invoke the lambda, which is often HTTP). + +`faas.trigger` 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 | Stability | +|---|---|---| +| `datasource` | A response to some data source operation such as a database or filesystem read/write | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `http` | To provide an answer to an inbound HTTP request | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `pubsub` | A function is set to be executed when messages are sent to a messaging system | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `timer` | A function is scheduled to be executed regularly | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `other` | If none of the others apply | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Resource attributes as incoming FaaS span attributes @@ -161,9 +171,9 @@ which the invoked FaaS instance reports about itself, if it's instrumented. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.invoked_name`](../attributes-registry/faas.md) | string | The name of the invoked function. [1] | `my-function` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.invoked_provider`](../attributes-registry/faas.md) | string | The cloud provider of the invoked function. [2] | `alibaba_cloud` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.invoked_region`](../attributes-registry/faas.md) | string | The cloud region of the invoked function. [3] | `eu-central-1` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invoked_name`](/docs/attributes-registry/faas.md) | string | The name of the invoked function. [1] | `my-function` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invoked_provider`](/docs/attributes-registry/faas.md) | string | The cloud provider of the invoked function. [2] | `alibaba_cloud`; `aws`; `azure` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.invoked_region`](/docs/attributes-registry/faas.md) | string | The cloud region of the invoked function. [3] | `eu-central-1` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** SHOULD be equal to the `faas.name` resource attribute of the invoked function. @@ -199,10 +209,10 @@ FaaS instrumentations that produce `faas` spans with trigger `datasource`, SHOUL | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.document.collection`](../attributes-registry/faas.md) | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.document.operation`](../attributes-registry/faas.md) | string | Describes the type of the operation that was performed on the data. | `insert` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.document.name`](../attributes-registry/faas.md) | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.document.time`](../attributes-registry/faas.md) | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.collection`](/docs/attributes-registry/faas.md) | string | The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. | `myBucketName`; `myDbName` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.operation`](/docs/attributes-registry/faas.md) | string | Describes the type of the operation that was performed on the data. | `insert`; `edit`; `delete` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.name`](/docs/attributes-registry/faas.md) | string | The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. | `myFile.txt`; `myTableName` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.document.time`](/docs/attributes-registry/faas.md) | string | A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `faas.document.operation` 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. @@ -232,8 +242,8 @@ A function is scheduled to be executed regularly. The following additional attri | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.cron`](../attributes-registry/faas.md) | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.time`](../attributes-registry/faas.md) | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.cron`](/docs/attributes-registry/faas.md) | string | A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). | `0/5 * * * ? *` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.time`](/docs/attributes-registry/faas.md) | string | A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). | `2020-01-23T13:47:06Z` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Other diff --git a/docs/feature-flags/feature-flags-logs.md b/docs/feature-flags/feature-flags-logs.md index 02624c257c..f6644e8053 100644 --- a/docs/feature-flags/feature-flags-logs.md +++ b/docs/feature-flags/feature-flags-logs.md @@ -38,13 +38,13 @@ The table below indicates which attributes should be added to the [LogRecord](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/logs/data-model.md#log-and-event-record-definition) and their types. -The event name MUST be `feature_flag`. +The event name MUST be `feature_flag` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.key`](/docs/attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.provider_name`](/docs/attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.variant`](/docs/attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/feature-flags/feature-flags-spans.md b/docs/feature-flags/feature-flags-spans.md index 6dd85fa18a..71a3f9684e 100644 --- a/docs/feature-flags/feature-flags-spans.md +++ b/docs/feature-flags/feature-flags-spans.md @@ -42,13 +42,13 @@ It's intended to be vendor neutral and provide flexibility for current and futur A flag evaluation SHOULD be recorded as an Event on the span during which it occurred. -The event name MUST be `feature_flag`. +The event name MUST be `feature_flag` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`feature_flag.key`](../attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`feature_flag.provider_name`](../attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`feature_flag.variant`](../attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.key`](/docs/attributes-registry/feature-flag.md) | string | The unique identifier of the feature flag. | `logo-color` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.provider_name`](/docs/attributes-registry/feature-flag.md) | string | The name of the service provider that performs the flag evaluation. | `Flag Manager` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`feature_flag.variant`](/docs/attributes-registry/feature-flag.md) | string | SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. [1] | `red`; `true`; `on` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without including the value itself. This can diff --git a/docs/gen-ai/llm-spans.md b/docs/gen-ai/llm-spans.md index 80d4176edf..5cf34e5ffd 100644 --- a/docs/gen-ai/llm-spans.md +++ b/docs/gen-ai/llm-spans.md @@ -39,22 +39,28 @@ These attributes track input data and metadata for a request to an LLM. Each att | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gen_ai.request.model`](../attributes-registry/llm.md) | string | The name of the LLM a request is being made to. [1] | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.system`](../attributes-registry/llm.md) | string | The name of the LLM foundation model vendor. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.max_tokens`](../attributes-registry/llm.md) | int | The maximum number of tokens the LLM generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.temperature`](../attributes-registry/llm.md) | double | The temperature setting for the LLM request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.top_p`](../attributes-registry/llm.md) | double | The top_p sampling setting for the LLM request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.response.finish_reasons`](../attributes-registry/llm.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `[stop]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.response.id`](../attributes-registry/llm.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.response.model`](../attributes-registry/llm.md) | string | The name of the LLM a response was generated from. [3] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.usage.completion_tokens`](../attributes-registry/llm.md) | int | The number of tokens used in the LLM response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.usage.prompt_tokens`](../attributes-registry/llm.md) | int | The number of tokens used in the LLM prompt. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the LLM a request is being made to. [1] | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The name of the LLM foundation model vendor. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.max_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of tokens the LLM generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the LLM request. | `0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the LLM request. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.finish_reasons`](/docs/attributes-registry/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `stop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the LLM a response was generated from. [3] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.completion_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the LLM response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.usage.prompt_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the LLM prompt. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The name of the LLM a request is being made to. If the LLM is supplied by a vendor, then the value must be the exact name of the model requested. If the LLM is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. **[2]:** If not using a vendor-supplied model, provide a custom friendly name, such as a name of the company or project. If the instrumetnation reports any attributes specific to a custom model, the value provided in the `gen_ai.system` SHOULD match the custom attribute namespace segment. For example, if `gen_ai.system` is set to `the_best_llm`, custom attributes should be added in the `gen_ai.the_best_llm.*` namespace. If none of above options apply, the instrumentation should set `_OTHER`. **[3]:** If available. The name of the LLM serving a response. If the LLM is supplied by a vendor, then the value must be the exact name of the model actually used. If the LLM is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned. + +`gen_ai.system` 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 | Stability | +|---|---|---| +| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Events @@ -62,21 +68,21 @@ These attributes track input data and metadata for a request to an LLM. Each att In the lifetime of an LLM span, an event for prompts sent and completions received MAY be created, depending on the configuration of the instrumentation. -The event name MUST be `gen_ai.content.prompt`. +The event name MUST be `gen_ai.content.prompt` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gen_ai.prompt`](../attributes-registry/llm.md) | string | The full prompt sent to an LLM. [1] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.prompt`](/docs/attributes-registry/gen-ai.md) | string | The full prompt sent to an LLM. [1] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) -The event name MUST be `gen_ai.content.completion`. +The event name MUST be `gen_ai.content.completion` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gen_ai.completion`](../attributes-registry/llm.md) | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gen_ai.completion`](/docs/attributes-registry/gen-ai.md) | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | `Conditionally Required` if and only if corresponding event is enabled | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) diff --git a/docs/general/attributes.md b/docs/general/attributes.md index 9ef3ec0b6c..c779547551 100644 --- a/docs/general/attributes.md +++ b/docs/general/attributes.md @@ -69,8 +69,8 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -106,8 +106,8 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](/docs/attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](/docs/attributes-registry/client.md) | int | Client port number. [2] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. @@ -128,8 +128,8 @@ This also covers unidirectional UDP flows and peer-to-peer communication where t | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`source.address`](../attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`source.port`](../attributes-registry/source.md) | int | Source port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`source.address`](/docs/attributes-registry/source.md) | string | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `source.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`source.port`](/docs/attributes-registry/source.md) | int | Source port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. @@ -141,8 +141,8 @@ Destination fields capture details about the receiver of a network exchange/pack | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`destination.address`](../attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`destination.port`](../attributes-registry/destination.md) | int | Destination port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`destination.address`](/docs/attributes-registry/destination.md) | string | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `destination.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`destination.port`](/docs/attributes-registry/destination.md) | int | Destination port number | `3389`; `2888` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. @@ -159,14 +159,14 @@ if they do not cause breaking changes to HTTP semantic conventions. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.local.address`](../attributes-registry/network.md) | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.local.port`](../attributes-registry/network.md) | int | Local port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.address`](/docs/attributes-registry/network.md) | string | Local address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.port`](/docs/attributes-registry/network.md) | int | Local port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [1] | `amqp`; `http`; `mqtt` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. @@ -241,12 +241,12 @@ Note that `network.local.*` attributes are not included in these examples since | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.carrier.icc`](../attributes-registry/network.md) | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.carrier.mcc`](../attributes-registry/network.md) | string | The mobile carrier country code. | `310` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.carrier.mnc`](../attributes-registry/network.md) | string | The mobile carrier network code. | `001` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.carrier.name`](../attributes-registry/network.md) | string | The name of the mobile carrier. | `sprint` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.connection.subtype`](../attributes-registry/network.md) | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.connection.type`](../attributes-registry/network.md) | string | The internet connection type. | `wifi` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.icc`](/docs/attributes-registry/network.md) | string | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. | `DE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.mcc`](/docs/attributes-registry/network.md) | string | The mobile carrier country code. | `310` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.mnc`](/docs/attributes-registry/network.md) | string | The mobile carrier network code. | `001` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.carrier.name`](/docs/attributes-registry/network.md) | string | The name of the mobile carrier. | `sprint` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.connection.subtype`](/docs/attributes-registry/network.md) | string | This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. | `LTE` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.connection.type`](/docs/attributes-registry/network.md) | string | The internet connection type. | `wifi` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `network.connection.subtype` 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. @@ -296,7 +296,7 @@ Instrumentations SHOULD provide a way for users to configure this name. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`peer.service`](../attributes-registry/peer.md) | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`peer.service`](/docs/attributes-registry/peer.md) | string | The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. | `AuthTokenCache` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Examples of `peer.service` that users may specify: @@ -311,9 +311,9 @@ These attributes may be used for any operation with an authenticated and/or auth | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`enduser.id`](../attributes-registry/enduser.md) | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`enduser.role`](../attributes-registry/enduser.md) | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`enduser.scope`](../attributes-registry/enduser.md) | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`enduser.id`](/docs/attributes-registry/enduser.md) | string | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. | `username` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`enduser.role`](/docs/attributes-registry/enduser.md) | string | Actual/assumed role the client is making the request under extracted from token or application security context. | `admin` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`enduser.scope`](/docs/attributes-registry/enduser.md) | string | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). | `read:message, write:files` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | These attributes describe the authenticated user driving the user agent making requests to the instrumented @@ -358,8 +358,8 @@ a thread that started a span. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`thread.id`](../attributes-registry/thread.md) | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`thread.name`](../attributes-registry/thread.md) | string | Current thread name. | `main` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`thread.id`](/docs/attributes-registry/thread.md) | int | Current "managed" thread ID (as opposed to OS thread ID). | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`thread.name`](/docs/attributes-registry/thread.md) | string | Current thread name. | `main` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Examples of where `thread.id` and `thread.name` can be extracted from: @@ -384,12 +384,12 @@ about the span. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`code.column`](../attributes-registry/code.md) | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`code.filepath`](../attributes-registry/code.md) | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`code.function`](../attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`code.lineno`](../attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`code.namespace`](../attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`code.stacktrace`](../attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.column`](/docs/attributes-registry/code.md) | int | The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `16` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.filepath`](/docs/attributes-registry/code.md) | string | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). | `/usr/local/MyApplication/content_root/app/index.php` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.function`](/docs/attributes-registry/code.md) | string | The method or function name, or equivalent (usually rightmost part of the code unit's name). | `serveRequest` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.lineno`](/docs/attributes-registry/code.md) | int | The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.namespace`](/docs/attributes-registry/code.md) | string | The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. | `com.example.MyHttpService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`code.stacktrace`](/docs/attributes-registry/code.md) | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. | `at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/events.md b/docs/general/events.md index 1cf9f33abb..d9c062a6a1 100644 --- a/docs/general/events.md +++ b/docs/general/events.md @@ -55,7 +55,7 @@ that identify the class of Events but not the instance of the Event. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`event.name`](../attributes-registry/event.md) | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`event.name`](/docs/attributes-registry/event.md) | string | Identifies the class / type of event. [1] | `browser.mouse.click`; `device.app.lifecycle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Event names are subject to the same rules as [attribute names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/common/attribute-naming.md). Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. diff --git a/docs/general/logs.md b/docs/general/logs.md index cd443a3b2d..e51b5d71f4 100644 --- a/docs/general/logs.md +++ b/docs/general/logs.md @@ -38,7 +38,7 @@ These attributes may be used for identifying a Log Record. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`log.record.uid`](../attributes-registry/log.md) | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.record.uid`](/docs/attributes-registry/log.md) | string | A unique identifier for the Log Record. [1] | `01ARZ3NDEKTSV4RRFFQ69G5FAV` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. @@ -59,10 +59,10 @@ As such, these should be recorded as Log Record attributes when applicable. They | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`log.file.name`](../attributes-registry/log.md) | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`log.file.name_resolved`](../attributes-registry/log.md) | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`log.file.path`](../attributes-registry/log.md) | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`log.file.path_resolved`](../attributes-registry/log.md) | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name`](/docs/attributes-registry/log.md) | string | The basename of the file. | `audit.log` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.name_resolved`](/docs/attributes-registry/log.md) | string | The basename of the file, with symlinks resolved. | `uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path`](/docs/attributes-registry/log.md) | string | The full path to the file. | `/var/log/mysql/audit.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.file.path_resolved`](/docs/attributes-registry/log.md) | string | The full path to the file, with symlinks resolved. | `/var/lib/docker/uuid.log` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### I/O Stream @@ -72,7 +72,7 @@ As such, these should be recorded as Log Record attributes when applicable. They | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`log.iostream`](../attributes-registry/log.md) | string | The stream associated with the log. See below for a list of well-known values. | `stdout` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`log.iostream`](/docs/attributes-registry/log.md) | string | The stream associated with the log. See below for a list of well-known values. | `stdout`; `stderr` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `log.iostream` 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. diff --git a/docs/general/session.md b/docs/general/session.md index 876d74d403..639b1c2044 100644 --- a/docs/general/session.md +++ b/docs/general/session.md @@ -20,8 +20,8 @@ backends can link the two sessions. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`session.id`](../attributes-registry/session.md) | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`session.previous_id`](../attributes-registry/session.md) | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`session.id`](/docs/attributes-registry/session.md) | string | A unique id to identify a session. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`session.previous_id`](/docs/attributes-registry/session.md) | string | The previous `session.id` for this user, when known. | `00112233-4455-6677-8899-aabbccddeeff` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/general/trace-compatibility.md b/docs/general/trace-compatibility.md index 958e6c5b4f..ffe1fe34b9 100644 --- a/docs/general/trace-compatibility.md +++ b/docs/general/trace-compatibility.md @@ -27,7 +27,7 @@ between a child Span and a parent Span, as defined by | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`opentracing.ref_type`](../attributes-registry/opentracing.md) | string | Parent-child Reference type [1] | `child_of` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`opentracing.ref_type`](/docs/attributes-registry/opentracing.md) | string | Parent-child Reference type [1] | `child_of`; `follows_from` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The causal relationship between a child Span and a parent Span. diff --git a/docs/graphql/graphql-spans.md b/docs/graphql/graphql-spans.md index a92d27275f..2dd2688405 100644 --- a/docs/graphql/graphql-spans.md +++ b/docs/graphql/graphql-spans.md @@ -17,13 +17,13 @@ MAY be used as span name. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`graphql.document`](../attributes-registry/graphql.md) | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`graphql.operation.name`](../attributes-registry/graphql.md) | string | The name of the operation being executed. | `findBookById` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`graphql.operation.type`](../attributes-registry/graphql.md) | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.document`](/docs/attributes-registry/graphql.md) | string | The GraphQL document being executed. [1] | `query findBookById { bookById(id: ?) { name } }` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.operation.name`](/docs/attributes-registry/graphql.md) | string | The name of the operation being executed. | `findBookById` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`graphql.operation.type`](/docs/attributes-registry/graphql.md) | string | The type of the operation being executed. | `query`; `mutation`; `subscription` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value may be sanitized to exclude sensitive information. -`graphql.operation.type` MUST be one of the following: +`graphql.operation.type` 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 | Stability | |---|---|---| diff --git a/docs/http/http-metrics.md b/docs/http/http-metrics.md index 7aaa901f9f..6f68efb10f 100644 --- a/docs/http/http-metrics.md +++ b/docs/http/http-metrics.md @@ -76,15 +76,15 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](/docs/attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -174,10 +174,10 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [3] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -235,15 +235,15 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](/docs/attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -335,15 +335,15 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [2] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](/docs/attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [4] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -441,14 +441,14 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -529,14 +529,14 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -617,14 +617,14 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [5] | `http`; `spdy` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [7] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -703,12 +703,12 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.connection.state`](../attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.connection.state`](/docs/attributes-registry/http.md) | string | State of the HTTP connection in the HTTP connection pool. | `active`; `idle` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -741,11 +741,11 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. @@ -769,10 +769,10 @@ This metric is optional. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. [2] | `80`; `8080`; `443` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 73a6915e58..4e34aa8403 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -124,23 +124,23 @@ For an HTTP client span, `SpanKind` MUST be `Client`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.resend_count`](../attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [9] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [10] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [11] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [12] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [13] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.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`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.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` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](/docs/attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [4] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [5] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](/docs/attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.resend_count`](/docs/attributes-registry/http.md) | int | The ordinal number of request resending attempt (for any reason, including redirects). [9] | `3` | `Recommended` if and only if request was retried. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [10] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](/docs/attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [11] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](/docs/attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [12] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [13] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -204,10 +204,10 @@ The attribute value MUST consist of either multiple header values as an array of The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* [`http.request.method`](../attributes-registry/http.md) -* [`server.address`](../attributes-registry/server.md) -* [`server.port`](../attributes-registry/server.md) -* [`url.full`](../attributes-registry/url.md) +* [`http.request.method`](/docs/attributes-registry/http.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`server.port`](/docs/attributes-registry/server.md) +* [`url.full`](/docs/attributes-registry/url.md) `http.request.method` 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. @@ -323,28 +323,28 @@ For an HTTP server span, `SpanKind` MUST be `Server`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`http.request.method`](../attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [3] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method_original`](../attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.status_code`](../attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.route`](../attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [6] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.name`](../attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [10] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](../attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [12] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](../attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [14] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.header.`](../attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [15] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.response.header.`](../attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [16] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.local.address`](../attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.local.port`](../attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [1] | `GET`; `POST`; `HEAD` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.path`](/docs/attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. [3] | `http`; `https` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If request has ended with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.method_original`](/docs/attributes-registry/http.md) | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.status_code`](/docs/attributes-registry/http.md) | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.route`](/docs/attributes-registry/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [6] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` If and only if it's available | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.name`](/docs/attributes-registry/network.md) | string | [OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. [7] | `http`; `spdy` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Port of the local HTTP server that received the request. [9] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](/docs/attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [10] | `q=OpenTelemetry` | `Conditionally Required` If and only if one was received/sent. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](/docs/attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `83.164.160.102` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [12] | `1.0`; `1.1`; `2`; `3` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the local HTTP server that received the request. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | 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`; `Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1`; `YourApp/1.0.0 grpc-java-okhttp/1.27.2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](/docs/attributes-registry/client.md) | int | The port of whichever client was captured in `client.address`. [14] | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.request.header.`](/docs/attributes-registry/http.md) | string[] | HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [15] | `http.request.header.content-type=["application/json"]`; `http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`http.response.header.`](/docs/attributes-registry/http.md) | string[] | HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. [16] | `http.response.header.content-type=["application/json"]`; `http.response.header.my-custom-header=["abc", "def"]` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.address`](/docs/attributes-registry/network.md) | string | Local socket address. Useful in case of a multi-IP host. | `10.1.2.80`; `/tmp/my.sock` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.local.port`](/docs/attributes-registry/network.md) | int | Local socket port. Useful in case of a multi-port host. | `65123` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [17] | `tcp`; `udp` | `Opt-In` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** HTTP request method value SHOULD be "known" to the instrumentation. By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) @@ -415,15 +415,15 @@ The attribute value MUST consist of either multiple header values as an array of The following attributes can be important for making sampling decisions and SHOULD be provided **at span creation time** (if provided at all): -* [`http.request.method`](../attributes-registry/http.md) -* [`url.path`](../attributes-registry/url.md) -* [`url.scheme`](../attributes-registry/url.md) -* [`server.port`](../attributes-registry/server.md) -* [`url.query`](../attributes-registry/url.md) -* [`client.address`](../attributes-registry/client.md) -* [`server.address`](../attributes-registry/server.md) -* [`user_agent.original`](../attributes-registry/user-agent.md) -* [`http.request.header.`](../attributes-registry/http.md) +* [`http.request.method`](/docs/attributes-registry/http.md) +* [`url.path`](/docs/attributes-registry/url.md) +* [`url.scheme`](/docs/attributes-registry/url.md) +* [`server.port`](/docs/attributes-registry/server.md) +* [`url.query`](/docs/attributes-registry/url.md) +* [`client.address`](/docs/attributes-registry/client.md) +* [`server.address`](/docs/attributes-registry/server.md) +* [`user_agent.original`](/docs/attributes-registry/user-agent.md) +* [`http.request.header.`](/docs/attributes-registry/http.md) `http.request.method` 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. diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 3deba05a1c..eea9ae1f81 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -18,12 +18,126 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.servicebus.destination.subscription_name`](../attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | `Conditionally Required` If messages are received from the subscription. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.servicebus.disposition_status`](../attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete` | `Conditionally Required` if and only if `messaging.operation` is `settle`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.servicebus.message.delivery_count`](../attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.servicebus.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.destination.subscription_name`](/docs/attributes-registry/messaging.md) | string | The name of the subscription in the topic messages are received from. | `mySubscription` | `Conditionally Required` If messages are received from the subscription. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.disposition_status`](/docs/attributes-registry/messaging.md) | string | Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). | `complete`; `abandon`; `dead_letter` | `Conditionally Required` if and only if `messaging.operation` is `settle`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.message.delivery_count`](/docs/attributes-registry/messaging.md) | int | Number of deliveries that have been attempted for this message. | `2` | `Conditionally Required` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client_id`](/docs/attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.conversation_id`](/docs/attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.servicebus.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** If delivery count is available and is bigger than 0. +**[1]:** If a custom value is used, it MUST be of low cardinality. + +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + +**[4]:** If the span describes an operation on a batch of messages. + +**[5]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + +**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. + +**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + +**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. + +**[10]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[11]:** If delivery count is available and is bigger than 0. + +**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +size should be used. + +**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +Network peer address and port are important when the application interacts with individual intermediary nodes directly, +If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[17]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`messaging.operation.type` 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 | Stability | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.system` 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 | Stability | +|---|---|---| +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +`messaging.servicebus.disposition_status` 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 | Stability | +|---|---|---| +| `complete` | Message is completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `abandon` | Message is abandoned | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dead_letter` | Message is sent to dead letter queue | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `defer` | Message is deferred | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Azure Event Hubs @@ -36,9 +150,113 @@ The following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | String representation of the partition id messages are sent to or received from, unique within the Event Hub. | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.eventhubs.consumer.group`](../attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.eventhubs.message.enqueued_time`](../attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | String representation of the partition id messages are sent to or received from, unique within the Event Hub. | `1` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.eventhubs.consumer.group`](/docs/attributes-registry/messaging.md) | string | The name of the consumer group the event consumer is associated with. | `indexer` | `Conditionally Required` If not default ("$Default"). | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client_id`](/docs/attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.eventhubs.message.enqueued_time`](/docs/attributes-registry/messaging.md) | int | The UTC epoch seconds at which the message has been accepted and stored in the entity. | `1701393730` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [12] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.conversation_id`](/docs/attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [13] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** If a custom value is used, it MUST be of low cardinality. + +**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +* Use a domain-specific attribute +* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + +**[4]:** If the span describes an operation on a batch of messages. + +**[5]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. + +**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. + +**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + +**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. + +**[10]:** If value is `true`. When missing, the value is assumed to be `false`. + +**[11]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + +**[12]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. + +**[13]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +size should be used. + +**[14]:** If the operation is not sufficiently described by `messaging.operation.type`. + +**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +Network peer address and port are important when the application interacts with individual intermediary nodes directly, +If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. + +**[16]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +`messaging.operation.type` 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 | Stability | +|---|---|---| +| `publish` | One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `process` | One or more messages are delivered to or processed by a consumer. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `settle` | One or more messages are settled. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`messaging.system` 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 | Stability | +|---|---|---| +| `activemq` | Apache ActiveMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `aws_sqs` | Amazon Simple Queue Service (SQS) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventgrid` | Azure Event Grid | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `eventhubs` | Azure Event Hubs | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `servicebus` | Azure Service Bus | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gcp_pubsub` | Google Cloud Pub/Sub | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `jms` | Java Message Service | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `kafka` | Apache Kafka | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rabbitmq` | RabbitMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `rocketmq` | Apache RocketMQ | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +`error.type` 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 | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 3ed71fdcf1..5707da5b31 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -17,10 +17,10 @@ For Google Cloud Pub/Sub, the following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.gcp_pubsub.message.ordering_key`](../attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.gcp_pubsub.message.ack_deadline`](../attributes-registry/messaging.md) | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.gcp_pubsub.message.ack_id`](../attributes-registry/messaging.md) | string | The ack id for a given message. | `ack_id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.gcp_pubsub.message.delivery_attempt`](../attributes-registry/messaging.md) | int | The delivery attempt for a given message. | `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ordering_key`](/docs/attributes-registry/messaging.md) | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` | `Conditionally Required` If the message type has an ordering key set. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_deadline`](/docs/attributes-registry/messaging.md) | int | The ack deadline in seconds set for the modify ack deadline request. | `10` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.ack_id`](/docs/attributes-registry/messaging.md) | string | The ack id for a given message. | `ack_id` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.gcp_pubsub.message.delivery_attempt`](/docs/attributes-registry/messaging.md) | int | The delivery attempt for a given message. | `2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Span names diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index 5002947f9e..e53472a28f 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -27,11 +27,11 @@ For Apache Kafka, the following additional attributes are defined: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.kafka.message.tombstone`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | String representation of the partition id the message (or batch) is sent to or received from. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.kafka.consumer.group`](../attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.kafka.message.key`](../attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [2] | `myKey` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.kafka.message.offset`](../attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.tombstone`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message is a tombstone. | | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | String representation of the partition id the message (or batch) is sent to or received from. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.consumer.group`](/docs/attributes-registry/messaging.md) | string | Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. | `my-group` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.key`](/docs/attributes-registry/messaging.md) | string | Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. [2] | `myKey` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.kafka.message.offset`](/docs/attributes-registry/messaging.md) | int | The offset of a record in the corresponding Kafka partition. | `42` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If value is `true`. When missing, the value is assumed to be `false`. diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 6d3f8da201..43f91ff657 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -32,13 +32,13 @@ All messaging metrics share the same set of attributes: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [3] | `MyQueue`; `MyTopic` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [5] | `/customers/{customerId}` | `Conditionally Required` if available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [7] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [2] | `MyQueue`; `MyTopic` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [4] | `/customers/{customerId}` | `Conditionally Required` if available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -60,18 +60,16 @@ it's RECOMMENDED to: * Use a domain-specific attribute * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -**[2]:** If and only if the messaging operation has failed. - -**[3]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[2]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. -**[4]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. +**[3]:** if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated. -**[5]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[4]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[6]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[5]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[7]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `messaging.system` 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. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 1b83775077..d8246af684 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -286,25 +286,25 @@ as described in [Attributes specific to certain messaging systems](#attributes-s | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.operation.type`](../attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.system`](../attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](../attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.batch.message_count`](../attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | `Conditionally Required` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.name`](../attributes-registry/messaging.md) | string | The message destination name [7] | `MyQueue`; `MyTopic` | `Conditionally Required` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.template`](../attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [9] | `/customers/{customerId}` | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.temporary`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`messaging.client_id`](../attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination.partition.id`](../attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.body.size`](../attributes-registry/messaging.md) | int | The size of the message body in bytes. [13] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.conversation_id`](../attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.envelope.size`](../attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [14] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.message.id`](../attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.operation.name`](../attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [16] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [17] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.operation.type`](/docs/attributes-registry/messaging.md) | string | A string identifying the type of the messaging operation. [1] | `publish`; `create`; `receive` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.system`](/docs/attributes-registry/messaging.md) | string | An identifier for the messaging system being used. See below for a list of well-known identifiers. | `activemq`; `aws_sqs`; `eventgrid` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` | `Conditionally Required` If and only if the messaging operation has failed. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.batch.message_count`](/docs/attributes-registry/messaging.md) | int | The number of messages sent, received, or processed in the scope of the batching operation. [3] | `0`; `1`; `2` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.anonymous`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). | | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.name`](/docs/attributes-registry/messaging.md) | string | The message destination name [6] | `MyQueue`; `MyTopic` | `Conditionally Required` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.template`](/docs/attributes-registry/messaging.md) | string | Low cardinality representation of the messaging destination name [8] | `/customers/{customerId}` | `Conditionally Required` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.temporary`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. | | `Conditionally Required` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Conditionally Required` If available. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.client_id`](/docs/attributes-registry/messaging.md) | string | A unique identifier for the client that consumes or produces a message. | `client-5`; `myhost@8742@s8083jm` | `Recommended` If a client id is available | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination.partition.id`](/docs/attributes-registry/messaging.md) | string | The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. | `1` | `Recommended` When applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.body.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body in bytes. [12] | `1439` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.conversation_id`](/docs/attributes-registry/messaging.md) | string | The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". | `MyConversationId` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.envelope.size`](/docs/attributes-registry/messaging.md) | int | The size of the message body and metadata in bytes. [13] | `2738` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.message.id`](/docs/attributes-registry/messaging.md) | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.operation.name`](/docs/attributes-registry/messaging.md) | string | The system-specific name of the messaging operation. | `ack`; `nack`; `send` | `Recommended` [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [15] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this messaging system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` if and only if `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [16] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If a custom value is used, it MUST be of low cardinality. @@ -328,40 +328,38 @@ it's RECOMMENDED to: * Use a domain-specific attribute * Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -**[3]:** If and only if the messaging operation has failed. +**[3]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. -**[4]:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +**[4]:** If the span describes an operation on a batch of messages. -**[5]:** If the span describes an operation on a batch of messages. +**[5]:** If value is `true`. When missing, the value is assumed to be `false`. -**[6]:** If value is `true`. When missing, the value is assumed to be `false`. - -**[7]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +**[6]:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. -**[8]:** If span describes operation on a single message or if the value applies to all messages in the batch. +**[7]:** If span describes operation on a single message or if the value applies to all messages in the batch. -**[9]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +**[8]:** Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -**[10]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. +**[9]:** If available. Instrumentations MUST NOT use `messaging.destination.name` as template unless low-cardinality of destination name is guaranteed. -**[11]:** If value is `true`. When missing, the value is assumed to be `false`. +**[10]:** If value is `true`. When missing, the value is assumed to be `false`. -**[12]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. +**[11]:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -**[13]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +**[12]:** This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed body size should be used. -**[14]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +**[13]:** This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed size should be used. -**[15]:** If the operation is not sufficiently described by `messaging.operation.type`. +**[14]:** If the operation is not sufficiently described by `messaging.operation.type`. -**[16]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. +**[15]:** Semantic conventions for individual messaging systems SHOULD document whether `network.peer.*` attributes are applicable. Network peer address and port are important when the application interacts with individual intermediary nodes directly, If a messaging operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[17]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[16]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. `messaging.operation.type` 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. @@ -409,8 +407,8 @@ under the namespace `messaging.destination_publish.*` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.destination_publish.anonymous`](../attributes-registry/messaging.md) | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.destination_publish.name`](../attributes-registry/messaging.md) | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination_publish.anonymous`](/docs/attributes-registry/messaging.md) | boolean | A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.destination_publish.name`](/docs/attributes-registry/messaging.md) | string | The name of the original destination the message was published to [1] | `MyQueue`; `MyTopic` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker. diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index 7bfac42160..c489cb7ebb 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -20,10 +20,10 @@ In RabbitMQ, the destination is defined by an *exchange* and a *routing key*. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.rabbitmq.destination.routing_key`](../attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | `Conditionally Required` If not empty. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rabbitmq.message.delivery_tag`](../attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | `Conditionally Required` When available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`messaging.rabbitmq.destination.routing_key`](/docs/attributes-registry/messaging.md) | string | RabbitMQ message routing key. | `myKey` | `Conditionally Required` If not empty. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rabbitmq.message.delivery_tag`](/docs/attributes-registry/messaging.md) | int | RabbitMQ message delivery tag | `123` | `Conditionally Required` When available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the messaging intermediary node where the operation was performed. [1] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port of the messaging intermediary node where the operation was performed. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** If an operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index c37538f903..6d99d19fab 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -19,28 +19,28 @@ Specific attributes for Apache RocketMQ are defined below. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`messaging.rocketmq.client_group`](../attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.namespace`](../attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.delay_time_level`](../attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.delivery_timestamp`](../attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.group`](../attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | `Conditionally Required` If the message type is FIFO. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.consumption_model`](../attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.keys`](../attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `[keyA, keyB]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.tag`](../attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`messaging.rocketmq.message.type`](../attributes-registry/messaging.md) | string | Type of message. | `normal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.client_group`](/docs/attributes-registry/messaging.md) | string | Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. | `myConsumerGroup` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.namespace`](/docs/attributes-registry/messaging.md) | string | Namespace of RocketMQ resources, resources in different namespaces are individual. | `myNamespace` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delay_time_level`](/docs/attributes-registry/messaging.md) | int | The delay time level for delay message, which determines the message delay time. | `3` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.delivery_timestamp`](/docs/attributes-registry/messaging.md) | int | The timestamp in milliseconds that the delay message is expected to be delivered to consumer. | `1665987217045` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.group`](/docs/attributes-registry/messaging.md) | string | It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. | `myMessageGroup` | `Conditionally Required` If the message type is FIFO. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.consumption_model`](/docs/attributes-registry/messaging.md) | string | Model of message consumption. This only applies to consumer spans. | `clustering`; `broadcasting` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.keys`](/docs/attributes-registry/messaging.md) | string[] | Key(s) of message, another way to mark message besides message id. | `keyA`; `keyB` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.tag`](/docs/attributes-registry/messaging.md) | string | The secondary classifier of message besides topic. | `tagA` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`messaging.rocketmq.message.type`](/docs/attributes-registry/messaging.md) | string | Type of message. | `normal`; `fifo`; `delay` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the message type is delay and delivery timestamp is not specified. **[2]:** If the message type is delay and delay time level is not specified. -`messaging.rocketmq.consumption_model` MUST be one of the following: +`messaging.rocketmq.consumption_model` 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 | Stability | |---|---|---| | `clustering` | Clustering consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `broadcasting` | Broadcasting consumption model | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`messaging.rocketmq.message.type` MUST be one of the following: +`messaging.rocketmq.message.type` 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 | Stability | |---|---|---| diff --git a/docs/mobile/events.md b/docs/mobile/events.md index 06a6907ef4..dd363ee9bc 100644 --- a/docs/mobile/events.md +++ b/docs/mobile/events.md @@ -30,8 +30,6 @@ NOT be used together, each field MUST be used with its corresponding ### Event details -The event name MUST be `device.app.lifecycle`. - diff --git a/docs/resource/README.md b/docs/resource/README.md index be562f4587..7128009d5f 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -82,8 +82,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`service.name`](../attributes-registry/service.md) | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`service.version`](../attributes-registry/service.md) | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.name`](/docs/attributes-registry/service.md) | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.version`](/docs/attributes-registry/service.md) | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. @@ -99,8 +99,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`service.instance.id`](../attributes-registry/service.md) | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`service.namespace`](../attributes-registry/service.md) | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.instance.id`](/docs/attributes-registry/service.md) | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.namespace`](/docs/attributes-registry/service.md) | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to @@ -157,9 +157,9 @@ service.name = Shop.shoppingcart | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`telemetry.sdk.language`](../attributes-registry/telemetry.md) | string | The language of the telemetry SDK. | `cpp` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`telemetry.sdk.name`](../attributes-registry/telemetry.md) | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`telemetry.sdk.version`](../attributes-registry/telemetry.md) | string | The version string of the telemetry SDK. | `1.2.3` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.language`](/docs/attributes-registry/telemetry.md) | string | The language of the telemetry SDK. | `cpp`; `dotnet`; `erlang` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.name`](/docs/attributes-registry/telemetry.md) | string | The name of the telemetry SDK as defined above. [1] | `opentelemetry` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`telemetry.sdk.version`](/docs/attributes-registry/telemetry.md) | string | The version string of the telemetry SDK. | `1.2.3` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the @@ -197,8 +197,8 @@ All custom identifiers SHOULD be stable across different versions of an implemen | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`telemetry.distro.name`](../attributes-registry/telemetry.md) | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`telemetry.distro.version`](../attributes-registry/telemetry.md) | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`telemetry.distro.name`](/docs/attributes-registry/telemetry.md) | string | The name of the auto instrumentation agent or distribution, if used. [1] | `parts-unlimited-java` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`telemetry.distro.version`](/docs/attributes-registry/telemetry.md) | string | The version string of the auto instrumentation agent or distribution, if used. | `1.2.3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. diff --git a/docs/resource/android.md b/docs/resource/android.md index bcb1317d10..23c7edb1c3 100644 --- a/docs/resource/android.md +++ b/docs/resource/android.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`android.os.api_level`](../attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`android.os.api_level`](/docs/attributes-registry/android.md) | string | Uniquely identifies the framework API revision offered by a version (`os.version`) of the android operating system. More information can be found [here](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels). | `33`; `32` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/browser.md b/docs/resource/browser.md index cc11276d76..767bfbc359 100644 --- a/docs/resource/browser.md +++ b/docs/resource/browser.md @@ -11,11 +11,11 @@ All of these attributes can be provided by the user agent itself in the form of | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`browser.brands`](../attributes-registry/browser.md) | string[] | Array of brand name and version separated by a space [1] | `[ Not A;Brand 99, Chromium 99, Chrome 99]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`browser.language`](../attributes-registry/browser.md) | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`browser.mobile`](../attributes-registry/browser.md) | boolean | A boolean that is true if the browser is running on a mobile device [3] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`browser.platform`](../attributes-registry/browser.md) | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`user_agent.original`](../attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`browser.brands`](/docs/attributes-registry/browser.md) | string[] | Array of brand name and version separated by a space [1] | ` Not A;Brand 99`; `Chromium 99`; `Chrome 99` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.language`](/docs/attributes-registry/browser.md) | string | Preferred language of the user using the browser [2] | `en`; `en-US`; `fr`; `fr-FR` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.mobile`](/docs/attributes-registry/browser.md) | boolean | A boolean that is true if the browser is running on a mobile device [3] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`browser.platform`](/docs/attributes-registry/browser.md) | string | The platform on which the browser is running [4] | `Windows`; `macOS`; `Android` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | string | Full user-agent string provided by the browser [5] | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). diff --git a/docs/resource/cloud-provider/aws/ecs.md b/docs/resource/cloud-provider/aws/ecs.md index c621699190..6a6da8e2eb 100644 --- a/docs/resource/cloud-provider/aws/ecs.md +++ b/docs/resource/cloud-provider/aws/ecs.md @@ -9,13 +9,13 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.ecs.task.id`](../../../attributes-registry/aws.md) | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Conditionally Required` If and only if `task.arn` is populated. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.cluster.arn`](../../../attributes-registry/aws.md) | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.container.arn`](../../../attributes-registry/aws.md) | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.launchtype`](../../../attributes-registry/aws.md) | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.task.arn`](../../../attributes-registry/aws.md) | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.task.family`](../../../attributes-registry/aws.md) | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.ecs.task.revision`](../../../attributes-registry/aws.md) | string | The revision for the task definition used to create the ECS task. | `8`; `26` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.id`](/docs/attributes-registry/aws.md) | string | The ID of a running ECS task. The ID MUST be extracted from `task.arn`. | `10838bed-421f-43ef-870a-f43feacbbb5b`; `23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Conditionally Required` If and only if `task.arn` is populated. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.cluster.arn`](/docs/attributes-registry/aws.md) | string | The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.container.arn`](/docs/attributes-registry/aws.md) | string | The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). | `arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.launchtype`](/docs/attributes-registry/aws.md) | string | The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. | `ec2`; `fargate` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.arn`](/docs/attributes-registry/aws.md) | string | The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). | `arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b`; `arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.family`](/docs/attributes-registry/aws.md) | string | The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. | `opentelemetry-family` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.ecs.task.revision`](/docs/attributes-registry/aws.md) | string | The revision for the task definition used to create the ECS task. | `8`; `26` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `aws.ecs.launchtype` 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. diff --git a/docs/resource/cloud-provider/aws/eks.md b/docs/resource/cloud-provider/aws/eks.md index 3eb55321da..8133eafec7 100644 --- a/docs/resource/cloud-provider/aws/eks.md +++ b/docs/resource/cloud-provider/aws/eks.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.eks.cluster.arn`](../../../attributes-registry/aws.md) | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.eks.cluster.arn`](/docs/attributes-registry/aws.md) | string | The ARN of an EKS cluster. | `arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/aws/logs.md b/docs/resource/cloud-provider/aws/logs.md index 9fc43b4831..4a6d764719 100644 --- a/docs/resource/cloud-provider/aws/logs.md +++ b/docs/resource/cloud-provider/aws/logs.md @@ -9,10 +9,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`aws.log.group.arns`](../../../attributes-registry/aws.md) | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.log.group.names`](../../../attributes-registry/aws.md) | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `[/aws/lambda/my-function, opentelemetry-service]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.log.stream.arns`](../../../attributes-registry/aws.md) | string[] | The ARN(s) of the AWS log stream(s). [3] | `[arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`aws.log.stream.names`](../../../attributes-registry/aws.md) | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `[logs/main/10838bed-421f-43ef-870a-f43feacbbb5b]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.group.arns`](/docs/attributes-registry/aws.md) | string[] | The Amazon Resource Name(s) (ARN) of the AWS log group(s). [1] | `arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.group.names`](/docs/attributes-registry/aws.md) | string[] | The name(s) of the AWS log group(s) an application is writing to. [2] | `/aws/lambda/my-function`; `opentelemetry-service` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.stream.arns`](/docs/attributes-registry/aws.md) | string[] | The ARN(s) of the AWS log stream(s). [3] | `arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`aws.log.stream.names`](/docs/attributes-registry/aws.md) | string[] | The name(s) of the AWS log stream(s) an application is writing to. | `logs/main/10838bed-421f-43ef-870a-f43feacbbb5b` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). diff --git a/docs/resource/cloud-provider/gcp/cloud-run.md b/docs/resource/cloud-provider/gcp/cloud-run.md index abea40486f..572a0e0a7c 100644 --- a/docs/resource/cloud-provider/gcp/cloud-run.md +++ b/docs/resource/cloud-provider/gcp/cloud-run.md @@ -11,8 +11,8 @@ These conventions are recommended for resources running on Cloud Run. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gcp.cloud_run.job.execution`](../../../attributes-registry/gcp.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gcp.cloud_run.job.task_index`](../../../attributes-registry/gcp.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.cloud_run.job.execution`](/docs/attributes-registry/gcp.md) | string | The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `job-name-xxxx`; `sample-job-mdw84` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.cloud_run.job.task_index`](/docs/attributes-registry/gcp.md) | int | The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. | `0`; `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md diff --git a/docs/resource/cloud-provider/gcp/gce.md b/docs/resource/cloud-provider/gcp/gce.md index 377d74679b..0798bc042e 100644 --- a/docs/resource/cloud-provider/gcp/gce.md +++ b/docs/resource/cloud-provider/gcp/gce.md @@ -7,6 +7,6 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gcp.gce.instance.hostname`](../../../attributes-registry/gcp.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gcp.gce.instance.name`](../../../attributes-registry/gcp.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.gce.instance.hostname`](/docs/attributes-registry/gcp.md) | string | The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). | `my-host1234.example.com`; `sample-vm.us-west1-b.c.my-project.internal` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`gcp.gce.instance.name`](/docs/attributes-registry/gcp.md) | string | The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). | `instance-1`; `my-vm-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/docs/resource/cloud-provider/heroku.md b/docs/resource/cloud-provider/heroku.md index 6776486eab..c7b30e8e77 100644 --- a/docs/resource/cloud-provider/heroku.md +++ b/docs/resource/cloud-provider/heroku.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`heroku.app.id`](../../attributes-registry/heroku.md) | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`heroku.release.commit`](../../attributes-registry/heroku.md) | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`heroku.release.creation_timestamp`](../../attributes-registry/heroku.md) | string | Time and date the release was created | `2022-10-23T18:00:42Z` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.app.id`](/docs/attributes-registry/heroku.md) | string | Unique identifier for the application | `2daa2797-e42b-4624-9322-ec3f968df4da` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.release.commit`](/docs/attributes-registry/heroku.md) | string | Commit hash for the current release | `e6134959463efd8966b20e75b913cafe3f5ec` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`heroku.release.creation_timestamp`](/docs/attributes-registry/heroku.md) | string | Time and date the release was created | `2022-10-23T18:00:42Z` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **Mapping:** diff --git a/docs/resource/cloud.md b/docs/resource/cloud.md index 65ed76d78e..797e219b3e 100644 --- a/docs/resource/cloud.md +++ b/docs/resource/cloud.md @@ -9,12 +9,12 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`cloud.account.id`](../attributes-registry/cloud.md) | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.availability_zone`](../attributes-registry/cloud.md) | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.platform`](../attributes-registry/cloud.md) | string | The cloud platform in use. [2] | `alibaba_cloud_ecs` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.provider`](../attributes-registry/cloud.md) | string | Name of the cloud provider. | `alibaba_cloud` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.region`](../attributes-registry/cloud.md) | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.account.id`](/docs/attributes-registry/cloud.md) | string | The cloud account ID the resource is assigned to. | `111111111111`; `opentelemetry` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.availability_zone`](/docs/attributes-registry/cloud.md) | string | Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. [1] | `us-east-1c` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.platform`](/docs/attributes-registry/cloud.md) | string | The cloud platform in use. [2] | `alibaba_cloud_ecs`; `alibaba_cloud_fc`; `alibaba_cloud_openshift` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.provider`](/docs/attributes-registry/cloud.md) | string | Name of the cloud provider. | `alibaba_cloud`; `aws`; `azure` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.region`](/docs/attributes-registry/cloud.md) | string | The geographical region the resource is running. [3] | `us-central1`; `us-east-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.resource_id`](/docs/attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [4] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Availability zones are called "zones" on Alibaba Cloud and Google Cloud. diff --git a/docs/resource/container.md b/docs/resource/container.md index f119a180d1..ce97e71bfc 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -9,18 +9,18 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`container.id`](../attributes-registry/container.md) | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.image.id`](../attributes-registry/container.md) | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [1] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.image.name`](../attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.image.repo_digests`](../attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [2] | `[example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb, internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.image.tags`](../attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `[v1.27.1, 3.5.7-0]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.label.`](../attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.name`](../attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.runtime`](../attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`oci.manifest.digest`](../attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [3] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.command`](../attributes-registry/container.md) | string | The command used to run the container (i.e. the command name). [4] | `otelcontribcol` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.command_args`](../attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `[otelcontribcol, --config, config.yaml]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`container.command_line`](../attributes-registry/container.md) | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.id`](/docs/attributes-registry/container.md) | string | Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. | `a3bf90e006b2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.id`](/docs/attributes-registry/container.md) | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [1] | `sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.name`](/docs/attributes-registry/container.md) | string | Name of the image the container was built on. | `gcr.io/opentelemetry/operator` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.repo_digests`](/docs/attributes-registry/container.md) | string[] | Repo digests of the container image as provided by the container runtime. [2] | `example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb`; `internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.image.tags`](/docs/attributes-registry/container.md) | string[] | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. | `v1.27.1`; `3.5.7-0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.label.`](/docs/attributes-registry/container.md) | string | Container labels, `` being the label name, the value being the label value. | `container.label.app=nginx` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.name`](/docs/attributes-registry/container.md) | string | Container name used by container runtime. | `opentelemetry-autoconf` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.runtime`](/docs/attributes-registry/container.md) | string | The container runtime managing this container. | `docker`; `containerd`; `rkt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`oci.manifest.digest`](/docs/attributes-registry/oci.md) | string | The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. [3] | `sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command`](/docs/attributes-registry/container.md) | string | The command used to run the container (i.e. the command name). [4] | `otelcontribcol` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command_args`](/docs/attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. [2] | `otelcontribcol, --config, config.yaml` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.command_line`](/docs/attributes-registry/container.md) | string | The full command run by the container as a single string representing the full command. [2] | `otelcontribcol --config config.yaml` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. diff --git a/docs/resource/deployment-environment.md b/docs/resource/deployment-environment.md index 7c00e968d8..dae823a128 100644 --- a/docs/resource/deployment-environment.md +++ b/docs/resource/deployment-environment.md @@ -9,7 +9,7 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`deployment.environment`](../attributes-registry/deployment.md) | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`deployment.environment`](/docs/attributes-registry/deployment.md) | string | Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). [1] | `staging`; `production` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** `deployment.environment` does not affect the uniqueness constraints defined through the `service.namespace`, `service.name` and `service.instance.id` resource attributes. diff --git a/docs/resource/device.md b/docs/resource/device.md index 6d76dd4ff5..bf927de0e8 100644 --- a/docs/resource/device.md +++ b/docs/resource/device.md @@ -9,10 +9,10 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`device.id`](../attributes-registry/device.md) | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`device.manufacturer`](../attributes-registry/device.md) | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`device.model.identifier`](../attributes-registry/device.md) | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`device.model.name`](../attributes-registry/device.md) | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.id`](/docs/attributes-registry/device.md) | string | A unique identifier representing the device [1] | `2ab2916d-a51f-4ac8-80ee-45ac31a28092` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.manufacturer`](/docs/attributes-registry/device.md) | string | The name of the device manufacturer [2] | `Apple`; `Samsung` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.model.identifier`](/docs/attributes-registry/device.md) | string | The model identifier for the device [3] | `iPhone3,4`; `SM-G920F` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`device.model.name`](/docs/attributes-registry/device.md) | string | The marketing name for the device model [4] | `iPhone 6s Plus`; `Samsung Galaxy S6` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. diff --git a/docs/resource/faas.md b/docs/resource/faas.md index 4f98555d38..6e949d2abd 100644 --- a/docs/resource/faas.md +++ b/docs/resource/faas.md @@ -16,11 +16,11 @@ See also: | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`faas.name`](../attributes-registry/faas.md) | string | The name of the single function that this runtime instance executes. [1] | `my-function`; `myazurefunctionapp/some-function-name` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`cloud.resource_id`](../attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [2] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.instance`](../attributes-registry/faas.md) | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [3] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.max_memory`](../attributes-registry/faas.md) | int | The amount of memory available to the serverless function converted to Bytes. [4] | `134217728` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`faas.version`](../attributes-registry/faas.md) | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.name`](/docs/attributes-registry/faas.md) | string | The name of the single function that this runtime instance executes. [1] | `my-function`; `myazurefunctionapp/some-function-name` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloud.resource_id`](/docs/attributes-registry/cloud.md) | string | Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP) [2] | `arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function`; `//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID`; `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.instance`](/docs/attributes-registry/faas.md) | string | The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [3] | `2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.max_memory`](/docs/attributes-registry/faas.md) | int | The amount of memory available to the serverless function converted to Bytes. [4] | `134217728` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`faas.version`](/docs/attributes-registry/faas.md) | string | The immutable version of the function being executed. [5] | `26`; `pinkfroid-00002` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is the name of the function as configured/deployed on the FaaS platform and is usually different from the name of the callback diff --git a/docs/resource/host.md b/docs/resource/host.md index 0c5c08daa2..4f39b8d508 100644 --- a/docs/resource/host.md +++ b/docs/resource/host.md @@ -12,15 +12,15 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`host.arch`](../attributes-registry/host.md) | string | The CPU architecture the host system is running on. | `amd64` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.id`](../attributes-registry/host.md) | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.image.id`](../attributes-registry/host.md) | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.image.name`](../attributes-registry/host.md) | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.image.version`](../attributes-registry/host.md) | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.name`](../attributes-registry/host.md) | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.type`](../attributes-registry/host.md) | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.ip`](../attributes-registry/host.md) | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `[192.168.1.140, fe80::abc2:4a28:737a:609e]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.mac`](../attributes-registry/host.md) | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `[AC-DE-48-23-45-67, AC-DE-48-23-45-67-01-9F]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.arch`](/docs/attributes-registry/host.md) | string | The CPU architecture the host system is running on. | `amd64`; `arm32`; `arm64` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.id`](/docs/attributes-registry/host.md) | string | Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. | `fdbf79e8af94cb7f9e8df36789187052` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.id`](/docs/attributes-registry/host.md) | string | VM image ID or host OS image ID. For Cloud, this value is from the provider. | `ami-07b06b442921831e5` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.name`](/docs/attributes-registry/host.md) | string | Name of the VM image or OS install the host was instantiated from. | `infra-ami-eks-worker-node-7d4ec78312`; `CentOS-8-x86_64-1905` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.image.version`](/docs/attributes-registry/host.md) | string | The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.name`](/docs/attributes-registry/host.md) | string | Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. | `opentelemetry-test` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.type`](/docs/attributes-registry/host.md) | string | Type of host. For Cloud, this must be the machine type. | `n1-standard-1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.ip`](/docs/attributes-registry/host.md) | string[] | Available IP addresses of the host, excluding loopback interfaces. [1] | `192.168.1.140`; `fe80::abc2:4a28:737a:609e` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.mac`](/docs/attributes-registry/host.md) | string[] | Available MAC addresses of the host, excluding loopback interfaces. [2] | `AC-DE-48-23-45-67`; `AC-DE-48-23-45-67-01-9F` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. @@ -45,12 +45,12 @@ To report host metrics, the `system.*` namespace SHOULD be used. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`host.cpu.cache.l2.size`](../attributes-registry/host.md) | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.cpu.family`](../attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.cpu.model.id`](../attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.cpu.model.name`](../attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.cpu.stepping`](../attributes-registry/host.md) | string | Stepping or core revisions. | `1`; `r1p1` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`host.cpu.vendor.id`](../attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.cache.l2.size`](/docs/attributes-registry/host.md) | int | The amount of level 2 memory cache available to the processor (in Bytes). | `12288000` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.family`](/docs/attributes-registry/host.md) | string | Family or generation of the CPU. | `6`; `PA-RISC 1.1e` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.model.id`](/docs/attributes-registry/host.md) | string | Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. | `6`; `9000/778/B180L` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.model.name`](/docs/attributes-registry/host.md) | string | Model designation of the processor. | `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.stepping`](/docs/attributes-registry/host.md) | string | Stepping or core revisions. | `1`; `r1p1` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`host.cpu.vendor.id`](/docs/attributes-registry/host.md) | string | Processor manufacturer identifier. A maximum 12-character string. [1] | `GenuineIntel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. diff --git a/docs/resource/os.md b/docs/resource/os.md index 7eb0454c94..6b638d07b7 100644 --- a/docs/resource/os.md +++ b/docs/resource/os.md @@ -11,11 +11,11 @@ In case of virtualized environments, this is the operating system as it is obser | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`os.type`](../attributes-registry/os.md) | string | The operating system type. | `windows` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`os.build_id`](../attributes-registry/os.md) | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`os.description`](../attributes-registry/os.md) | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`os.name`](../attributes-registry/os.md) | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`os.version`](../attributes-registry/os.md) | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.type`](/docs/attributes-registry/os.md) | string | The operating system type. | `windows`; `linux`; `darwin` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.build_id`](/docs/attributes-registry/os.md) | string | Unique identifier for a particular build or compilation of the operating system. | `TQ3C.230805.001.B2`; `20E247`; `22621` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.description`](/docs/attributes-registry/os.md) | string | Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. | `Microsoft Windows [Version 10.0.18363.778]`; `Ubuntu 18.04.1 LTS` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.name`](/docs/attributes-registry/os.md) | string | Human readable operating system name. | `iOS`; `Android`; `Ubuntu` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`os.version`](/docs/attributes-registry/os.md) | string | The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). | `14.2.1`; `18.04.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `os.type` 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. diff --git a/docs/resource/process.md b/docs/resource/process.md index 8b5c5f9619..86081e0f9e 100644 --- a/docs/resource/process.md +++ b/docs/resource/process.md @@ -28,14 +28,14 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`process.command`](../attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.command_args`](../attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `[cmd/otecol, --config=config.yaml]` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.command_line`](../attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.executable.name`](../attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.executable.path`](../attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.owner`](../attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.parent_pid`](../attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.pid`](../attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command`](/docs/attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_args`](/docs/attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `cmd/otecol`; `--config=config.yaml` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.command_line`](/docs/attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.executable.path`](/docs/attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.owner`](/docs/attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.parent_pid`](/docs/attributes-registry/process.md) | int | Parent Process identifier (PPID). | `111` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.pid`](/docs/attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** See [Selecting process attributes](#selecting-process-attributes) for details. @@ -71,9 +71,9 @@ On Windows and other systems where the native format of process commands is a si | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`process.runtime.description`](../attributes-registry/process.md) | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.runtime.name`](../attributes-registry/process.md) | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`process.runtime.version`](../attributes-registry/process.md) | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.runtime.description`](/docs/attributes-registry/process.md) | string | An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. | `Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.runtime.name`](/docs/attributes-registry/process.md) | string | The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. | `OpenJDK Runtime Environment` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.runtime.version`](/docs/attributes-registry/process.md) | string | The version of the runtime of this process, as returned by the runtime without modification. | `14.0.2` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | How to set these attributes for particular runtime kinds is described in the following subsections. diff --git a/docs/resource/webengine.md b/docs/resource/webengine.md index 4ff192e9b4..0a7b282450 100644 --- a/docs/resource/webengine.md +++ b/docs/resource/webengine.md @@ -9,9 +9,9 @@ | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`webengine.name`](../attributes-registry/webengine.md) | string | The name of the web engine. | `WildFly` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`webengine.description`](../attributes-registry/webengine.md) | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`webengine.version`](../attributes-registry/webengine.md) | string | The version of the web engine. | `21.0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.name`](/docs/attributes-registry/webengine.md) | string | The name of the web engine. | `WildFly` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.description`](/docs/attributes-registry/webengine.md) | string | Additional description of the web engine (e.g. detailed version and edition information). | `WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`webengine.version`](/docs/attributes-registry/webengine.md) | string | The version of the web engine. | `21.0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | Information describing the web engine SHOULD be captured using the values acquired from the API provided by the web engine, preferably during runtime, to avoid maintenance burden on engine version upgrades. As an example - Java engines are often but not always packaged as application servers. For Java application servers supporting Servlet API the required information MAY be captured by invoking `ServletContext.getServerInfo()` during runtime and parsing the result. diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index c0b17cbffc..4ef1dd0660 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -19,9 +19,9 @@ Below is a table of attributes that SHOULD be included on client and server Conn | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.connect_rpc.error_code`](../attributes-registry/rpc.md) | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.connect_rpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.connect_rpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.connect_rpc.error_code`](/docs/attributes-registry/rpc.md) | string | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled`; `unknown`; `invalid_argument` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.connect_rpc.request.metadata.`](/docs/attributes-registry/rpc.md) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `rpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.connect_rpc.response.metadata.`](/docs/attributes-registry/rpc.md) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [3] | `rpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If response is not successful and if error code available. @@ -29,7 +29,7 @@ Below is a table of attributes that SHOULD be included on client and server Conn **[3]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. -`rpc.connect_rpc.error_code` MUST be one of the following: +`rpc.connect_rpc.error_code` 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 | Stability | |---|---|---| diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 08b556c080..c2c31ba541 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -19,15 +19,15 @@ Below is a table of attributes that SHOULD be included on client and server gRPC | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.grpc.status_code`](../attributes-registry/rpc.md) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.grpc.request.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.grpc.response.metadata.`](../attributes-registry/rpc.md) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.grpc.status_code`](/docs/attributes-registry/rpc.md) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `2` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.grpc.request.metadata.`](/docs/attributes-registry/rpc.md) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [1] | `rpc.grpc.request.metadata.my-custom-metadata-attribute=["1.2.3.4", "1.2.3.5"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.grpc.response.metadata.`](/docs/attributes-registry/rpc.md) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [2] | `rpc.grpc.response.metadata.my-custom-metadata-attribute=["attribute_value"]` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. **[2]:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. -`rpc.grpc.status_code` MUST be one of the following: +`rpc.grpc.status_code` 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 | Stability | |---|---|---| diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index 2fd56eabe1..c31b17bdd8 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -17,11 +17,11 @@ described on this page. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.jsonrpc.error_code`](../attributes-registry/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response is not successful. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.jsonrpc.version`](../attributes-registry/rpc.md) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | `Conditionally Required` If other than the default version (`1.0`) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.jsonrpc.error_message`](../attributes-registry/rpc.md) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.jsonrpc.request_id`](../attributes-registry/rpc.md) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [1] | `exampleMethod` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.error_code`](/docs/attributes-registry/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response is not successful. | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.version`](/docs/attributes-registry/rpc.md) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | `Conditionally Required` If other than the default version (`1.0`) | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.error_message`](/docs/attributes-registry/rpc.md) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.jsonrpc.request_id`](/docs/attributes-registry/rpc.md) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This is always required for jsonrpc. See the note in the general RPC conventions for more information. diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index 7c2c5fbe32..5c892f8245 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -219,13 +219,13 @@ measurements. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [2] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [3] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [4] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The value SHOULD be normalized to lowercase. diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index f38c76f0b7..b03bb96910 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -97,15 +97,15 @@ Generally, a user SHOULD NOT set `peer.service` to a fully qualified RPC service | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [5] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [6] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [7] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. @@ -157,17 +157,17 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.system`](../attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](../attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](../attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.address`](../attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](../attributes-registry/client.md) | int | Client port number. [5] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.address`](../attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.peer.port`](../attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](../attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [7] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`rpc.method`](../attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [8] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.service`](../attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [9] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.system`](/docs/attributes-registry/rpc.md) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [2] | `80`; `8080`; `443` | `Conditionally Required` [3] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.address`](/docs/attributes-registry/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](/docs/attributes-registry/client.md) | int | Client port number. [5] | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` If `network.peer.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [7] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`rpc.method`](/docs/attributes-registry/rpc.md) | string | The name of the (logical) method being called, must be equal to the $method part in the span name. [8] | `exampleMethod` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.service`](/docs/attributes-registry/rpc.md) | string | The full (logical) name of the service being called, including its package name, if applicable. [9] | `myservice.EchoService` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. @@ -225,18 +225,18 @@ client and server spans SHOULD be created. In case of unary calls only one sent and one received message will be recorded for both client and server spans. -The event name MUST be `rpc.message`. +The event name MUST be `rpc.message` | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`rpc.message.compressed_size`](../attributes-registry/rpc.md) | int | Compressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.message.id`](../attributes-registry/rpc.md) | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.message.type`](../attributes-registry/rpc.md) | string | Whether this is a received or sent message. | `SENT` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`rpc.message.uncompressed_size`](../attributes-registry/rpc.md) | int | Uncompressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.compressed_size`](/docs/attributes-registry/rpc.md) | int | Compressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.id`](/docs/attributes-registry/rpc.md) | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.type`](/docs/attributes-registry/rpc.md) | string | Whether this is a received or sent message. | `SENT`; `RECEIVED` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`rpc.message.uncompressed_size`](/docs/attributes-registry/rpc.md) | int | Uncompressed size of the message in bytes. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** This way we guarantee that the values will be consistent between different implementations. -`rpc.message.type` MUST be one of the following: +`rpc.message.type` 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 | Stability | |---|---|---| diff --git a/docs/runtime/jvm-metrics.md b/docs/runtime/jvm-metrics.md index 769a69f859..c1fbf23158 100644 --- a/docs/runtime/jvm-metrics.md +++ b/docs/runtime/jvm-metrics.md @@ -59,12 +59,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](/docs/attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | |---|---|---| @@ -86,12 +86,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](/docs/attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | |---|---|---| @@ -113,12 +113,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](/docs/attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | |---|---|---| @@ -140,12 +140,12 @@ This metric is obtained from [`MemoryPoolMXBean#getCollectionUsage()`](https://d | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](/docs/attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | |---|---|---| @@ -178,8 +178,8 @@ of `[ 0.01, 0.1, 1, 10 ]`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.gc.action`](../attributes-registry/jvm.md) | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.gc.name`](../attributes-registry/jvm.md) | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.gc.action`](/docs/attributes-registry/jvm.md) | string | Name of the garbage collector action. [1] | `end of minor GC`; `end of major GC` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.gc.name`](/docs/attributes-registry/jvm.md) | string | Name of the garbage collector. [2] | `G1 Young Generation`; `G1 Old Generation` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). @@ -213,10 +213,10 @@ Note that this is the number of platform threads (as opposed to virtual threads) | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.thread.daemon`](../attributes-registry/jvm.md) | boolean | Whether the thread is daemon or not. | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.thread.state`](../attributes-registry/jvm.md) | string | State of the thread. | `runnable`; `blocked` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.thread.daemon`](/docs/attributes-registry/jvm.md) | boolean | Whether the thread is daemon or not. | | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.thread.state`](/docs/attributes-registry/jvm.md) | string | State of the thread. | `runnable`; `blocked` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`jvm.thread.state` MUST be one of the following: +`jvm.thread.state` 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 | Stability | |---|---|---| @@ -351,12 +351,12 @@ This metric is obtained from [`MemoryPoolMXBean#getUsage()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`jvm.memory.pool.name`](../attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`jvm.memory.type`](../attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the memory pool. [1] | `G1 Old Gen`; `G1 Eden space`; `G1 Survivor Space` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`jvm.memory.type`](/docs/attributes-registry/jvm.md) | string | The type of memory. | `heap`; `non_heap` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()). -`jvm.memory.type` MUST be one of the following: +`jvm.memory.type` 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 | Stability | |---|---|---| @@ -411,7 +411,7 @@ This metric is obtained from [`BufferPoolMXBean#getMemoryUsed()`](https://docs.o | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`jvm.buffer.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -430,7 +430,7 @@ This metric is obtained from [`BufferPoolMXBean#getTotalCapacity()`](https://doc | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`jvm.buffer.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). @@ -449,7 +449,7 @@ This metric is obtained from [`BufferPoolMXBean#getCount()`](https://docs.oracle | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `jvm.buffer.pool.name` | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`jvm.buffer.pool.name`](/docs/attributes-registry/jvm.md) | string | Name of the buffer pool. [1] | `mapped`; `direct` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). diff --git a/docs/system/container-metrics.md b/docs/system/container-metrics.md index bec823a405..87c3db0087 100644 --- a/docs/system/container-metrics.md +++ b/docs/system/container-metrics.md @@ -23,7 +23,7 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`container.cpu.state`](../attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`container.cpu.state`](/docs/attributes-registry/container.md) | string | The CPU state for this data point. A container SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `user`; `kernel` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `container.cpu.state` 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. @@ -64,10 +64,10 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -90,10 +90,10 @@ This metric is [opt-in][MetricOptIn]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| diff --git a/docs/system/process-metrics.md b/docs/system/process-metrics.md index e91052222e..dfb0dc13af 100644 --- a/docs/system/process-metrics.md +++ b/docs/system/process-metrics.md @@ -58,7 +58,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.cpu.state`](/docs/attributes-registry/process.md) | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system`; `user`; `wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `process.cpu.state` 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. @@ -82,7 +82,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `process.cpu.state` | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.cpu.state`](/docs/attributes-registry/process.md) | string | The CPU state for this data point. A process SHOULD be characterized _either_ by data points with no `state` labels, _or only_ data points with `state` labels. | `system`; `user`; `wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `process.cpu.state` 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. @@ -132,9 +132,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -155,9 +155,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| @@ -204,7 +204,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `process.context_switch_type` | string | Specifies whether the context switches for this data point were voluntary or involuntary. | `voluntary` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.context_switch_type`](/docs/attributes-registry/process.md) | string | Specifies whether the context switches for this data point were voluntary or involuntary. | `voluntary`; `involuntary` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `process.context_switch_type` 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. @@ -227,7 +227,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `process.paging.fault_type` | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`process.paging.fault_type`](/docs/attributes-registry/process.md) | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major`; `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `process.paging.fault_type` 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. diff --git a/docs/system/system-metrics.md b/docs/system/system-metrics.md index 91f4606aa9..822035f264 100644 --- a/docs/system/system-metrics.md +++ b/docs/system/system-metrics.md @@ -87,8 +87,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.cpu.state`](../attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](/docs/attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.state`](/docs/attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.cpu.state` 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. @@ -116,8 +116,8 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.cpu.state`](../attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](/docs/attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.state`](/docs/attributes-registry/system.md) | string | The CPU state for this data point. A system's CPU SHOULD be characterized *either* by data points with no `state` labels, *or only* data points with `state` labels. | `idle`; `interrupt` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.cpu.state` 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. @@ -171,7 +171,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.cpu.logical_number`](../attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.cpu.logical_number`](/docs/attributes-registry/system.md) | int | The logical CPU number [0..n-1] | `1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ## Memory Metrics @@ -195,7 +195,7 @@ available on the system, that is `system.memory.limit`. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.memory.state`](../attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.memory.state`](/docs/attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.memory.state` 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. @@ -252,7 +252,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.memory.state`](../attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.memory.state`](/docs/attributes-registry/system.md) | string | The memory state | `free`; `cached` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.memory.state` 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. @@ -282,9 +282,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.paging.state`](../attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.state`](/docs/attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.paging.state` MUST be one of the following: +`system.paging.state` 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 | Stability | |---|---|---| @@ -305,9 +305,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.paging.state`](../attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.state`](/docs/attributes-registry/system.md) | string | The memory paging state | `free` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.paging.state` MUST be one of the following: +`system.paging.state` 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 | Stability | |---|---|---| @@ -328,9 +328,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.paging.type`](../attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.type`](/docs/attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.paging.type` MUST be one of the following: +`system.paging.type` 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 | Stability | |---|---|---| @@ -351,17 +351,17 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.paging.direction`](../attributes-registry/system.md) | string | The paging access direction | `in` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.paging.type`](../attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.direction`](/docs/attributes-registry/system.md) | string | The paging access direction | `in` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.paging.type`](/docs/attributes-registry/system.md) | string | The memory paging type | `minor` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.paging.direction` MUST be one of the following: +`system.paging.direction` 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 | Stability | |---|---|---| | `in` | in | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `out` | out | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.paging.type` MUST be one of the following: +`system.paging.type` 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 | Stability | |---|---|---| @@ -386,10 +386,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -410,10 +410,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -441,7 +441,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | ### Metric: `system.disk.operation_time` @@ -462,10 +462,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -486,10 +486,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`disk.io.direction`](../attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`disk.io.direction`](/docs/attributes-registry/disk.md) | string | The disk IO operation direction. | `read` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`disk.io.direction` MUST be one of the following: +`disk.io.direction` 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 | Stability | |---|---|---| @@ -514,13 +514,13 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.mode`](../attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.mountpoint`](../attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.state`](../attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.type`](../attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mode`](/docs/attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mountpoint`](/docs/attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.state`](/docs/attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.type`](/docs/attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.state` MUST be one of the following: +`system.filesystem.state` 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 | Stability | |---|---|---| @@ -553,13 +553,13 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.mode`](../attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.mountpoint`](../attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.state`](../attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.filesystem.type`](../attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mode`](/docs/attributes-registry/system.md) | string | The filesystem mode | `rw, ro` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.mountpoint`](/docs/attributes-registry/system.md) | string | The filesystem mount path | `/mnt/data` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.state`](/docs/attributes-registry/system.md) | string | The filesystem state | `used` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.filesystem.type`](/docs/attributes-registry/system.md) | string | The filesystem type | `ext4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`system.filesystem.state` MUST be one of the following: +`system.filesystem.state` 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 | Stability | |---|---|---| @@ -602,10 +602,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| @@ -626,10 +626,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| @@ -656,10 +656,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| @@ -680,10 +680,10 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.io.direction`](../attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.io.direction`](/docs/attributes-registry/network.md) | string | The network IO operation direction. | `transmit` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -`network.io.direction` MUST be one of the following: +`network.io.direction` 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 | Stability | |---|---|---| @@ -704,9 +704,9 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`network.transport`](../attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`system.device`](../attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`system.network.state`](../attributes-registry/system.md) | string | A stateless protocol MUST NOT set this attribute | `close_wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [1] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`system.device`](/docs/attributes-registry/system.md) | string | The device identifier | `(identifier)` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.network.state`](/docs/attributes-registry/system.md) | string | A stateless protocol MUST NOT set this attribute | `close_wait` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The value SHOULD be normalized to lowercase. @@ -723,7 +723,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`system.network.state` MUST be one of the following: +`system.network.state` 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 | Stability | |---|---|---| @@ -758,7 +758,7 @@ This metric is [recommended][MetricRecommended]. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`system.process.status`](../attributes-registry/system.md) | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`system.process.status`](/docs/attributes-registry/system.md) | string | The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES) | `running` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | `system.process.status` 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. diff --git a/docs/url/url.md b/docs/url/url.md index a33c8f046b..8cf2ce6fec 100644 --- a/docs/url/url.md +++ b/docs/url/url.md @@ -25,11 +25,11 @@ This document defines semantic conventions that describe URL and its components. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`url.fragment`](../attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.full`](../attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.path`](../attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.query`](../attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](../attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.fragment`](/docs/attributes-registry/url.md) | string | The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component | `SemConv` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.full`](/docs/attributes-registry/url.md) | string | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) [1] | `https://www.foo.bar/search?q=OpenTelemetry#SemConv`; `//localhost` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.path`](/docs/attributes-registry/url.md) | string | The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component [2] | `/search` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.query`](/docs/attributes-registry/url.md) | string | The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component [3] | `q=OpenTelemetry` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. diff --git a/model/registry/exception.yaml b/model/registry/exception.yaml index 7e1b011889..70dea3d509 100644 --- a/model/registry/exception.yaml +++ b/model/registry/exception.yaml @@ -46,7 +46,7 @@ groups: whether it will escape the scope of a span. However, it is trivial to know that an exception will escape, if one checks for an active exception just before ending the span, - as done in the [example for recording span exceptions](#recording-an-exception). + as done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception). It follows that an exception may still escape the scope of the span even if the `exception.escaped` attribute was not set or set to false, diff --git a/templates/registry/markdown/attribute_name.j2 b/templates/registry/markdown/attribute_name.j2 new file mode 100644 index 0000000000..e268e6f93d --- /dev/null +++ b/templates/registry/markdown/attribute_name.j2 @@ -0,0 +1,2 @@ +{%- if attribute.type is startingwith("template[") %}`{{ attribute.name }}.` +{%- else %}`{{ attribute.name }}`{%- endif %} \ No newline at end of file diff --git a/templates/registry/markdown/attribute_namespace.md.j2 b/templates/registry/markdown/attribute_namespace.md.j2 new file mode 100644 index 0000000000..e41f6bd09d --- /dev/null +++ b/templates/registry/markdown/attribute_namespace.md.j2 @@ -0,0 +1,45 @@ +{#- This template is rendered per top-level registry namespace. -#} +{#- It consists of two variables: -#} +{#- - id: The top-level namespace id. -#} +{#- - groups: A sequence of all attribute groups under this namespace. -#} +{#- This includes deprecated groups. -#} +{% import 'stability.j2' as stability %} +{% import 'notes.j2' as notes %} +{%- set my_file_name = ctx.id | lower | kebab_case ~ ".md" -%} +{{- template.set_file_name(my_file_name) -}} + + + + + + +# {{ ctx.id | title_case | acronym }} + +{% if ctx.groups | length > 1 %}{% for group in ctx.groups | sort(attribute="id") %} +{%- set group_name = group.id | split_id | list | reject("eq", "registry") | join(" ") -%} +- [{{ group_name | title_case }}](#{{group_name | kebab_case }}-attributes) +{% endfor %}{% endif %} +{% for group in ctx.groups | sort(attribute="id") %} +## {{ group.id | split_id | list | reject("eq", "registry") | join(" ") | title_case }} Attributes + +{{ group.brief }} + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +{%- for attribute in group.attributes | sort(attribute="name") %} +| {% include "attribute_name.j2" %} | {% include "attribute_type.j2" | trim %} | {{ attribute.brief | trim }}{{ notes.add(attribute.note) }} | {% include "examples.j2" | trim %} | {{ stability.badge(attribute.stability, attribute.deprecated) | trim }} | +{%- endfor %} + +{{ notes.render() }} +{% for enum in group.attributes | sort(attribute="name") %} +{%- if enum.type is mapping -%}{#- We should use a filter for enums vs. this if. -#} +`{{enum.name}}` 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 | Stability | +|---|---|---| +{% for espec in enum.type.members %}| `{{espec.value}}` | {{espec.brief | trim}} | {{ stability.badge(espec.stability, espec.deprecated) }} | +{% endfor %} +{% endif %} +{%- endfor -%} +{%- endfor -%} diff --git a/templates/registry/markdown/attribute_type.j2 b/templates/registry/markdown/attribute_type.j2 new file mode 100644 index 0000000000..dd4905253d --- /dev/null +++ b/templates/registry/markdown/attribute_type.j2 @@ -0,0 +1,13 @@ +{%- if attribute.type is mapping %} +{%- if attribute.type.members[0].value is string %}string{%- endif %} +{%- if attribute.type.members[0].value is int %}int{%- endif %} +{%- if attribute.type.members[0].value is float %}double{%- endif %} +{%- elif attribute.type == "template[boolean]" %}boolean +{%- elif attribute.type == "template[int]" %}int +{%- elif attribute.type == "template[double]" %}double +{%- elif attribute.type == "template[string]" %}string +{%- elif attribute.type == "template[boolean[]]" %}boolean[] +{%- elif attribute.type == "template[int[]]" %}int[] +{%- elif attribute.type == "template[double[]]" %}double[] +{%- elif attribute.type == "template[string[]]" %}string[] +{%- else %}{{ attribute.type | trim }}{%- endif %} \ No newline at end of file diff --git a/templates/registry/markdown/examples.j2 b/templates/registry/markdown/examples.j2 new file mode 100644 index 0000000000..63cfcae389 --- /dev/null +++ b/templates/registry/markdown/examples.j2 @@ -0,0 +1,10 @@ +{%- if attribute.type is mapping %} +{%- for e in attribute.type.members %}{% if loop.index0 < 3 %}{% if loop.first == false %}; {% endif %}`{{ e.value | trim }}`{% endif %}{%- endfor %} +{%- else %} +{%- if attribute.examples %} +{%- if attribute.examples is sequence %} +{%- for example in attribute.examples %}{%if loop.first == false %}; {% endif %}`{{ example }}`{%- endfor %} +{%- else %}`{{ attribute.examples | trim }}` +{%- endif %} +{%- endif %} +{%- endif %} diff --git a/templates/registry/markdown/notes.j2 b/templates/registry/markdown/notes.j2 new file mode 100644 index 0000000000..c1d382ab8b --- /dev/null +++ b/templates/registry/markdown/notes.j2 @@ -0,0 +1,16 @@ +{%- set ns = namespace(notes=[],index=0) -%} +{%- macro add(note) %}{% if note %}{% set ns.notes = [ns.notes, [note]] | flatten %} [{{ ns.notes | length + ns.index }}]{% endif %}{% endmacro %} +{%- macro add_with_limit(note) %} +{%- if note | length > 50 %} +{%- set ns.notes = [ns.notes, [note]] | flatten -%} +[{{ ns.notes | length + ns.index }}] +{%- elif note -%} +{{ note }} +{%- endif %} +{%- endmacro %} +{%- macro render() %} +{% for note in ns.notes %}**[{{ns.index+loop.index}}]:** {{note}} +{% endfor %} +{%- set ns.index = ns.notes | length + ns.index -%} +{%- set ns.notes = [] -%} +{%- endmacro %} \ No newline at end of file diff --git a/templates/registry/markdown/readme.md.j2 b/templates/registry/markdown/readme.md.j2 new file mode 100644 index 0000000000..14cf1f38d0 --- /dev/null +++ b/templates/registry/markdown/readme.md.j2 @@ -0,0 +1,40 @@ +{{- template.set_file_name("README.md") -}} + + + + + +# Attribute Registry + +The attributes registry is the place where attributes are defined. An attribute definition covers the following properties of an attribute: + +- the `id` (the fully qualified name) of the attribute +- the `type` of the attribute +- the `stability` of the attribute +- a `brief` description of the attribute and optionally a longer `note` +- example values + +Attributes defined in the registry can be used in different semantic conventions. Attributes should be included in this registry before they are used in semantic conventions. Semantic conventions may override all the properties of an attribute except for the `id` and `type` in case it's required for a particular context. In addition, semantic conventions specify the requirement level of an attribute in the corresponding context. + +A definition of an attribute in the registry doesn't necessarily imply that the attribute is used in any of the semantic conventions. + +If applicable, application developers are encouraged to use existing attributes from this registry. See also [these recommendations][developers recommendations] regarding attribute selection and attribute naming for custom use cases. + +All registered attributes are listed by namespace in this registry. + +> **Warning** +> The following registry overview is a work in progress. +> +> Further attribute namespaces are currently being migrated and will appear in this registry soon. + +Currently, the following namespaces exist: + +{% for bundle in ctx %} +{%- set my_file_name = bundle.id | kebab_case ~ ".md" -%} +- [{{ bundle.id | title_case | acronym }}]({{ my_file_name }}) +{% endfor %} + +[developers recommendations]: ../general/attribute-naming.md#recommendations-for-application-developers \ No newline at end of file diff --git a/templates/registry/markdown/stability.j2 b/templates/registry/markdown/stability.j2 new file mode 100644 index 0000000000..7f43919196 --- /dev/null +++ b/templates/registry/markdown/stability.j2 @@ -0,0 +1,7 @@ +{% macro badge(stability, deprecated) -%} +{%- if deprecated %} ![Deprecated](https://img.shields.io/badge/-deprecated-red)
{{ deprecated | trim }} +{%- elif stability == "stable" %}![Stable](https://img.shields.io/badge/-stable-lightgreen) +{%- elif stability == "deprecated" %}![Deprecated](https://img.shields.io/badge/-deprecated-red) +{%- else %}![Experimental](https://img.shields.io/badge/-experimental-blue) +{%- endif %} +{%- endmacro %} \ No newline at end of file diff --git a/templates/registry/markdown/weaver.yaml b/templates/registry/markdown/weaver.yaml new file mode 100644 index 0000000000..19cbd089a6 --- /dev/null +++ b/templates/registry/markdown/weaver.yaml @@ -0,0 +1,32 @@ +templates: + - pattern: readme.md.j2 + filter: '.groups | map(select(.type == "attribute_group")) | map(select(.id | startswith("registry"))) | group_by(.id | split(".") | .[1]) | map({id: .[0].id | split(".") | .[1], groups: .})' + application_mode: single + - pattern: attribute_namespace.md.j2 + filter: '.groups | map(select(.type == "attribute_group")) | map(select(.id | startswith("registry"))) | group_by(.id | split(".") | .[1]) | map({id: .[0].id | split(".") | .[1], groups: .})' + application_mode: each +acronyms: + - AI + - iOS + - AWS + - CloudEvents + - CosmosDB + - DynamoDB + - ECS + - EKS + - GraphQL + - GCP + - GCE + - HTTP + - JVM + - OCI + - OTel + - OpenTracing + - OS + - RabbitMQ + - RocketMQ + - RPC + - S3 + - SignalR + - TLS + - URL From 70baddd2afa21f618b8723468c7b949d0e5608f9 Mon Sep 17 00:00:00 2001 From: Gergely Kalapos Date: Thu, 2 May 2024 20:20:27 +0200 Subject: [PATCH 478/482] Rename `db.client.connections.*` metrics to `db.client.connection.*` and rename `db.client.connection.usage` to `db.client.connection.count` and adapting units (#966) Co-authored-by: Liudmila Molkova --- .chloggen/db_client_connection_metric.yaml | 24 +++++ docs/database/database-metrics.md | 90 ++++++++--------- model/metrics/database-metrics.yaml | 42 ++++---- model/metrics/deprecated/database.yaml | 110 +++++++++++++++++++++ schema-next.yaml | 8 ++ 5 files changed, 208 insertions(+), 66 deletions(-) create mode 100755 .chloggen/db_client_connection_metric.yaml create mode 100644 model/metrics/deprecated/database.yaml diff --git a/.chloggen/db_client_connection_metric.yaml b/.chloggen/db_client_connection_metric.yaml new file mode 100755 index 0000000000..0c3c9222d8 --- /dev/null +++ b/.chloggen/db_client_connection_metric.yaml @@ -0,0 +1,24 @@ +# Use this changelog template to create an entry for release notes. +# +# If your change doesn't affect end users you should instead start +# your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: db + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: > + Rename `db.client.connections.*` metric namespace to `db.client.connection.*` and + rename `db.client.connection.usage` to `db.client.connection.count`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +# The values here must be integers. +issues: [201, 967] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index dbace71ea0..4350081a1d 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -18,15 +18,15 @@ and attributes but more may be added in the future. - [Database operation](#database-operation) - [Metric: `db.client.operation.duration`](#metric-dbclientoperationduration) - [Connection pools](#connection-pools) - - [Metric: `db.client.connections.usage`](#metric-dbclientconnectionsusage) - - [Metric: `db.client.connections.idle.max`](#metric-dbclientconnectionsidlemax) - - [Metric: `db.client.connections.idle.min`](#metric-dbclientconnectionsidlemin) - - [Metric: `db.client.connections.max`](#metric-dbclientconnectionsmax) - - [Metric: `db.client.connections.pending_requests`](#metric-dbclientconnectionspending_requests) - - [Metric: `db.client.connections.timeouts`](#metric-dbclientconnectionstimeouts) - - [Metric: `db.client.connections.create_time`](#metric-dbclientconnectionscreate_time) - - [Metric: `db.client.connections.wait_time`](#metric-dbclientconnectionswait_time) - - [Metric: `db.client.connections.use_time`](#metric-dbclientconnectionsuse_time) + - [Metric: `db.client.connection.count`](#metric-dbclientconnectioncount) + - [Metric: `db.client.connection.idle.max`](#metric-dbclientconnectionidlemax) + - [Metric: `db.client.connection.idle.min`](#metric-dbclientconnectionidlemin) + - [Metric: `db.client.connection.max`](#metric-dbclientconnectionmax) + - [Metric: `db.client.connection.pending_requests`](#metric-dbclientconnectionpending_requests) + - [Metric: `db.client.connection.timeouts`](#metric-dbclientconnectiontimeouts) + - [Metric: `db.client.connection.create_time`](#metric-dbclientconnectioncreate_time) + - [Metric: `db.client.connection.wait_time`](#metric-dbclientconnectionwait_time) + - [Metric: `db.client.connection.use_time`](#metric-dbclientconnectionuse_time) @@ -158,17 +158,17 @@ If a database operation involved multiple network calls (for example retries), t The following metric instruments describe database client connection pool operations. -### Metric: `db.client.connections.usage` +### Metric: `db.client.connection.count` This metric is [required][MetricRequired]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.usage` | UpDownCounter | `{connection}` | The number of connections that are currently in state described by the `state` attribute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.count` | UpDownCounter | `{connection}` | The number of connections that are currently in state described by the `state` attribute | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -181,129 +181,129 @@ This metric is [required][MetricRequired]. | `idle` | idle | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `used` | used | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.idle.max` +### Metric: `db.client.connection.idle.max` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.idle.max` | UpDownCounter | `{connection}` | The maximum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.idle.min` +### Metric: `db.client.connection.idle.min` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.idle.min` | UpDownCounter | `{connection}` | The minimum number of idle open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.max` +### Metric: `db.client.connection.max` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.max` | UpDownCounter | `{connection}` | The maximum number of open connections allowed | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.pending_requests` +### Metric: `db.client.connection.pending_requests` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.pending_requests` | UpDownCounter | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.pending_requests` | UpDownCounter | `{request}` | The number of pending requests for an open connection, cumulative for the entire pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.timeouts` +### Metric: `db.client.connection.timeouts` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.timeouts` | Counter | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.timeouts` | Counter | `{timeout}` | The number of connection timeouts that have occurred trying to obtain a connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.create_time` +### Metric: `db.client.connection.create_time` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.create_time` | Histogram | `ms` | The time it took to create a new connection | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.create_time` | Histogram | `s` | The time it took to create a new connection | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.wait_time` +### Metric: `db.client.connection.wait_time` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.wait_time` | Histogram | `ms` | The time it took to obtain an open connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.wait_time` | Histogram | `s` | The time it took to obtain an open connection from the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -### Metric: `db.client.connections.use_time` +### Metric: `db.client.connection.use_time` This metric is [recommended][MetricRecommended]. - + | Name | Instrument Type | Unit (UCUM) | Description | Stability | | -------- | --------------- | ----------- | -------------- | --------- | -| `db.client.connections.use_time` | Histogram | `ms` | The time between borrowing a connection and returning it to the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.client.connection.use_time` | Histogram | `s` | The time between borrowing a connection and returning it to the pool | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - + | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`db.client.connections.pool.name`](/docs/attributes-registry/db.md) | string | The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of `server.address` and `server.port` attributes formatted as `server.address:server.port`. | `myDataSource` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | diff --git a/model/metrics/database-metrics.yaml b/model/metrics/database-metrics.yaml index ec8f61c55c..95f884f342 100644 --- a/model/metrics/database-metrics.yaml +++ b/model/metrics/database-metrics.yaml @@ -8,9 +8,9 @@ groups: stability: experimental extends: attributes.db.client - - id: metric.db.client.connections.usage + - id: metric.db.client.connection.count type: metric - metric_name: db.client.connections.usage + metric_name: db.client.connection.count stability: experimental brief: "The number of connections that are currently in state described by the `state` attribute" instrument: updowncounter @@ -21,9 +21,9 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.idle.max + - id: metric.db.client.connection.idle.max type: metric - metric_name: db.client.connections.idle.max + metric_name: db.client.connection.idle.max stability: experimental brief: "The maximum number of idle open connections allowed" instrument: updowncounter @@ -32,9 +32,9 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.idle.min + - id: metric.db.client.connection.idle.min type: metric - metric_name: db.client.connections.idle.min + metric_name: db.client.connection.idle.min stability: experimental brief: "The minimum number of idle open connections allowed" instrument: updowncounter @@ -43,9 +43,9 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.max + - id: metric.db.client.connection.max type: metric - metric_name: db.client.connections.max + metric_name: db.client.connection.max stability: experimental brief: "The maximum number of open connections allowed" instrument: updowncounter @@ -54,9 +54,9 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.pending_requests + - id: metric.db.client.connection.pending_requests type: metric - metric_name: db.client.connections.pending_requests + metric_name: db.client.connection.pending_requests stability: experimental brief: "The number of pending requests for an open connection, cumulative for the entire pool" instrument: updowncounter @@ -65,9 +65,9 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.timeouts + - id: metric.db.client.connection.timeouts type: metric - metric_name: db.client.connections.timeouts + metric_name: db.client.connection.timeouts stability: experimental brief: "The number of connection timeouts that have occurred trying to obtain a connection from the pool" instrument: counter @@ -76,35 +76,35 @@ groups: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.create_time + - id: metric.db.client.connection.create_time type: metric - metric_name: db.client.connections.create_time + metric_name: db.client.connection.create_time stability: experimental brief: "The time it took to create a new connection" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.wait_time + - id: metric.db.client.connection.wait_time type: metric - metric_name: db.client.connections.wait_time + metric_name: db.client.connection.wait_time stability: experimental brief: "The time it took to obtain an open connection from the pool" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: db.client.connections.pool.name requirement_level: required - - id: metric.db.client.connections.use_time + - id: metric.db.client.connection.use_time type: metric - metric_name: db.client.connections.use_time + metric_name: db.client.connection.use_time stability: experimental brief: "The time between borrowing a connection and returning it to the pool" instrument: histogram - unit: "ms" + unit: "s" attributes: - ref: db.client.connections.pool.name requirement_level: required diff --git a/model/metrics/deprecated/database.yaml b/model/metrics/deprecated/database.yaml new file mode 100644 index 0000000000..5e6332294f --- /dev/null +++ b/model/metrics/deprecated/database.yaml @@ -0,0 +1,110 @@ +groups: + - id: metric.db.client.connections.count.deprecated + type: metric + metric_name: db.client.connections.usage + stability: experimental + deprecated: "Replaced by `db.client.connection.count`." + brief: "Deprecated, use `db.client.connection.count` instead." + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: db.client.connections.state + requirement_level: required + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.idle.max.deprecated + type: metric + metric_name: db.client.connections.idle.max + stability: experimental + deprecated: "Replaced by `db.client.connection.idle.max`." + brief: "Deprecated, use `db.client.connection.idle.max` instead." + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.idle.min.deprecated + type: metric + metric_name: db.client.connections.idle.min + stability: experimental + deprecated: "Replaced by `db.client.connection.idle.min`." + brief: "Deprecated, use `db.client.connection.idle.min` instead." + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.max.deprecated + type: metric + metric_name: db.client.connections.max + stability: experimental + deprecated: "Replaced by `db.client.connection.max`." + brief: "Deprecated, use `db.client.connection.max` instead." + instrument: updowncounter + unit: "{connection}" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.pending_requests.deprecated + type: metric + metric_name: db.client.connections.pending_requests + stability: experimental + deprecated: "Replaced by `db.client.connection.pending_requests`." + brief: "Deprecated, use `db.client.connection.pending_requests` instead." + instrument: updowncounter + unit: "{request}" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.timeouts.deprecated + type: metric + metric_name: db.client.connections.timeouts + stability: experimental + deprecated: "Replaced by `db.client.connection.timeouts`." + brief: "Deprecated, use `db.client.connection.timeouts` instead." + instrument: counter + unit: "{timeout}" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.create_time.deprecated + type: metric + metric_name: db.client.connections.create_time + stability: experimental + deprecated: "Replaced by `db.client.connection.create_time`. Note: the unit also changed from `ms` to `s`." + brief: "Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`." + instrument: histogram + unit: "ms" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.wait_time.deprecated + type: metric + metric_name: db.client.connections.wait_time + stability: experimental + deprecated: "Replaced by `db.client.connection.wait_time`. Note: the unit also changed from `ms` to `s`." + brief: "Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`." + instrument: histogram + unit: "ms" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required + + - id: metric.db.client.connections.use_time.deprecated + type: metric + metric_name: db.client.connections.use_time + stability: experimental + deprecated: "Replaced by `db.client.connection.use_time`. Note: the unit also changed from `ms` to `s`." + brief: "Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`." + instrument: histogram + unit: "ms" + attributes: + - ref: db.client.connections.pool.name + requirement_level: required diff --git a/schema-next.yaml b/schema-next.yaml index 85bfa85d72..e344c34056 100644 --- a/schema-next.yaml +++ b/schema-next.yaml @@ -4,6 +4,14 @@ versions: next: metrics: changes: + # https://github.com/open-telemetry/semantic-conventions/pull/966 + - rename_metrics: + db.client.connections.usage: db.client.connection.count + db.client.connections.idle.max: db.client.connection.idle.max + db.client.connections.idle.min: db.client.connection.idle.min + db.client.connections.max: db.client.connection.max + db.client.connections.pending_requests: db.client.connection.pending_requests + db.client.connections.timeouts: db.client.connection.timeouts # https://github.com/open-telemetry/semantic-conventions/pull/909 - rename_attributes: attribute_map: From 30402c468f38c8d0250fa37b1dda590bfb9f81f2 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 2 May 2024 12:03:52 -0700 Subject: [PATCH 479/482] Add experimental HTTP attributes to HTTP spans (#989) --- .chloggen/989.yaml | 7 +++++++ docs/http/http-spans.md | 38 +++++++++++++++++++++++++++++++++++--- model/trace/http.yaml | 30 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 .chloggen/989.yaml diff --git a/.chloggen/989.yaml b/.chloggen/989.yaml new file mode 100644 index 0000000000..d0124672bc --- /dev/null +++ b/.chloggen/989.yaml @@ -0,0 +1,7 @@ +change_type: enhancement + +component: http + +note: List experimental HTTP attributes applicable to HTTP client and server spans. + +issues: [989] diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md index 4e34aa8403..91c060240c 100644 --- a/docs/http/http-spans.md +++ b/docs/http/http-spans.md @@ -4,7 +4,7 @@ linkTitle: Spans # Semantic Conventions for HTTP Spans -**Status**: [Stable][DocumentStatus] +**Status**: [Stable][DocumentStatus], Unless otherwise specified. This document defines semantic conventions for HTTP client and server Spans. They can be used for http and https schemes @@ -17,6 +17,7 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Name](#name) - [Status](#status) - [HTTP client](#http-client) + - [HTTP client experimental attributes](#http-client-experimental-attributes) - [HTTP client span duration](#http-client-span-duration) - [HTTP request retries and redirects](#http-request-retries-and-redirects) - [HTTP server](#http-server) @@ -24,7 +25,8 @@ and various HTTP versions like 1.1, 2 and SPDY. - [Setting `server.address` and `server.port` attributes](#setting-serveraddress-and-serverport-attributes) - [Simple client/server example](#simple-clientserver-example) - [Client/server example with reverse proxy](#clientserver-example-with-reverse-proxy) - - [HTTP Server semantic conventions](#http-server-semantic-conventions) + - [HTTP server semantic conventions](#http-server-semantic-conventions) + - [HTTP server experimental attributes](#http-server-experimental-attributes) - [Examples](#examples) - [HTTP client-server example](#http-client-server-example) - [HTTP client retries examples](#http-client-retries-examples) @@ -240,6 +242,21 @@ The following attributes can be important for making sampling decisions and SHOU | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +### HTTP client experimental attributes + +**Status**: [Experimental][DocumentStatus] + +Instrumentations MAY allow users to enable additional experimental attributes. + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.body.size`](/docs/attributes-registry/http.md) | 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` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.request.size`](/docs/attributes-registry/http.md) | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.response.body.size`](/docs/attributes-registry/http.md) | 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` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.response.size`](/docs/attributes-registry/http.md) | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + ### HTTP client span duration There are some minimal constraints that SHOULD be honored: @@ -314,7 +331,7 @@ Application developers MAY overwrite potentially inaccurate values of `server.*` [Forwarded#host]: https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#host [X-Forwarded-Host]: https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Host -### HTTP Server semantic conventions +### HTTP server semantic conventions This span type represents an inbound HTTP request. @@ -458,6 +475,21 @@ The following attributes can be important for making sampling decisions and SHOU `http.route` MUST be provided at span creation time if and only if it's already available. If it becomes available after span starts, instrumentation MUST populate it anytime before span ends. +### HTTP server experimental attributes + +**Status**: [Experimental][DocumentStatus] + +Instrumentations MAY allow users to enable additional experimental attributes. + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`http.request.body.size`](/docs/attributes-registry/http.md) | 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` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.request.size`](/docs/attributes-registry/http.md) | int | The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. | `1437` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.response.body.size`](/docs/attributes-registry/http.md) | 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` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`http.response.size`](/docs/attributes-registry/http.md) | int | The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. | `1437` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + ## Examples ### HTTP client-server example diff --git a/model/trace/http.yaml b/model/trace/http.yaml index b463f38497..9bfadac3c9 100644 --- a/model/trace/http.yaml +++ b/model/trace/http.yaml @@ -4,6 +4,7 @@ groups: extends: attributes.http.client span_kind: client brief: 'Semantic Convention for HTTP Client' + stability: stable attributes: - ref: http.request.method sampling_relevant: true @@ -37,11 +38,26 @@ groups: Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. + - id: trace.http.client.experimental + type: attribute_group + brief: 'Experimental attributes for HTTP Client spans' + stability: experimental + attributes: + - ref: http.request.size + requirement_level: opt_in + - ref: http.response.size + requirement_level: opt_in + - ref: http.request.body.size + requirement_level: opt_in + - ref: http.response.body.size + requirement_level: opt_in + - id: trace.http.server type: span extends: attributes.http.server span_kind: server brief: 'Semantic Convention for HTTP Server' + stability: stable attributes: - ref: http.request.method sampling_relevant: true @@ -95,3 +111,17 @@ groups: note: > Generally `tcp` for `HTTP/1.0`, `HTTP/1.1`, and `HTTP/2`. Generally `udp` for `HTTP/3`. Other obscure implementations are possible. + + - id: trace.http.server.experimental + type: attribute_group + brief: 'Experimental attributes for HTTP Server spans' + stability: experimental + attributes: + - ref: http.request.size + requirement_level: opt_in + - ref: http.response.size + requirement_level: opt_in + - ref: http.request.body.size + requirement_level: opt_in + - ref: http.response.body.size + requirement_level: opt_in From 127974282767f708993771606b1b9a5621b33609 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 2 May 2024 14:06:29 -0700 Subject: [PATCH 480/482] Database: update span name (#974) Co-authored-by: Trask Stalnaker Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> --- .chloggen/974.yaml | 7 +++++++ docs/database/cosmosdb.md | 2 +- docs/database/database-spans.md | 34 ++++++++++++++++++++++----------- docs/database/mongodb.md | 2 +- docs/database/redis.md | 4 ++-- 5 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 .chloggen/974.yaml diff --git a/.chloggen/974.yaml b/.chloggen/974.yaml new file mode 100644 index 0000000000..5be41e3283 --- /dev/null +++ b/.chloggen/974.yaml @@ -0,0 +1,7 @@ +change_type: breaking + +component: db + +note: Clarify database span name format and fallback values. + +issues: [974, 704] diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 5e38a20aa4..80ea0bc7a9 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -71,7 +71,7 @@ In addition to Cosmos DB attributes, all spans include | Key | Value | |:-------------------------------------| :------------------- | -| Span name | `"ReadItemsAsync"` | +| Span name | `"ReadItemsAsync orders"` | | `kind` | `"internal"` | | `az.namespace` | `"Microsoft.DocumentDB"` | | `db.system` | `"cosmosdb"` | diff --git a/docs/database/database-spans.md b/docs/database/database-spans.md index eaded43c6e..919a736301 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -10,6 +10,7 @@ linkTitle: Client Calls +- [Name](#name) - [Common attributes](#common-attributes) - [Notes and well-known identifiers for `db.system`](#notes-and-well-known-identifiers-for-dbsystem) - [Semantic Conventions for specific database technologies](#semantic-conventions-for-specific-database-technologies) @@ -51,21 +52,32 @@ linkTitle: Client Calls **Span kind:** MUST always be `CLIENT`. -The **span name** SHOULD be set to a low cardinality value representing the statement executed on the database. -It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. -Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the -following way, unless the statement is known to be of low cardinality: -` .`, provided that `db.operation.name` and `db.collection.name` are available. -If `db.collection.name` is not available due to its semantics, the span SHOULD be named ` `. - -It is not recommended to attempt any client-side parsing of `db.query.text` just to get these properties, -they should only be used if the library being instrumented already provides them. -When it's otherwise impossible to get any meaningful span name, `db.namespace` or the tech-specific database name MAY be used. - Span that describes database call SHOULD cover the duration of the corresponding call as if it was observed by the caller (such as client application). For example, if a transient issue happened and was retried within this database call, the corresponding span should cover the duration of the logical operation with all retries. +## Name + +Database spans MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/trace/api.md#span). + + + +The **span name** SHOULD be `{db.operation.name} {target}` if there is a +(low-cardinality) `db.operation.name` available (see below for the exact definition of the [`{target}`](#target-placeholder) placeholder). + +If there is no (low-cardinality) `db.operation.name` available, database span names +SHOULD be [`{target}`](#target-placeholder). + + +Semantic conventions for individual database systems MAY specify different span name format. + +The `{target}` SHOULD adhere to one of the following values, arranged in prioritized order, provided they are accessible: + +- `db.collection.name` +- `db.namespace` +- `server.address:server.port` +- `db.system` + ## Common attributes These attributes will usually be the same for all operations performed over the same database connection. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 7d874c3f09..7a48550c8f 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -34,7 +34,7 @@ described on this page. | Key | Value | |:------------------------| :----------------------------------------------------------- | -| Span name | `"products.findAndModify"` | +| Span name | `"findAndModify products"` | | `db.system` | `"mongodb"` | | `server.address` | `"mongodb0.example.com"` | | `server.port` | `27017` | diff --git a/docs/database/redis.md b/docs/database/redis.md index ec3c6cd77e..25706de783 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -39,12 +39,12 @@ In this example, Redis is connected using a unix domain socket and therefore the | Key | Value | |:--------------------------| :-------------------------------------------- | -| Span name | `"HMSET myhash"` | +| Span name | `"HMSET 15"` | | `db.system` | `"redis"` | | `network.peer.address` | `"/tmp/redis.sock"` | | `network.transport` | `"unix"` | | `db.namespace` | `"15"` | | `db.query.text` | `"HMSET myhash field1 'Hello' field2 'World"` | -| `db.operation.name` | not set | +| `db.operation.name` | `"HMSET"` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md From e760c9967898537363c9c08dea6408b8c05f2fdb Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Fri, 3 May 2024 15:43:04 +0200 Subject: [PATCH 481/482] Use --dryRun from v2.* docfx --- .github/workflows/checks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index d7a284a688..9c8907000d 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -79,10 +79,10 @@ jobs: dotnet-version: 6.0.x - name: install docfx - run: dotnet tool update -g docfx --version "3.0.0-*" --add-source https://docfx.pkgs.visualstudio.com/docfx/_packaging/docs-public-packages/nuget/v3/index.json + run: dotnet tool update -g docfx - name: run docfx - run: docfx build --dry-run + run: docfx build --dryRun semantic-conventions: runs-on: ubuntu-latest From a7d125cee6bc6f254bba291c1cb5c2baef1558c5 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Fri, 3 May 2024 15:48:11 +0200 Subject: [PATCH 482/482] Fix docfx.json --- docfx.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docfx.json b/docfx.json index f69395082c..a04e6403f4 100644 --- a/docfx.json +++ b/docfx.json @@ -2,6 +2,6 @@ "files": "**/*.{md,png}", "warningsAsErrors": true, "rules": { - "link-out-of-scope": "off" + "link-out-of-scope": "verbose" } }

4e_BpJXMNO-)91223 z19(DmxI^Y$o)9dX6r^Q)ehqO9hk3*(YLQWyaWPggu{3ML{Pw47EYU9Sb_X5T1)Li}z2u=~KwDWywT+tiu0TGI*Pekz|)Pd1?;7J#4Dsv^# z@+s*X?{22`=Dm;-!0NCH910YQ@Lk(5YqN$>q(=VmSJbD=bB+*z2!E*@c7rQUrsm;s z0q^loGqi6w7DPa3%KJ>%vUrjp1QaF7rPXqiRW3C=v&iuiky6OnpoZI9J40YGOGOC? zMXYk*p1+B81wq6V%XGPeQ2irMb7Qfj^FA%miBuDi<)K`0?F z-QRv()|M48Mj2>F91VQdtzeAU6f&HQrI+-5pFo`b9oW~SqMXnqyr_Chph+3bwfM5w z<0=hg^u+b0{`CFKeH-672uZDrO>83OSP39x7#EdYsndfYvQ&JSdMp~m z-*k;&5kFkPRQkG5fyUo{@{Xu_%U|)t^{(HhCOnM)4{}YQ%1jBIE)LfeL&O zt1~QGt3FLsBZx!zbu#XJCf3M=8kmibP=-%4^cO54;Fln-H1@Dlg$}e z^0`R+`rwU{dkxEI9FHwG_({E1m`z2IR&O+T`nB#BXA!p zj|~NEpi^~Vn(%aS&;x|rZu^SX`ve%&rBsW!W8@q_z+cYb;qT&6L?b+`TkV$Lx`j>eouO4y#+(M_OLD@ zwk!EEn32Eas?jt8r5mw3rShuhu|sbr2R1&0uEm!UPb)-fMvQgIhEu;D2Z zfRI)149d?xPG2(YN>77W;9w+BN2%JUonHype(RD)IIAaM7BLectH0Eq;MS%kA)Hw> zn27ZRkDpA9&)8oEs+Xt|c=t z@z1=*J)Ab=rs=Le`MuHlMG59mjPiah7E9)Q{|t+Xd>Q>M-8+jopAXI5NH&IPWOXh{ z+`uQieCW&8srQp(rFxZyzhMskdJ!^Ta+}(owF> zV(Md$5Qe$QEc z51ruu=5e7+@ZrkBbWLI_V)yf^&^x^SFNlw-U?(9yCJ0MXA4Fu|{g55j_48N6s9^h* z(WcW_o!KVvN&0EvnAVnk2}Z;u;X@cNcwb>2;S9YRTF^?F2un^E`RcT3oqRZh~=NjO*#F9hc~Uc_tE8IX5$$ckTu4~y8$t8RidRoU)Z*`r>Fv$fTzj7n{O znQ_O=$D901y00A}0?`dO_@t~f7M6$oX(y+mdI>ms2qN8Z;U|dGT&OD799?Cyv3-V+ zOb;xEf1ZA2DLrCjeR>&ZFDTjJFM&{Tmuc!1+Whw-H9i~p(efmQASCID8bWm#3v|V* z>u7IQR^b{)BLpGy0o^<^oz2DA*jTKMDESmZEKPfME$EAEO@7JO3DWnof{{PJStOh) z^AGFrgT*WmDp4GUL`L94T+PR^`eUd6^HrR*^e5w~CaN1w+;HI;nu!;+E5;UH;ai;! z&T(b1g!#gNK&v@FKa3F8?pz>;YSr7qK}?{;N4M}O(@fPHK1TUS^gMXw`%95vR5}=) z`x2q%A$AfQwwtw@D*X*36} zQv|%QTot4_cnUUD@ibUMdQ4W z6=E9Fd7B;&xbjqJuJ=8x!lF{&NPo28b?LY4;-1F$`d2=* z`eP{XI>V=MwVoeh$DN9OnYggFFyAcu*_6u{~wpDa<3;k~N3%*GnQX+C$KjE5PbV!?GR8k#NI-C;N3Hh?YWq z_R}?oL`V3^cxwJ#2yEsaF8B_@6A`3|#|yS9n7A-g#FT&$ETX+_1~mqu@;vhhykoD5 z%?RO*z7hv=ZeBh%dbx67rRFDvgX%wV ztF`waWH`tPWXv69~$4vK50-){THzXklM NoL4`WCvO_?zX06li`W1F literal 0 HcmV?d00001 diff --git a/docs/general/reverse-proxy.png b/docs/general/reverse-proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..2f21f817d8ebd3cc511c76bd7295c607b2e34949 GIT binary patch literal 270548 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