diff --git a/.chloggen/1421.yaml b/.chloggen/1421.yaml new file mode 100644 index 0000000000..c1870bdf0f --- /dev/null +++ b/.chloggen/1421.yaml @@ -0,0 +1,4 @@ +change_type: breaking +component: database +note: Add new `db.response.status_code` attribute, deprecate `db.cosmos.status_code`. +issues: [1424] diff --git a/.chloggen/add_container_csi_attributes.yaml b/.chloggen/add_container_csi_attributes.yaml new file mode 100644 index 0000000000..8bcfe8a961 --- /dev/null +++ b/.chloggen/add_container_csi_attributes.yaml @@ -0,0 +1,7 @@ +change_type: enhancement +component: container +note: >- + Add CSI (Container Storage Interface) attributes: + `container.csi.plugin.name` and `container.csi.volume.id`. +issues: [1119] +subtext: diff --git a/.chloggen/add_k8s_memory_usage.yaml b/.chloggen/add_k8s_memory_usage.yaml new file mode 100755 index 0000000000..a57b9d7f42 --- /dev/null +++ b/.chloggen/add_k8s_memory_usage.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 k8s.pod.memory usage and k8s.node.memory.usage metrics + +# 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: [1406] + +# (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/cf-resource.yaml b/.chloggen/cf-resource.yaml new file mode 100644 index 0000000000..d30ce7052c --- /dev/null +++ b/.chloggen/cf-resource.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: new_component + +# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db) +component: cloudfoundry + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Adds a resource convention for Cloud Foundry applications and system components. + +# 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: [622, 624] + +# (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: | + Introduces a description for CloudFoundry resources. These can either be + applications deployed on the runtime or system components of Cloud Foundry + itself. It also extends to the runtime logs and metrics, e.g. Gorouter access + logs and container metrics. diff --git a/.chloggen/file_leftovers.yaml b/.chloggen/file_leftovers.yaml new file mode 100755 index 0000000000..099d6d9e3c --- /dev/null +++ b/.chloggen/file_leftovers.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: file + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add additional attributes from ECS to the `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: [914] + +# (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-deprecated-messaging-servicebus.yaml b/.chloggen/fix-deprecated-messaging-servicebus.yaml new file mode 100755 index 0000000000..996b4a4deb --- /dev/null +++ b/.chloggen/fix-deprecated-messaging-servicebus.yaml @@ -0,0 +1,4 @@ +change_type: 'bug_fix' +component: messaging +note: Fix deprecated note for service bus attributes +issues: [1418] diff --git a/.chloggen/messaging-parent-child-trace.yaml b/.chloggen/messaging-parent-child-trace.yaml new file mode 100755 index 0000000000..6cf1fd1c10 --- /dev/null +++ b/.chloggen/messaging-parent-child-trace.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: messaging +note: Clarify the possibility to have a parent-child trace structure in messaging conventions +issues: [1282] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index d0efd84320..e4e6d6b430 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -30,6 +30,7 @@ body: - area:client - area:cloud - area:cloudevents + - area:cloudfoundry - area:code - area:container - area:cpu diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 206cc1c715..4c9316ddf1 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -22,6 +22,7 @@ body: - area:client - area:cloud - area:cloudevents + - area:cloudfoundry - area:code - area:container - area:cpu diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index 1c9cfe8ef9..e6e543158e 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -31,6 +31,7 @@ body: - area:client - area:cloud - area:cloudevents + - area:cloudfoundry - area:code - area:container - area:cpu diff --git a/Makefile b/Makefile index 3f9eba31c4..4e4a64d350 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ else SED := sed endif -TOOLS_DIR := ./internal/tools +TOOLS_DIR := $(PWD)/internal/tools MISSPELL_BINARY=bin/misspell MISSPELL = $(TOOLS_DIR)/$(MISSPELL_BINARY) @@ -150,7 +150,7 @@ table-check: --mount 'type=bind,source=$(PWD)/model,target=/home/weaver/source,readonly' \ --mount 'type=bind,source=$(PWD)/docs,target=/home/weaver/target,readonly' \ $(WEAVER_CONTAINER) registry update-markdown \ - --registry=/home/weaver/target \ + --registry=/home/weaver/source \ --attribute-registry-base-url=/docs/attributes-registry \ --templates=/home/weaver/templates \ --target=markdown \ diff --git a/dependencies.Dockerfile b/dependencies.Dockerfile index 3abc7b7c13..9423ce0749 100644 --- a/dependencies.Dockerfile +++ b/dependencies.Dockerfile @@ -3,7 +3,7 @@ # Dependabot can keep this file up to date with latest containers. # Weaver is used to generate markdown docs, and enforce policies on the model. -FROM otel/weaver:v0.9.2 AS weaver +FROM otel/weaver:v0.10.0 AS weaver # OPA is used to test policies enforced by weaver. FROM openpolicyagent/opa:0.68.0 AS opa diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index b5688cac23..35356a67cb 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -41,6 +41,7 @@ Currently, the following namespaces exist: - [Client](client.md) - [Cloud](cloud.md) - [CloudEvents](cloudevents.md) +- [CloudFoundry](cloudfoundry.md) - [Code](code.md) - [Container](container.md) - [CPU](cpu.md) diff --git a/docs/attributes-registry/cloudfoundry.md b/docs/attributes-registry/cloudfoundry.md new file mode 100644 index 0000000000..26074805e8 --- /dev/null +++ b/docs/attributes-registry/cloudfoundry.md @@ -0,0 +1,84 @@ + + + + + +# CloudFoundry + +## CloudFoundry Attributes + +CloudFoundry resource attributes. + +| Attribute | Type | Description | Examples | Stability | +| --------------------------------- | ------ | ------------------------------------------------------------------------------ | -------------------------------------- | ---------------------------------------------------------------- | +| `cloudfoundry.app.id` | string | The guid of the application. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.app.instance.id` | string | The index of the application instance. 0 when just one instance is active. [2] | `0`; `1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.app.name` | string | The name of the application. [3] | `my-app-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.org.id` | string | The guid of the CloudFoundry org the application is running in. [4] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.org.name` | string | The name of the CloudFoundry organization the app is running in. [5] | `my-org-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.process.id` | string | The UID identifying the process. [6] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.process.type` | string | The type of process. [7] | `web` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.space.id` | string | The guid of the CloudFoundry space the application is running in. [8] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.space.name` | string | The name of the CloudFoundry space the application is running in. [9] | `my-space-name` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.system.id` | string | A guid or another name describing the event source. [10] | `cf/gorouter` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `cloudfoundry.system.instance.id` | string | A guid describing the concrete instance of the event source. [11] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_id`. This is the same value as +reported by `cf app --guid`. + +**[2]:** CloudFoundry defines the `instance_id` in the [Loggegator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the application instance index for applications +deployed on the runtime. + +Application instrumentation should use the value from environment +variable `CF_INSTANCE_INDEX`. + +**[3]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_name`. This is the same value +as reported by `cf apps`. + +**[4]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_id`. This is the same value as +reported by `cf org --guid`. + +**[5]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_name`. This is the same value as +reported by `cf orgs`. + +**[6]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to +`VCAP_APPLICATION.app_id` for applications deployed to the runtime. +For system components, this could be the actual PID. + +**[7]:** CloudFoundry applications can consist of multiple jobs. Usually the +main process will be of type `web`. There can be additional background +tasks or side-cars with different process types. + +**[8]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_id`. This is the same value as +reported by `cf space --guid`. + +**[9]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_name`. This is the same value as +reported by `cf spaces`. + +**[10]:** CloudFoundry defines the `source_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the component name, e.g. "gorouter", for +CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.id` should be set to +`spec.deployment/spec.name`. + +**[11]:** CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the vm id for CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.instance.id` should be set to `spec.id`. diff --git a/docs/attributes-registry/container.md b/docs/attributes-registry/container.md index 187f973818..f1606c3160 100644 --- a/docs/attributes-registry/container.md +++ b/docs/attributes-registry/container.md @@ -16,12 +16,14 @@ 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.command_args` | string[] | All the command arguments (including the command/executable itself) run by the container. | `["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. | `otelcontribcol --config config.yaml` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.csi.plugin.name` | string | The name of the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin used by the volume. [2] | `pd.csi.storage.gke.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `container.csi.volume.id` | string | The unique volume ID returned by the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin. [3] | `projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk` | ![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/containers/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.id` | string | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. [4] | `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.repo_digests` | string[] | Repo digests of the container image as provided by the container runtime. [5] | `["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) | @@ -29,11 +31,15 @@ A container instance. **[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. +**[2]:** This can sometimes be referred to as a "driver" in CSI implementations. This should represent the `name` field of the GetPluginInfo RPC. + +**[3]:** This can sometimes be referred to as a "volume handle" in CSI implementations. This should represent the `Volume.volume_id` field in CSI spec. + +**[4]:** 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 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. +**[5]:** [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. ## Deprecated Container Attributes diff --git a/docs/attributes-registry/db.md b/docs/attributes-registry/db.md index 5f869e9c57..4e525bc163 100644 --- a/docs/attributes-registry/db.md +++ b/docs/attributes-registry/db.md @@ -27,7 +27,8 @@ This group defines the attributes used to describe telemetry in the context of d | `db.operation.name` | string | The name of the operation or command being executed. [4] | `findAndModify`; `HMSET`; `SELECT` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.parameter.` | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [5] | `someval`; `55` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `db.query.text` | string | The database query being executed. [6] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `db.system` | string | The database management system (DBMS) product as identified by the client instrumentation. [7] | `other_sql`; `adabas`; `cache` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.response.status_code` | string | Database response status code. [7] | `102`; `ORA-17002`; `08P01`; `404` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.system` | string | The database management system (DBMS) product as identified by the client instrumentation. [8] | `other_sql`; `adabas`; `cache` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. @@ -50,7 +51,10 @@ If a parameter has no name and instead is referenced only by index, then `` For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[7]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. +**[7]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. + +**[8]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. `db.client.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. @@ -158,7 +162,6 @@ This group defines attributes for Azure Cosmos DB. | `db.cosmosdb.operation_type` | string | Cosmos DB Operation Type. | `batch`; `create`; `delete` | ![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. @@ -195,9 +198,9 @@ This group defines attributes for Elasticsearch. | Attribute | Type | Description | Examples | Stability | | ----------------------------------- | ------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | `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. [8] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `db.elasticsearch.path_parts.` | string | A dynamic value in the url path. [9] | `db.elasticsearch.path_parts.index=test-index`; `db.elasticsearch.path_parts.doc_id=123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[8]:** 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]:** 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 Database Attributes @@ -208,6 +211,7 @@ This group defines attributes for Elasticsearch. | `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.cosmosdb.status_code` | int | Deprecated, use `db.response.status_code` instead. | `200`; `201` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.response.status_code`. | | `db.elasticsearch.cluster.name` | string | Deprecated, use `db.namespace` instead. | `e9106fc68e3044f0b1475b04bf4ffd5f` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `db.namespace`. | | `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. | diff --git a/docs/attributes-registry/file.md b/docs/attributes-registry/file.md index eb9a4140dc..b8cfc67b22 100644 --- a/docs/attributes-registry/file.md +++ b/docs/attributes-registry/file.md @@ -10,12 +10,38 @@ 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"). +| Attribute | Type | Description | Examples | Stability | +| -------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------- | +| `file.accessed` | string | Time when the file was last accessed, in ISO 8601 format. [1] | `2021-01-01T12:00:00Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.attributes` | string[] | Array of file attributes. [2] | `["readonly", "hidden"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.changed` | string | Time when the file attributes or metadata was last changed, in ISO 8601 format. [3] | `2021-01-01T12:00:00Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.created` | string | Time when the file was created, in ISO 8601 format. [4] | `2021-01-01T12:00:00Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `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. [5] | `png`; `gz` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.fork_name` | string | Name of the fork. A fork is additional data associated with a filesystem object. [6] | `Zone.Identifer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.group.id` | string | Primary Group ID (GID) of the file. | `1000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.group.name` | string | Primary group name of the file. | `users` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.inode` | string | Inode representing the file in the filesystem. | `256383` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.mode` | string | Mode of the file in octal representation. | `0640` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.modified` | string | Time when the file content was last modified, in ISO 8601 format. | `2021-01-01T12:00:00Z` | ![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.owner.id` | string | The user ID (UID) or security identifier (SID) of the file owner. | `1000` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `file.owner.name` | string | Username of the file owner. | `root` | ![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) | +| `file.symbolic_link.target_path` | string | Path to the target of a symbolic link. [7] | `/usr/bin/python3` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + +**[2]:** Attributes names depend on the OS or file system. Here’s a non-exhaustive list of values expected for this attribute: `archive`, `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`, `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`, `write`. + +**[3]:** `file.changed` captures the time when any of the file's properties or attributes (including the content) are changed, while `file.modified` captures the timestamp when the file content is modified. + +**[4]:** This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + +**[5]:** When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). + +**[6]:** On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. +On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. An ADS is typically of the form: C:\path\to\filename.extension:some_fork_name, and some_fork_name is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. + +**[7]:** This attribute is only applicable to symbolic links. diff --git a/docs/attributes-registry/messaging.md b/docs/attributes-registry/messaging.md index 47fff29b16..396c632efc 100644 --- a/docs/attributes-registry/messaging.md +++ b/docs/attributes-registry/messaging.md @@ -180,15 +180,15 @@ This group describes attributes specific to Azure Service Bus. Describes deprecated messaging attributes. -| Attribute | Type | Description | Examples | Stability | -| ---------------------------------------------------- | ------- | ----------------------------------------------------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `messaging.client_id` | string | Deprecated, use `messaging.client.id` instead. | `client-5`; `myhost@8742@s8083jm` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.client.id`. | -| `messaging.destination_publish.anonymous` | boolean | Deprecated, no replacement at this time. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | -| `messaging.destination_publish.name` | string | Deprecated, no replacement at this time. | `MyQueue`; `MyTopic` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | -| `messaging.eventhubs.consumer.group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `$Default` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name`. | -| `messaging.kafka.consumer.group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `my-group` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name`. | -| `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.message.offset` | int | Deprecated, use `messaging.kafka.offset` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.kafka.offset`. | -| `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.rocketmq.client_group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `myConsumerGroup` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name` on the consumer spans. No replacement for producer spans. | -| `messaging.servicebus.destination.subscription_name` | string | Deprecated, use `messaging.servicebus.destination.subscription_name` instead. | `subscription-a` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.servicebus.destination.subscription_name`. | +| Attribute | Type | Description | Examples | Stability | +| ---------------------------------------------------- | ------- | ------------------------------------------------------------------ | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `messaging.client_id` | string | Deprecated, use `messaging.client.id` instead. | `client-5`; `myhost@8742@s8083jm` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.client.id`. | +| `messaging.destination_publish.anonymous` | boolean | Deprecated, no replacement at this time. | | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | +| `messaging.destination_publish.name` | string | Deprecated, no replacement at this time. | `MyQueue`; `MyTopic` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
No replacement at this time. | +| `messaging.eventhubs.consumer.group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `$Default` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name`. | +| `messaging.kafka.consumer.group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `my-group` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name`. | +| `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.message.offset` | int | Deprecated, use `messaging.kafka.offset` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.kafka.offset`. | +| `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.rocketmq.client_group` | string | Deprecated, use `messaging.consumer.group.name` instead. | `myConsumerGroup` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.consumer.group.name` on the consumer spans. No replacement for producer spans. | +| `messaging.servicebus.destination.subscription_name` | string | Deprecated, use `messaging.destination.subscription.name` instead. | `subscription-a` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `messaging.destination.subscription.name`. | diff --git a/docs/database/cassandra.md b/docs/database/cassandra.md index 18940ece55..6d6142af9b 100644 --- a/docs/database/cassandra.md +++ b/docs/database/cassandra.md @@ -24,19 +24,20 @@ The Semantic Conventions for [Cassandra](https://cassandra.apache.org/) extend a | [`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.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [4] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [5] | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | [Cassandra protocol error code](https://github.com/apache/cassandra/blob/cassandra-5.0/doc/native_protocol_v5.spec) represented as a string. [6] | `102`; `40020` | `Conditionally Required` [7] | ![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. [8] | `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. [9] | `80`; `8080`; `443` | `Conditionally Required` [10] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`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) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![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. [11] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [11] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [12] | ![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. [13] | `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. [12] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [14] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [15] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. @@ -52,23 +53,30 @@ For batch operations, if the individual operations are known to have the same op **[5]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[6]:** 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]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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. +**[7]:** If the operation failed and status code is available. -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[8]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[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]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[11]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[12]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). -**[11]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[13]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[12]:** 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. +**[14]:** 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. -**[13]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[15]:** 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. diff --git a/docs/database/cosmosdb.md b/docs/database/cosmosdb.md index 1200fc7ee8..c663a9ad95 100644 --- a/docs/database/cosmosdb.md +++ b/docs/database/cosmosdb.md @@ -28,19 +28,19 @@ Cosmos DB instrumentation includes call-level (public API) surface spans and net | [`db.cosmosdb.connection_mode`](/docs/attributes-registry/db.md) | string | Cosmos client connection mode. | `gateway`; `direct` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`db.cosmosdb.operation_type`](/docs/attributes-registry/db.md) | string | Cosmos DB Operation Type. | `batch`; `create`; `delete` | `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.0` | `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.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. | `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. [3] | `create_item`; `query_items`; `read_item` | `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` If not default (443). | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`az.namespace`](/docs/attributes-registry/azure.md) | string | [Azure Resource Provider Namespace](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) as recognized by the client. [7] | `Microsoft.DocumentDB` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | Cosmos DB status code. [5] | `200`; `201` | `Conditionally Required` if response was received | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` If not default (443). | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`az.namespace`](/docs/attributes-registry/azure.md) | string | [Azure Resource Provider Namespace](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) as recognized by the client. [8] | `Microsoft.DocumentDB` | `Recommended` | ![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) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [8] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`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) | -| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [11] | `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.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`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) | +| [`user_agent.original`](/docs/attributes-registry/user-agent.md) | string | Full user-agent string is generated by Cosmos DB SDK [12] | `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.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. @@ -172,25 +172,30 @@ additional values when introducing new operations. **[4]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[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. +**[5]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[7]:** When `az.namespace` attribute is populated, it MUST be set to `Microsoft.DocumentDB` for all operations performed by Cosmos DB client. +**[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]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[8]:** When `az.namespace` attribute is populated, it MUST be set to `Microsoft.DocumentDB` for all operations performed by Cosmos DB client. + +**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[9]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). -**[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. +**[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. -**[11]:** 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. +**[12]:** 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". -**[12]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[13]:** 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. diff --git a/docs/database/couchdb.md b/docs/database/couchdb.md index 6e2bf13444..4544c2946d 100644 --- a/docs/database/couchdb.md +++ b/docs/database/couchdb.md @@ -23,21 +23,29 @@ The Semantic Conventions for [CouchDB](https://couchdb.apache.org/) extend and o |---|---|---|---|---|---| | [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the database, fully qualified within the server address and port. | `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 HTTP method + the target REST route. [1] | `GET /{db}/{docid}` | `Conditionally Required` [2] | ![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. [3] | `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. [4] | `80`; `8080`; `443` | `Conditionally Required` [5] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | The HTTP response code returned by the Couch DB. [3] | `200`; `201`; `429` | `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) | +| [`server.address`](/docs/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]:** 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. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[3]:** 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. +**[3]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** If response was received and the HTTP response code is available. -**[5]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[5]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[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. +**[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. + +**[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. diff --git a/docs/database/database-metrics.md b/docs/database/database-metrics.md index 9178b35f77..af571e11e1 100644 --- a/docs/database/database-metrics.md +++ b/docs/database/database-metrics.md @@ -91,11 +91,12 @@ of `[ 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10 ]`. | [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [2] | `public.users`; `customers` | `Conditionally Required` [3] | ![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. [4] | `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. [5] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [6] | ![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. [7] | `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. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![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. [10] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | Database response status code. [7] | `102`; `ORA-17002`; `08P01`; `404` | `Conditionally Required` [8] | ![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. [9] | `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. [10] | `80`; `8080`; `443` | `Conditionally Required` [11] | ![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. [12] | `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. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. @@ -115,16 +116,23 @@ For batch operations, if the individual operations are known to have the same op **[6]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[7]:** 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. +**[7]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** If the operation failed and status code is available. -**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[9]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[10]:** 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. +**[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. + +**[11]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[12]:** 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. -**[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. +**[13]:** 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/database/database-spans.md b/docs/database/database-spans.md index ab5a1b334b..5496681ee5 100644 --- a/docs/database/database-spans.md +++ b/docs/database/database-spans.md @@ -94,13 +94,14 @@ These attributes will usually be the same for all operations performed over the | [`db.collection.name`](/docs/attributes-registry/db.md) | string | The name of a collection (table, container) within the database. [2] | `public.users`; `customers` | `Conditionally Required` [3] | ![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. [4] | `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. [5] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [6] | ![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. [7] | `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. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [10] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [11] | ![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. [12] | `10.1.2.80`; `/tmp/my.sock` | `Recommended` If applicable for this database system. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | Database response status code. [7] | `102`; `ORA-17002`; `08P01`; `404` | `Conditionally Required` [8] | ![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. [9] | `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. [10] | `80`; `8080`; `443` | `Conditionally Required` [11] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [12] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [13] | ![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. [14] | `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. [13] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [14] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [15] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [16] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the instrumentation's best knowledge. @@ -120,24 +121,31 @@ For batch operations, if the individual operations are known to have the same op **[6]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[7]:** 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. +**[7]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** If the operation failed and status code is available. -**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[9]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[10]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[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. + +**[11]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[12]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[11]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[13]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). -**[12]:** 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. +**[14]:** 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. -**[13]:** 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. +**[15]:** 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. -**[14]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[16]:** 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. diff --git a/docs/database/elasticsearch.md b/docs/database/elasticsearch.md index 3fc7cae64c..ab338db007 100644 --- a/docs/database/elasticsearch.md +++ b/docs/database/elasticsearch.md @@ -29,13 +29,14 @@ The **span name** follows the [general database span name guidelines](database-s | [`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) | -| [`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.collection.name`](/docs/attributes-registry/db.md) | string | The index or data stream against which the query is executed. [8] | `my_index`; `index1, index2` | `Recommended` | ![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. [9] | `instance-0000000001` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the Elasticsearch cluster which the client connects to. [10] | `customers`; `test.users` | `Recommended` | ![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. [11] | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [12] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | The HTTP response code returned by the Elasticsearch cluster. [5] | `200`; `201`; `429` | `Conditionally Required` If response was received. | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.collection.name`](/docs/attributes-registry/db.md) | string | The index or data stream against which the query is executed. [9] | `my_index`; `index1, index2` | `Recommended` | ![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. [10] | `instance-0000000001` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.namespace`](/docs/attributes-registry/db.md) | string | The name of the Elasticsearch cluster which the client connects to. [11] | `customers`; `test.users` | `Recommended` | ![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. [12] | `"{\"query\":{\"term\":{\"user.id\":\"kimchy\"}}}"` | `Recommended` [13] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [14] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** The `db.operation.name` SHOULD match the endpoint identifier provided in the request (see the [Elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json)). @@ -60,25 +61,30 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original **[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. -**[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. +**[5]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[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]:** The query may target multiple indices or data streams, in which case it SHOULD be a comma separated list of those. If the query doesn't target a specific index, this field MUST NOT be set. +**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. -**[9]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. +**[9]:** The query may target multiple indices or data streams, in which case it SHOULD be a comma separated list of those. If the query doesn't target a specific index, this field MUST NOT be set. -**[10]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. +**[10]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. -**[11]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[11]:** When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. + +**[12]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[12]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. +**[13]:** Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information. -**[13]:** 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. +**[14]:** 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/database/hbase.md b/docs/database/hbase.md index c6cac4340f..fdb4fd65e1 100644 --- a/docs/database/hbase.md +++ b/docs/database/hbase.md @@ -24,9 +24,10 @@ The Semantic Conventions for [HBase](https://hbase.apache.org/) extend and overr | [`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) | | [`db.operation.name`](/docs/attributes-registry/db.md) | string | The name of the operation or command being executed. [3] | `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) | -| [`server.address`](/docs/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) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | Protocol-specific response code recorded as string. [5] | `200`; `409`; `14` | `Conditionally Required` If response was received. | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![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 table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. @@ -38,13 +39,18 @@ For batch operations, if the individual operations are known to have the same op **[4]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[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. +**[5]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[7]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[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]:** 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]:** 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.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. diff --git a/docs/database/mongodb.md b/docs/database/mongodb.md index 6063a4678a..6bb7814742 100644 --- a/docs/database/mongodb.md +++ b/docs/database/mongodb.md @@ -24,9 +24,10 @@ The Semantic Conventions for [MongoDB](https://www.mongodb.com/) extend and over | [`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. | `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. [2] | `findAndModify`; `getMore`; `update` | `Conditionally Required` [3] | ![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. [4] | `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. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/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.response.status_code`](/docs/attributes-registry/db.md) | string | [MongoDB error code](https://www.mongodb.com/docs/manual/reference/error-codes/) represented as a string. [4] | `36`; `11602` | `Conditionally Required` [5] | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![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]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. @@ -36,13 +37,20 @@ For batch operations, if the individual operations are known to have the same co **[3]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[4]:** 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. +**[4]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** If the operation failed and error code is available. -**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[6]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[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]:** 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. + +**[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. diff --git a/docs/database/mssql.md b/docs/database/mssql.md index 75ba20ccdf..ecb59c4654 100644 --- a/docs/database/mssql.md +++ b/docs/database/mssql.md @@ -24,11 +24,12 @@ The Semantic Conventions for the *Microsoft SQL Server* extend and override the | [`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) | -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`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) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | [Microsoft SQL Server error](https://learn.microsoft.com/sql/relational-databases/errors-events/database-engine-events-and-errors) number represented as a string. [6] | `102`; `40020` | `Conditionally Required` If response has ended with warning or an error. | ![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. [7] | `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. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [10] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [12] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. @@ -44,21 +45,25 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[5]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[6]:** 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]:** Microsoft SQL Server does not report SQLSTATE. -**[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. +**[7]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[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]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[9]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[10]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[11]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). -**[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. +**[12]:** 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. -**[12]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[13]:** 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. diff --git a/docs/database/redis.md b/docs/database/redis.md index f6441b7d8c..3289822458 100644 --- a/docs/database/redis.md +++ b/docs/database/redis.md @@ -23,13 +23,14 @@ The Semantic Conventions for [Redis](https://redis.com/) extend and override the |---|---|---|---|---|---| | [`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) (captured as a string). [1] | `0`; `1`; `15` | `Conditionally Required` If and only if it can be captured reliably. | ![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. [2] | `findAndModify`; `HMSET`; `SELECT` | `Conditionally Required` [3] | ![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. [4] | `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. [5] | `80`; `8080`; `443` | `Conditionally Required` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [7] | `HMSET myhash field1 'Hello' field2 'World'` | `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` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | The Redis [simple error](https://redis.io/docs/latest/develop/reference/protocol-spec/#simple-errors) prefix. [4] | `ERR`; `WRONGTYPE`; `CLUSTERDOWN` | `Conditionally Required` [5] | ![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. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The full syntax of the Redis CLI command. [9] | `HMSET myhash field1 'Hello' field2 'World'` | `Recommended` [10] | ![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. [11] | `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. [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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [11] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [12] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[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. @@ -41,22 +42,29 @@ For batch operations, if the individual operations are known to have the same op **[3]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[4]:** 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. +**[4]:** The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -**[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]:** If the operation failed and status code is available. -**[6]:** If using a port other than the default port for this DBMS and if `server.address` is set. +**[6]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. -**[7]:** 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`. +**[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]:** Non-parameterized query text SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data, e.g. by redacting all literal values present in the query text. +**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. + +**[9]:** 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`. + +**[10]:** Non-parameterized query text SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data, e.g. by redacting all literal values present in the query text. Parameterized query text SHOULD be collected by default (the query parameter values themselves are opt-in, see [`db.query.parameter.`](../../docs/attributes-registry/db.md)). -**[9]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. +**[11]:** If a database operation involved multiple network calls (for example retries), the address of the last contacted node SHOULD be used. -**[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. +**[12]:** 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. -**[11]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[13]:** 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. diff --git a/docs/database/sql.md b/docs/database/sql.md index bca96789ce..fa3fbdb71e 100644 --- a/docs/database/sql.md +++ b/docs/database/sql.md @@ -48,11 +48,12 @@ Instrumentations applied to generic SQL drivers SHOULD adhere to SQL semantic co | [`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) | -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [6] | `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. [7] | `80`; `8080`; `443` | `Conditionally Required` [8] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [9] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`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) | -| [`db.query.parameter.`](/docs/attributes-registry/db.md) | string | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [12] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`db.response.status_code`](/docs/attributes-registry/db.md) | string | Database response code recorded as string. [6] | `ORA-17027`; `1052`; `2201B` | `Conditionally Required` If response has ended with warning or an error. | ![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. [7] | `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. [8] | `80`; `8080`; `443` | `Conditionally Required` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`db.query.text`](/docs/attributes-registry/db.md) | string | The database query being executed. [10] | `SELECT * FROM wuser_table where username = ?`; `SET mykey "WuValue"` | `Recommended` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`server.address`](/docs/attributes-registry/server.md) | string | Name of the database host. [12] | `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 | A query parameter used in `db.query.text`, with `` being the parameter name, and the attribute value being a string representation of the parameter value. [13] | `someval`; `55` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. @@ -85,21 +86,59 @@ In the case of `EXEC`, this SHOULD be the stored procedure name that is being ex **[5]:** If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query. -**[6]:** 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]:** SQL defines [SQLSTATE](https://wikipedia.org/wiki/SQLSTATE) as a database +return code which is adopted by some database systems like PostgreSQL. +See [PostgreSQL error codes](https://www.postgresql.org/docs/current/errcodes-appendix.html) +for the details. -**[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. +Other systems like MySQL, Oracle, or MS SQL Server define vendor-specific +error codes. Database SQL drivers usually provide access to both properties. +For example, in Java, the [`SQLException`](https://docs.oracle.com/javase/8/docs/api/java/sql/SQLException.html) +class reports them with `getSQLState()` and `getErrorCode()` methods. -**[8]:** If using a port other than the default port for this DBMS and if `server.address` is set. +Instrumentations SHOULD populate the `db.response.status_code` with the +the most specific code available to them. -**[9]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +Here's a non-exhaustive list of databases that report vendor-specific +codes with granularity higher than SQLSTATE (or don't report SQLSTATE +at all): + +- [DB2 SQL codes](https://www.ibm.com/docs/db2-for-zos/12?topic=codes-sql). +- [Maria DB error codes](https://mariadb.com/kb/en/mariadb-error-code-reference/) +- [Microsoft SQL Server errors](https://docs.microsoft.com/sql/relational-databases/errors-events/database-engine-events-and-errors) +- [MySQL error codes](https://dev.mysql.com/doc/mysql-errors/9.0/en/error-reference-introduction.html) +- [Oracle error codes](https://docs.oracle.com/cd/B28359_01/server.111/b28278/toc.htm) +- [SQLite result codes](https://www.sqlite.org/rescode.html) + +These systems SHOULD set the `db.response.status_code` to a +known vendor-specific error code. If only SQLSTATE is available, +it SHOULD be used. + +When multiple error codes are available and specificity is unclear, +instrumentation SHOULD set the `db.response.status_code` to the +concatenated string of all codes with '/' used as a separator. + +For example, generic DB instrumentation that detected an error and has +SQLSTATE `"42000"` and vendor-specific `1071` should set +`db.response.status_code` to `"42000/1071"`." + +**[7]:** The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, or the canonical name of exception that occurred. +When using canonical exception type name, instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original exception is wrapped into a generic one, the original exception SHOULD be preferred. +Instrumentations SHOULD document how `error.type` is populated. + +**[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. + +**[10]:** For sanitization see [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -**[10]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). +**[11]:** SHOULD be collected by default only if there is sanitization that excludes sensitive information. See [Sanitization of `db.query.text`](../../docs/database/database-spans.md#sanitization-of-dbquerytext). -**[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. +**[12]:** 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. -**[12]:** Query parameters should only be captured when `db.query.text` is parameterized with placeholders. +**[13]:** 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. diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index 9e3c32abcd..5ffc36c97d 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -25,6 +25,7 @@ - [Trace structure](#trace-structure) - [Producer spans](#producer-spans) - [Consumer spans](#consumer-spans) + - [Message creation context as parent of "Process" span](#message-creation-context-as-parent-of-process-span) - [Messaging attributes](#messaging-attributes) - [Recording per-message attributes on batch operations](#recording-per-message-attributes-on-batch-operations) - [Examples](#examples) @@ -261,12 +262,56 @@ 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 "Process" or "Receive" span SHOULD link to the message's creation context. +> [!IMPORTANT] +> These conventions use spans links as the default mechanism to correlate +> producers and consumer(s) because: +> +> - It is the only consistent trace structure that can be guaranteed, +> given the many different messaging systems models available. +> +> - It is the only option to correlate producer and consumer(s) in batch scenarios +> as a span can only have a single parent. +> +> - It is the only option to correlate produce and consumer(s) when message +> consumption can happen in the scope of another ambient context such as a +> HTTP server span. + "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. +##### Message creation context as parent of "Process" span + +Exclusively for single messages scenarios, the "Process" span MAY +use the message's creation context as its parent, thus achieving a direct +parent-child relationship between producer and consumer(s). +Instrumentations SHOULD document whether they use the message creation context +as a parent for "Process" spans and MAY provide configuration options +allowing users to control this behavior. + +It is NOT RECOMMENDED to use the message creation context as the parent of "Process" +spans (by default) if processing happens in the scope of another span. + +If instrumentation use the message creation context as the parent for "Process" +spans in the scope of another valid ambient context, they SHOULD add the +ambient context as a link on the "Process" span to preserve the correlation +between message processing and that context. + +For example, a messaging broker pushes messages over HTTP to a consumer +application which has HTTP server and messaging instrumentations enabled. + +The messaging instrumentation would create the "Process" span following +one of these possible approaches: + +- "Process" span is a child of the HTTP server span context and has a link + to the message creation context. This is the default behavior. + +- "Process" span is a child of the message creation context and has two links: + one to the message creation context and another one to HTTP server span context. + This is an opt-in behavior. + ## Messaging attributes Messaging attributes are organized into the following namespaces: @@ -467,17 +512,19 @@ flowchart LR; R2[Span Process A 2] end P-. link .-R1; + P-- parent -->R1; P-. link .-R2; + P-- parent -->R2; classDef normal fill:green class P,R1,R2 normal - linkStyle 0,1 color:green,stroke:green + linkStyle 0,1,2,3 color:green,stroke:green ``` | Field or Attribute | Span Publish A | Span Process A 1| Span Process A 2 | |-|-|-|-| | Span name | `publish T` | `consume T` | `consume T` | -| Parent | | | | +| Parent (optional) | | `publish T` | `publish T` | | Links | | `publish T` | `publish T` | | SpanKind | `PRODUCER` | `CONSUMER` | `CONSUMER` | | `server.address` | `"ms"` | `"ms"` | `"ms"` | diff --git a/docs/resource/README.md b/docs/resource/README.md index ca2387cb52..43b9abe51a 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -292,6 +292,7 @@ Attributes defining a running environment (e.g. Operating System, Cloud, Data Ce - Deployment: - [Deployment Environment](./deployment-environment.md) - [Kubernetes](./k8s.md) + - [CloudFoundry](./cloudfoundry.md) - [Browser](./browser.md) ## Version attributes diff --git a/docs/resource/cloudfoundry.md b/docs/resource/cloudfoundry.md new file mode 100644 index 0000000000..7a6f04bc29 --- /dev/null +++ b/docs/resource/cloudfoundry.md @@ -0,0 +1,219 @@ +# CloudFoundry + +**Status**: [Experimental][DocumentStatus] + +Useful resources to understand CloudFoundry metadata: + +* +* +* +* + +CloudFoundry organizes application deployments (apps) by spaces contained in +organizations (orgs). Names are unique only in their respective enclosing +entity. Ids are unique in the entire CloudFoundry installation. Different +instances of the same application are separated by an integer index. Apps can +consist of a main job and multiple tasks and side-cars, which can be +distinguished by different process attributes. + +CloudFoundry can also emit signals from system components. They use a different +approach as applications, since they are not organized into orgs and spaces. +They align with the Bosh deployment tool of CloudFoundry. + +## Organization + + + + + + + + + +**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue) + +**type:** `cloudfoundry.org` + +**Description:** The organization of the application which is monitored. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudfoundry.org.id`](/docs/attributes-registry/cloudfoundry.md) | string | The guid of the CloudFoundry org the application is running in. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudfoundry.org.name`](/docs/attributes-registry/cloudfoundry.md) | string | The name of the CloudFoundry organization the app is running in. [2] | `my-org-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_id`. This is the same value as +reported by `cf org --guid`. + +**[2]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_name`. This is the same value as +reported by `cf orgs`. + + + + + + + + + +## Space + + + + + + + + + +**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue) + +**type:** `cloudfoundry.space` + +**Description:** The space of the application which is monitored. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudfoundry.space.id`](/docs/attributes-registry/cloudfoundry.md) | string | The guid of the CloudFoundry space the application is running in. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudfoundry.space.name`](/docs/attributes-registry/cloudfoundry.md) | string | The name of the CloudFoundry space the application is running in. [2] | `my-space-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_id`. This is the same value as +reported by `cf space --guid`. + +**[2]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_name`. This is the same value as +reported by `cf spaces`. + + + + + + + + + +## Application + + + + + + + + + +**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue) + +**type:** `cloudfoundry.app` + +**Description:** The application which is monitored. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudfoundry.app.id`](/docs/attributes-registry/cloudfoundry.md) | string | The guid of the application. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudfoundry.app.name`](/docs/attributes-registry/cloudfoundry.md) | string | The name of the application. [2] | `my-app-name` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_id`. This is the same value as +reported by `cf app --guid`. + +**[2]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_name`. This is the same value +as reported by `cf apps`. + + + + + + + + + +## Process + + + + + + + + + +**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue) + +**type:** `cloudfoundry.process` + +**Description:** The process of the application which is monitored. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudfoundry.process.id`](/docs/attributes-registry/cloudfoundry.md) | string | The UID identifying the process. [1] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudfoundry.process.type`](/docs/attributes-registry/cloudfoundry.md) | string | The type of process. [2] | `web` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to +`VCAP_APPLICATION.app_id` for applications deployed to the runtime. +For system components, this could be the actual PID. + +**[2]:** CloudFoundry applications can consist of multiple jobs. Usually the +main process will be of type `web`. There can be additional background +tasks or side-cars with different process types. + + + + + + + + + +## Cloud Foundry System Component + + + + + + + + + +**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue) + +**type:** `cloudfoundry.system` + +**Description:** The system component which is monitored. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`cloudfoundry.system.id`](/docs/attributes-registry/cloudfoundry.md) | string | A guid or another name describing the event source. [1] | `cf/gorouter` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`cloudfoundry.system.instance.id`](/docs/attributes-registry/cloudfoundry.md) | string | A guid describing the concrete instance of the event source. [2] | `218fc5a9-a5f1-4b54-aa05-46717d0ab26d` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** CloudFoundry defines the `source_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the component name, e.g. "gorouter", for +CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.id` should be set to +`spec.deployment/spec.name`. + +**[2]:** CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the vm id for CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.instance.id` should be set to `spec.id`. + + + + + + + + + +[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 971e2df204..b57f2b0f36 100644 --- a/docs/resource/container.md +++ b/docs/resource/container.md @@ -26,8 +26,8 @@ | [`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) | +| [`container.command_args`](/docs/attributes-registry/container.md) | string[] | All the command arguments (including the command/executable itself) run by the container. | `["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. | `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/system/k8s-metrics.md b/docs/system/k8s-metrics.md index d5b6f0f839..42d152c65e 100644 --- a/docs/system/k8s-metrics.md +++ b/docs/system/k8s-metrics.md @@ -60,6 +60,31 @@ This metric is [recommended][MetricRecommended]. + + + + + +### Metric: `k8s.pod.memory.usage` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `k8s.pod.memory.usage` | Gauge | `By` | Memory usage of the Pod [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Total memory usage of the Pod + + + @@ -110,6 +135,31 @@ This metric is [recommended][MetricRecommended]. + + + + + +### Metric: `k8s.node.memory.usage` + +This metric is [recommended][MetricRecommended]. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | +| -------- | --------------- | ----------- | -------------- | --------- | +| `k8s.node.memory.usage` | Gauge | `By` | Memory usage of the Node [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + + +**[1]:** Total memory usage of the Node + + + diff --git a/model/cloudfoundry/registry.yaml b/model/cloudfoundry/registry.yaml new file mode 100644 index 0000000000..c360d69335 --- /dev/null +++ b/model/cloudfoundry/registry.yaml @@ -0,0 +1,135 @@ +groups: + - id: registry.cloudfoundry + type: attribute_group + brief: > + CloudFoundry resource attributes. + attributes: + - id: cloudfoundry.system.id + type: string + stability: experimental + brief: > + A guid or another name describing the event source. + note: | + CloudFoundry defines the `source_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). + It is used for logs and metrics emitted by CloudFoundry. It is + supposed to contain the component name, e.g. "gorouter", for + CloudFoundry components. + + When system components are instrumented, values from the + [Bosh spec](https://bosh.io/docs/jobs/#properties-spec) + should be used. The `system.id` should be set to + `spec.deployment/spec.name`. + examples: + - 'cf/gorouter' + - id: cloudfoundry.system.instance.id + type: string + stability: experimental + brief: > + A guid describing the concrete instance of the event source. + note: | + CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). + It is used for logs and metrics emitted by CloudFoundry. It is + supposed to contain the vm id for CloudFoundry components. + + When system components are instrumented, values from the + [Bosh spec](https://bosh.io/docs/jobs/#properties-spec) + should be used. The `system.instance.id` should be set to `spec.id`. + examples: + - '218fc5a9-a5f1-4b54-aa05-46717d0ab26d' + - id: cloudfoundry.app.name + type: string + stability: experimental + brief: > + The name of the application. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.application_name`. This is the same value + as reported by `cf apps`. + examples: ['my-app-name'] + - id: cloudfoundry.app.id + type: string + stability: experimental + brief: > + The guid of the application. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.application_id`. This is the same value as + reported by `cf app --guid`. + examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - id: cloudfoundry.app.instance.id + type: string + stability: experimental + brief: > + The index of the application instance. 0 when just one instance is active. + note: | + CloudFoundry defines the `instance_id` in the [Loggegator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). + It is used for logs and metrics emitted by CloudFoundry. It is + supposed to contain the application instance index for applications + deployed on the runtime. + + Application instrumentation should use the value from environment + variable `CF_INSTANCE_INDEX`. + examples: + - '0' + - '1' + - id: cloudfoundry.space.name + type: string + stability: experimental + brief: > + The name of the CloudFoundry space the application is running in. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.space_name`. This is the same value as + reported by `cf spaces`. + examples: ['my-space-name'] + - id: cloudfoundry.space.id + type: string + stability: experimental + brief: > + The guid of the CloudFoundry space the application is running in. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.space_id`. This is the same value as + reported by `cf space --guid`. + examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - id: cloudfoundry.org.name + type: string + stability: experimental + brief: > + The name of the CloudFoundry organization the app is running in. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.org_name`. This is the same value as + reported by `cf orgs`. + examples: ['my-org-name'] + - id: cloudfoundry.org.id + type: string + stability: experimental + brief: > + The guid of the CloudFoundry org the application is running in. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.org_id`. This is the same value as + reported by `cf org --guid`. + examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - id: cloudfoundry.process.id + type: string + stability: experimental + brief: > + The UID identifying the process. + note: | + Application instrumentation should use the value from environment + variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to + `VCAP_APPLICATION.app_id` for applications deployed to the runtime. + For system components, this could be the actual PID. + examples: ['218fc5a9-a5f1-4b54-aa05-46717d0ab26d'] + - id: cloudfoundry.process.type + type: string + stability: experimental + brief: > + The type of process. + note: | + CloudFoundry applications can consist of multiple jobs. Usually the + main process will be of type `web`. There can be additional background + tasks or side-cars with different process types. + examples: ['web'] diff --git a/model/cloudfoundry/resources.yaml b/model/cloudfoundry/resources.yaml new file mode 100644 index 0000000000..95d60abe35 --- /dev/null +++ b/model/cloudfoundry/resources.yaml @@ -0,0 +1,41 @@ +groups: + - id: cloudfoundry.system + type: resource + name: cloudfoundry.system + brief: > + The system component which is monitored. + attributes: + - ref: cloudfoundry.system.id + - ref: cloudfoundry.system.instance.id + - id: cloudfoundry.app + type: resource + name: cloudfoundry.app + brief: > + The application which is monitored. + attributes: + - ref: cloudfoundry.app.id + - ref: cloudfoundry.app.name + - id: cloudfoundry.space + type: resource + name: cloudfoundry.space + brief: > + The space of the application which is monitored. + attributes: + - ref: cloudfoundry.space.id + - ref: cloudfoundry.space.name + - id: cloudfoundry.org + type: resource + name: cloudfoundry.org + brief: > + The organization of the application which is monitored. + attributes: + - ref: cloudfoundry.org.id + - ref: cloudfoundry.org.name + - id: cloudfoundry.process + type: resource + name: cloudfoundry.process + brief: > + The process of the application which is monitored. + attributes: + - ref: cloudfoundry.process.id + - ref: cloudfoundry.process.type diff --git a/model/container/registry.yaml b/model/container/registry.yaml index 090c7bddff..e81b18187f 100644 --- a/model/container/registry.yaml +++ b/model/container/registry.yaml @@ -84,13 +84,13 @@ groups: type: string stability: experimental brief: > - The full command run by the container as a single string representing the full command. [2] + The full command run by the container as a single string representing the full command. examples: [ 'otelcontribcol --config config.yaml' ] - id: container.command_args type: string[] stability: experimental brief: > - All the command arguments (including the command/executable itself) run by the container. [2] + All the command arguments (including the command/executable itself) run by the container. examples: - [ 'otelcontribcol', '--config', 'config.yaml' ] - id: container.label @@ -99,3 +99,23 @@ groups: brief: > Container labels, `` being the label name, the value being the label value. examples: [ 'container.label.app=nginx' ] + - id: container.csi.plugin.name + type: string + stability: experimental + brief: > + The name of the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin used by the volume. + note: > + This can sometimes be referred to as a "driver" in CSI implementations. + This should represent the `name` field of the GetPluginInfo RPC. + examples: + - "pd.csi.storage.gke.io" + - id: container.csi.volume.id + type: string + stability: experimental + brief: > + The unique volume ID returned by the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin. + note: > + This can sometimes be referred to as a "volume handle" in CSI implementations. + This should represent the `Volume.volume_id` field in CSI spec. + examples: + - "projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk" diff --git a/model/database/common.yaml b/model/database/common.yaml index 3dfc31af14..72a6cdac89 100644 --- a/model/database/common.yaml +++ b/model/database/common.yaml @@ -2,6 +2,7 @@ groups: - id: attributes.db.client.minimal type: attribute_group brief: 'Database Client attributes' + stability: experimental attributes: - ref: db.operation.name requirement_level: @@ -14,10 +15,18 @@ 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.response.status_code + requirement_level: + conditionally_required: If the operation failed and status code is available. - 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. + The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client library, + or the canonical name of exception that occurred. + + When using canonical exception type name, instrumentation SHOULD do the best effort to + report the most relevant type. For example, if the original exception is wrapped into a + generic one, the original exception SHOULD be preferred. + + Instrumentations SHOULD document how `error.type` is populated. diff --git a/model/database/deprecated/registry-deprecated.yaml b/model/database/deprecated/registry-deprecated.yaml index e8fdf5d667..610aadf0ca 100644 --- a/model/database/deprecated/registry-deprecated.yaml +++ b/model/database/deprecated/registry-deprecated.yaml @@ -4,6 +4,7 @@ groups: display_name: Deprecated Database Attributes brief: > "Describes deprecated db attributes." + stability: experimental attributes: - id: db.connection_string type: string @@ -90,12 +91,19 @@ groups: brief: > Deprecated, use `db.namespace` instead. examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + - id: db.cosmosdb.status_code + type: int + stability: experimental + deprecated: 'Replaced by `db.response.status_code`.' + brief: 'Deprecated, use `db.response.status_code` instead.' + examples: [200, 201] - id: registry.db.metrics.deprecated type: attribute_group display_name: Deprecated Database Metrics brief: > "Describes deprecated db metrics attributes." + stability: experimental attributes: - id: state stability: experimental diff --git a/model/database/registry.yaml b/model/database/registry.yaml index 081e140f20..ebe1c68af5 100644 --- a/model/database/registry.yaml +++ b/model/database/registry.yaml @@ -88,6 +88,19 @@ groups: Operations are only considered batches when they contain two or more operations, and so `db.operation.batch.size` SHOULD never be `1`. examples: [2, 3, 4] + - id: db.response.status_code + type: string + stability: experimental + brief: Database response status code. + note: > + The status code returned by the database. Usually it represents an error code, + but may also represent partial success, warning, or differentiate + between various types of successful outcomes. + + Semantic conventions for individual database systems SHOULD document what + `db.response.status_code` means in the context of that system. + examples: ["102", "ORA-17002", "08P01", "404"] + - id: db.system brief: The database management system (DBMS) product as identified by the client instrumentation. note: > @@ -419,6 +432,7 @@ groups: - id: registry.db.cosmosdb type: attribute_group display_name: Azure Cosmos DB Attributes + stability: experimental brief: > This group defines attributes for Azure Cosmos DB. attributes: @@ -499,11 +513,6 @@ groups: type: int stability: experimental brief: Request payload size in bytes - - id: db.cosmosdb.status_code - type: int - stability: experimental - brief: Cosmos DB status code. - examples: [200, 201] - id: db.cosmosdb.sub_status_code type: int stability: experimental diff --git a/model/database/spans.yaml b/model/database/spans.yaml index 6e507c7fb6..10b56c8ad6 100644 --- a/model/database/spans.yaml +++ b/model/database/spans.yaml @@ -2,6 +2,7 @@ groups: - id: trace.db.common.minimal extends: attributes.db.client.minimal type: attribute_group + stability: experimental brief: This group defines the attributes used to perform database client calls. attributes: # TODO: add db.system once https://github.com/open-telemetry/build-tools/issues/192 is possible @@ -17,6 +18,7 @@ groups: - id: trace.db.common.query extends: trace.db.common.minimal type: attribute_group + stability: experimental brief: This group defines the attributes used to perform database client calls. attributes: - ref: db.query.text @@ -35,6 +37,7 @@ groups: - id: trace.db.common.query_and_collection extends: trace.db.common.minimal type: attribute_group + stability: experimental brief: This group defines the attributes used to perform database client calls. attributes: - ref: db.query.text @@ -54,6 +57,7 @@ groups: - id: trace.db.common.full type: attribute_group + stability: experimental brief: This group documents attributes that describe database call along with network information. extends: trace.db.common.query_and_collection attributes: @@ -78,15 +82,16 @@ groups: requirement_level: conditionally_required: If available. - - id: db type: span + stability: experimental brief: This span defines the attributes used to perform database client calls. span_kind: client extends: trace.db.common.full - id: db.mssql type: span + stability: experimental extends: db.sql brief: > Attributes for Microsoft SQL Server @@ -101,9 +106,17 @@ groups: For commands that switch the database, this SHOULD be set to the target database (even if the command fails). examples: ["instance1.products", "customers"] + - ref: db.response.status_code + brief: > + [Microsoft SQL Server error](https://learn.microsoft.com/sql/relational-databases/errors-events/database-engine-events-and-errors) number + represented as a string. + note: > + Microsoft SQL Server does not report SQLSTATE. + examples: ["102", "40020"] - id: db.cassandra type: span + stability: experimental extends: trace.db.common.query_and_collection brief: > Attributes for Cassandra @@ -132,8 +145,13 @@ groups: - ref: network.peer.port requirement_level: recommended: if and only if `network.peer.address` is set. + - ref: db.response.status_code + brief: > + [Cassandra protocol error code](https://github.com/apache/cassandra/blob/cassandra-5.0/doc/native_protocol_v5.spec) represented as a string. + examples: ["102", "40020"] - id: db.hbase type: span + stability: experimental extends: trace.db.common.minimal brief: > Attributes for HBase @@ -156,9 +174,15 @@ groups: note: > If table name includes the namespace, the `db.collection.name` SHOULD be set to the full table name. examples: ['mytable', 'ns:table'] - + - ref: db.response.status_code + brief: > + Protocol-specific response code recorded as string. + examples: ["200", "409", "14"] + requirement_level: + conditionally_required: If response was received. - id: db.couchdb type: span + stability: experimental extends: trace.db.common.minimal brief: > Attributes for CouchDB @@ -179,9 +203,16 @@ groups: requirement_level: conditionally_required: If available. note: "" # overriding the base note + - ref: db.response.status_code + brief: > + The HTTP response code returned by the Couch DB. + examples: ["200", "201", "429"] + requirement_level: + conditionally_required: If response was received and the HTTP response code is available. - id: db.redis type: span + stability: experimental extends: trace.db.common.query brief: > Attributes for Redis @@ -219,9 +250,14 @@ groups: - ref: network.peer.port requirement_level: recommended: if and only if `network.peer.address` is set. + - ref: db.response.status_code + brief: > + The Redis [simple error](https://redis.io/docs/latest/develop/reference/protocol-spec/#simple-errors) prefix. + examples: ["ERR", "WRONGTYPE", "CLUSTERDOWN"] - id: db.mongodb type: span + stability: experimental extends: trace.db.common.minimal brief: > Attributes for MongoDB @@ -244,9 +280,16 @@ groups: requirement_level: conditionally_required: If available. note: "" # overriding the base note + - ref: db.response.status_code + brief: > + [MongoDB error code](https://www.mongodb.com/docs/manual/reference/error-codes/) represented as a string. + requirement_level: + conditionally_required: If the operation failed and error code is available. + examples: ["36", "11602"] - id: db.elasticsearch type: span + stability: experimental extends: trace.db.common.minimal brief: > Attributes for Elasticsearch @@ -293,9 +336,15 @@ groups: - ref: db.elasticsearch.path_parts requirement_level: conditionally_required: when the url has dynamic values - + - ref: db.response.status_code + brief: > + The HTTP response code returned by the Elasticsearch cluster. + examples: ["200", "201", "429"] + requirement_level: + conditionally_required: If response was received. - id: db.sql type: span + stability: experimental extends: trace.db.common.query_and_collection brief: > Attributes for SQL databases @@ -332,8 +381,53 @@ groups: 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`. + + - ref: db.response.status_code + brief: > + Database response code recorded as string. + note: | + SQL defines [SQLSTATE](https://wikipedia.org/wiki/SQLSTATE) as a database + return code which is adopted by some database systems like PostgreSQL. + See [PostgreSQL error codes](https://www.postgresql.org/docs/current/errcodes-appendix.html) + for the details. + + Other systems like MySQL, Oracle, or MS SQL Server define vendor-specific + error codes. Database SQL drivers usually provide access to both properties. + For example, in Java, the [`SQLException`](https://docs.oracle.com/javase/8/docs/api/java/sql/SQLException.html) + class reports them with `getSQLState()` and `getErrorCode()` methods. + + Instrumentations SHOULD populate the `db.response.status_code` with the + the most specific code available to them. + + Here's a non-exhaustive list of databases that report vendor-specific + codes with granularity higher than SQLSTATE (or don't report SQLSTATE + at all): + + - [DB2 SQL codes](https://www.ibm.com/docs/db2-for-zos/12?topic=codes-sql). + - [Maria DB error codes](https://mariadb.com/kb/en/mariadb-error-code-reference/) + - [Microsoft SQL Server errors](https://docs.microsoft.com/sql/relational-databases/errors-events/database-engine-events-and-errors) + - [MySQL error codes](https://dev.mysql.com/doc/mysql-errors/9.0/en/error-reference-introduction.html) + - [Oracle error codes](https://docs.oracle.com/cd/B28359_01/server.111/b28278/toc.htm) + - [SQLite result codes](https://www.sqlite.org/rescode.html) + + These systems SHOULD set the `db.response.status_code` to a + known vendor-specific error code. If only SQLSTATE is available, + it SHOULD be used. + + When multiple error codes are available and specificity is unclear, + instrumentation SHOULD set the `db.response.status_code` to the + concatenated string of all codes with '/' used as a separator. + + For example, generic DB instrumentation that detected an error and has + SQLSTATE `"42000"` and vendor-specific `1071` should set + `db.response.status_code` to `"42000/1071"`." + + examples: ["ORA-17027", "1052", "2201B"] + requirement_level: + conditionally_required: If response has ended with warning or an error. - id: db.cosmosdb type: span + stability: experimental extends: trace.db.common.query_and_collection brief: > Attributes for Cosmos DB. @@ -367,7 +461,10 @@ groups: requirement_level: conditionally_required: if available - ref: db.cosmosdb.request_content_length - - ref: db.cosmosdb.status_code + - ref: db.response.status_code + brief: > + Cosmos DB status code. + examples: ["200", "201"] requirement_level: conditionally_required: if response was received - ref: db.cosmosdb.sub_status_code diff --git a/model/file/registry.yaml b/model/file/registry.yaml index 742f95afee..cf138ba9a3 100644 --- a/model/file/registry.yaml +++ b/model/file/registry.yaml @@ -4,6 +4,42 @@ groups: display_name: File Attributes brief: "Describes file attributes." attributes: + - id: file.accessed + type: string + brief: > + Time when the file was last accessed, in ISO 8601 format. + note: > + This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + stability: experimental + examples: ['2021-01-01T12:00:00Z'] + - id: file.attributes + type: string[] + brief: > + Array of file attributes. + note: > + Attributes names depend on the OS or file system. Here’s a non-exhaustive list of values expected for this + attribute: `archive`, `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`, `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`, `write`. + stability: experimental + examples: + - ['readonly', 'hidden'] + - id: file.created + type: string + brief: > + Time when the file was created, in ISO 8601 format. + note: > + This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + stability: experimental + examples: ['2021-01-01T12:00:00Z'] + - id: file.changed + type: string + brief: > + Time when the file attributes or metadata was last changed, in ISO 8601 format. + note: > + `file.changed` captures the time when any of the file's properties or attributes + (including the content) are changed, while `file.modified` captures the timestamp + when the file content is modified. + stability: experimental + examples: ['2021-01-01T12:00:00Z'] - id: file.directory type: string brief: > @@ -19,12 +55,69 @@ groups: note: > When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). + - id: file.fork_name + type: string + brief: > + Name of the fork. A fork is additional data associated with a filesystem object. + note: > + On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at + least one fork for the data portion, and additional forks may exist. + + On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is + just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. + An ADS is typically of the form: C:\path\to\filename.extension:some_fork_name, and some_fork_name is the + value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` + should populate `file.extension`. The full path, `file.path`, will include the fork name. + stability: experimental + examples: ['Zone.Identifer'] + - id: file.group.id + type: string + brief: > + Primary Group ID (GID) of the file. + stability: experimental + examples: ["1000"] + - id: file.group.name + type: string + brief: > + Primary group name of the file. + stability: experimental + examples: ['users'] + - id: file.inode + type: string + brief: > + Inode representing the file in the filesystem. + stability: experimental + examples: ['256383'] + - id: file.mode + type: string + brief: > + Mode of the file in octal representation. + stability: experimental + examples: ['0640'] + - id: file.modified + type: string + brief: > + Time when the file content was last modified, in ISO 8601 format. + stability: experimental + examples: ['2021-01-01T12:00:00Z'] - id: file.name type: string brief: > Name of the file including the extension, without the directory. stability: experimental examples: ['example.png'] + - id: file.owner.id + type: string + brief: > + The user ID (UID) or security identifier (SID) of the file owner. + stability: experimental + examples: ["1000"] + - id: file.owner.name + type: string + brief: > + Username of the file owner. + stability: experimental + examples: ['root'] - id: file.path type: string brief: > @@ -36,3 +129,11 @@ groups: brief: > File size in bytes. stability: experimental + - id: file.symbolic_link.target_path + type: string + brief: > + Path to the target of a symbolic link. + note: > + This attribute is only applicable to symbolic links. + stability: experimental + examples: ['/usr/bin/python3'] diff --git a/model/k8s/metrics.yaml b/model/k8s/metrics.yaml index b11a6f68d4..a09cfee780 100644 --- a/model/k8s/metrics.yaml +++ b/model/k8s/metrics.yaml @@ -19,6 +19,17 @@ groups: instrument: gauge unit: "{cpu}" + # k8s.pod.memory.* metrics + - id: metric.k8s.pod.memory.usage + type: metric + metric_name: k8s.pod.memory.usage + stability: experimental + brief: "Memory usage of the Pod" + note: > + Total memory usage of the Pod + instrument: gauge + unit: "By" + # k8s.node.cpu.* metrics - id: metric.k8s.node.cpu.time type: metric @@ -38,3 +49,14 @@ groups: CPU usage of the specific Node on all available CPU cores, averaged over the sample window instrument: gauge unit: "{cpu}" + + # k8s.node.memory.* metrics + - id: metric.k8s.node.memory.usage + type: metric + metric_name: k8s.node.memory.usage + stability: experimental + brief: "Memory usage of the Node" + note: > + Total memory usage of the Node + instrument: gauge + unit: "By" diff --git a/model/messaging/deprecated/registry-deprecated.yaml b/model/messaging/deprecated/registry-deprecated.yaml index 02c145f2ce..d5d7305429 100644 --- a/model/messaging/deprecated/registry-deprecated.yaml +++ b/model/messaging/deprecated/registry-deprecated.yaml @@ -49,10 +49,10 @@ groups: - id: messaging.servicebus.destination.subscription_name type: string brief: > - Deprecated, use `messaging.servicebus.destination.subscription_name` instead. + Deprecated, use `messaging.destination.subscription.name` instead. stability: experimental examples: 'subscription-a' - deprecated: "Replaced by `messaging.servicebus.destination.subscription_name`." + deprecated: "Replaced by `messaging.destination.subscription.name`." - id: messaging.kafka.message.offset type: int stability: experimental diff --git a/package.json b/package.json index dc7296fb15..e62765487f 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "markdown-link-check": "3.11.2", "markdown-toc": "^1.2.0", "markdownlint": "0.35.0", - "markdownlint-cli": "0.41.0", + "markdownlint-cli": "0.42.0", "prettier": "^3.0.0", "through2": "^4.0.2" }, diff --git a/templates/registry/markdown/weaver.yaml b/templates/registry/markdown/weaver.yaml index 0570d9f9f2..104823f184 100644 --- a/templates/registry/markdown/weaver.yaml +++ b/templates/registry/markdown/weaver.yaml @@ -7,25 +7,27 @@ templates: application_mode: each acronyms: - AI - - iOS - AWS - CICD - CloudEvents + - CloudFoundry - CLR - CPU + - CSI - DynamoDB - ECS - EKS - - GraphQL - - GCP - GCE + - GCP + - GraphQL - HTTP + - iOS - JVM - NodeJS - OCI - - OTel - OpenTracing - OS + - OTel - RabbitMQ - RocketMQ - RPC