diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4453e430d9..fdb256bcf2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -52,6 +52,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 7ca04917ef..f8f8e1aa55 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -45,6 +45,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index cb66735b41..60cc97b2b5 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -54,6 +54,7 @@ body: - area:process - area:rpc - area:server + - area:service - area:source - area:thread - area:tls diff --git a/docs/attributes-registry/README.md b/docs/attributes-registry/README.md index f8fcc96414..343b0702c0 100644 --- a/docs/attributes-registry/README.md +++ b/docs/attributes-registry/README.md @@ -58,6 +58,7 @@ Currently, the following namespaces exist: * [Process](process.md) * [RPC](rpc.md) * [Server](server.md) +* [Service](service.md) * [Source](source.md) * [Thread](thread.md) * [TLS](tls.md) diff --git a/docs/attributes-registry/service.md b/docs/attributes-registry/service.md new file mode 100644 index 0000000000..9022d5ac94 --- /dev/null +++ b/docs/attributes-registry/service.md @@ -0,0 +1,46 @@ + + +# Service + +## Service Attributes + + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.name` | string | Logical name of the service. [2] | `shoppingcart` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `service.namespace` | string | A namespace for `service.name`. [3] | `Shop` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words +`service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to +distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled +service). + +Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC +4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of +this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and +SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + +UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is +needed. Similar to what can be seen in the man page for the +[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying +data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it +or not via another resource attribute. + +For applications running behind an application server (like unicorn), we do not recommend using one identifier +for all processes participating in the application. Instead, it's recommended each division (e.g. a worker +thread in unicorn) to have its own instance.id. + +It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the +service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will +likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. +However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance +for that telemetry. This is typically the case for scraping receivers, as they know the target address and +port. + +**[2]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. + +**[3]:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + \ No newline at end of file diff --git a/docs/resource/README.md b/docs/resource/README.md index 18e8e6dbb1..bcbaf2ed41 100644 --- a/docs/resource/README.md +++ b/docs/resource/README.md @@ -82,8 +82,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `service.name` | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `service.version` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.name`](../attributes-registry/service.md) | string | Logical name of the service. [1] | `shoppingcart` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`service.version`](../attributes-registry/service.md) | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1]:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. @@ -99,8 +99,8 @@ as specified in the [Resource SDK specification](https://github.com/open-telemet | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| `service.instance.id` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `service.namespace` | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.instance.id`](../attributes-registry/service.md) | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`service.namespace`](../attributes-registry/service.md) | string | A namespace for `service.name`. [2] | `Shop` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to diff --git a/model/registry/service.yaml b/model/registry/service.yaml new file mode 100644 index 0000000000..4e139da36b --- /dev/null +++ b/model/registry/service.yaml @@ -0,0 +1,71 @@ +groups: + - id: registry.service + prefix: service + type: attribute_group + brief: > + A service instance. + attributes: + - id: name + type: string + brief: > + Logical name of the service. + note: > + MUST be the same for all instances of horizontally scaled services. + If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated + with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. + If `process.executable.name` is not available, the value MUST be set to `unknown_service`. + examples: ["shoppingcart"] + stability: stable + - id: version + type: string + brief: > + The version string of the service API or implementation. The format is not defined by these conventions. + examples: ["2.0.0", "a01dbef8a"] + stability: stable + - id: namespace + type: string + stability: experimental + brief: > + A namespace for `service.name`. + note: > + A string value having a meaning that helps to distinguish a group of services, + for example the team name that owns a group of services. + `service.name` is expected to be unique within the same namespace. + If `service.namespace` is not specified in the Resource then `service.name` + is expected to be unique for all services that have no explicit namespace defined + (so the empty/unspecified namespace is simply one more valid namespace). + Zero-length namespace string is assumed equal to unspecified namespace. + examples: ["Shop"] + - id: instance.id + type: string + stability: experimental + brief: > + The string ID of the service instance. + note: | + MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words + `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to + distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + service). + + Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC + 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of + this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and + SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + + UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + needed. Similar to what can be seen in the man page for the + [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying + data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it + or not via another resource attribute. + + For applications running behind an application server (like unicorn), we do not recommend using one identifier + for all processes participating in the application. Instead, it's recommended each division (e.g. a worker + thread in unicorn) to have its own instance.id. + + It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the + service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will + likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance + for that telemetry. This is typically the case for scraping receivers, as they know the target address and + port. + examples: ["627cc493-f310-47de-96bd-71410b7dec09"] diff --git a/model/resource/service.yaml b/model/resource/service.yaml index 05b2e02698..6384246ae6 100644 --- a/model/resource/service.yaml +++ b/model/resource/service.yaml @@ -5,21 +5,6 @@ groups: brief: > A service instance. attributes: - - id: name - type: string - stability: stable + - ref: service.name requirement_level: required - brief: > - Logical name of the service. - note: > - MUST be the same for all instances of horizontally scaled services. - If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated - with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. - If `process.executable.name` is not available, the value MUST be set to `unknown_service`. - examples: ["shoppingcart"] - - id: version - type: string - stability: stable - brief: > - The version string of the service API or implementation. The format is not defined by these conventions. - examples: ["2.0.0", "a01dbef8a"] + - ref: service.version diff --git a/model/resource/service_experimental.yaml b/model/resource/service_experimental.yaml index a11a30a048..97a58f6f6e 100644 --- a/model/resource/service_experimental.yaml +++ b/model/resource/service_experimental.yaml @@ -5,50 +5,5 @@ groups: brief: > A service instance. attributes: - - id: namespace - type: string - stability: experimental - brief: > - A namespace for `service.name`. - note: > - A string value having a meaning that helps to distinguish a group of services, - for example the team name that owns a group of services. - `service.name` is expected to be unique within the same namespace. - If `service.namespace` is not specified in the Resource then `service.name` - is expected to be unique for all services that have no explicit namespace defined - (so the empty/unspecified namespace is simply one more valid namespace). - Zero-length namespace string is assumed equal to unspecified namespace. - examples: ["Shop"] - - id: instance.id - type: string - stability: experimental - brief: > - The string ID of the service instance. - note: | - MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words - `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to - distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled - service). - - Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC - 4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of - this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and - SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. - - UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is - needed. Similar to what can be seen in the man page for the - [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html) file, the underlying - data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it - or not via another resource attribute. - - For applications running behind an application server (like unicorn), we do not recommend using one identifier - for all processes participating in the application. Instead, it's recommended each division (e.g. a worker - thread in unicorn) to have its own instance.id. - - It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the - service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will - likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. - However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance - for that telemetry. This is typically the case for scraping receivers, as they know the target address and - port. - examples: ["627cc493-f310-47de-96bd-71410b7dec09"] + - ref: service.namespace + - ref: service.instance.id