diff --git a/.chloggen/fix-2880.yaml b/.chloggen/fix-2880.yaml
new file mode 100755
index 0000000000..c6a0701b63
--- /dev/null
+++ b/.chloggen/fix-2880.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: enhancement
+
+# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db)
+component: service
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: Splits `service` entity into three pieces - namespace, service and instance.
+
+# 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: [2880]
+
+# (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: |
+ The service entity is now split into three: `service.namespace`,
+ `service` and `service.instance`. Existing service attributes are
+ distributed between these three and descriptions are updated to
+ denote how to think about these concepts going forward.
diff --git a/docs/registry/attributes/service.md b/docs/registry/attributes/service.md
index a5d3f6be08..2e0b16cc94 100644
--- a/docs/registry/attributes/service.md
+++ b/docs/registry/attributes/service.md
@@ -14,7 +14,7 @@ A service instance.
| `service.instance.id` |  | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` |
| `service.name` |  | string | Logical name of the service. [2] | `shoppingcart` |
| `service.namespace` |  | string | A namespace for `service.name`. [3] | `Shop` |
-| `service.version` |  | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
+| `service.version` |  | string | The version string of the service component. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
**[1] `service.instance.id`:** 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/docs/registry/entities/README.md b/docs/registry/entities/README.md
index 9a3c0c576c..a5c6da6344 100644
--- a/docs/registry/entities/README.md
+++ b/docs/registry/entities/README.md
@@ -88,6 +88,8 @@ Currently, the following namespaces exist:
| | [process.runtime](process.md#process-runtime) |  |
| Service | | |
| | [service](service.md#service) |  |
+| | [service.instance](service.md#service-instance) |  |
+| | [service.namespace](service.md#service-namespace) |  |
| Telemetry | | |
| | [telemetry.distro](telemetry.md#telemetry-distro) |  |
| | [telemetry.sdk](telemetry.md#telemetry-sdk) |  |
diff --git a/docs/registry/entities/service.md b/docs/registry/entities/service.md
index fefd081b16..f51ea04540 100644
--- a/docs/registry/entities/service.md
+++ b/docs/registry/entities/service.md
@@ -11,17 +11,27 @@
**type:** `service`
-**Description:** A service instance.
+**Description:** A logical unit of an application or system that performs a specific function.
| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
|---|---|---|---|---|---|---|
| Identity | [`service.name`](/docs/registry/attributes/service.md) |  | `Required` | string | Logical name of the service. [1] | `shoppingcart` |
-| Identity | [`service.instance.id`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The string ID of the service instance. [2] | `627cc493-f310-47de-96bd-71410b7dec09` |
-| Identity | [`service.namespace`](/docs/registry/attributes/service.md) |  | `Recommended` | string | A namespace for `service.name`. [3] | `Shop` |
-| Description | [`service.version`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
+| Description | [`service.version`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The version string of the service component. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
**[1] `service.name`:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`.
+## Service Instance
+
+**Status:** 
+
+**type:** `service.instance`
+
+**Description:** A unique instance of a logical service.
+
+| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+|---|---|---|---|---|---|---|
+| Identity | [`service.instance.id`](/docs/registry/attributes/service.md) |  | `Required` | string | The string ID of the service instance. [2] | `627cc493-f310-47de-96bd-71410b7dec09` |
+
**[2] `service.instance.id`:** 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
@@ -49,6 +59,18 @@ However, Collectors can set the `service.instance.id` if they can unambiguously
for that telemetry. This is typically the case for scraping receivers, as they know the target address and
port.
+## Service Namespace
+
+**Status:** 
+
+**type:** `service.namespace`
+
+**Description:** Groups related services that compose a system or application under a common namespace.
+
+| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+|---|---|---|---|---|---|---|
+| Identity | [`service.namespace`](/docs/registry/attributes/service.md) |  | `Required` | string | A namespace for `service.name`. [3] | `Shop` |
+
**[3] `service.namespace`:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace.
diff --git a/docs/resource/README.md b/docs/resource/README.md
index e7af2ada1c..40927b4679 100644
--- a/docs/resource/README.md
+++ b/docs/resource/README.md
@@ -62,78 +62,14 @@ as specified in [OpenTelemetry Environment Variable Specification](https://githu
These are the attributes which MUST be provided by the SDK
as specified in the [Resource SDK specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.51.0/specification/resource/sdk.md#sdk-provided-resource-attributes):
-- [`service.name`](#service)
+- [`service.name`](service.md#service)
- [`telemetry.sdk` group](#telemetry-sdk)
## Service
-
-
-
-
-
-
-
-**Status:** 
-
-**type:** `service`
-
-**Description:** A service instance.
-| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
-|---|---|---|---|---|---|---|
-| Identity | [`service.name`](/docs/registry/attributes/service.md) |  | `Required` | string | Logical name of the service. [1] | `shoppingcart` |
-| Identity | [`service.instance.id`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The string ID of the service instance. [2] | `627cc493-f310-47de-96bd-71410b7dec09` |
-| Identity | [`service.namespace`](/docs/registry/attributes/service.md) |  | `Recommended` | string | A namespace for `service.name`. [3] | `Shop` |
-| Description | [`service.version`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The version string of the service API or implementation. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
-
-**[1] `service.name`:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`.
-
-**[2] `service.instance.id`:** 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/latest/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.
-
-**[3] `service.namespace`:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace.
-
-
-
-
-
-Note: `service.namespace` and `service.name` are not intended to be concatenated for the purpose of forming a single globally unique name for the service. For example the following 2 sets of attributes actually describe 2 different services (despite the fact that the concatenation would result in the same string):
-
-```
-# Resource attributes that describes a service.
-namespace = Company.Shop
-service.name = shoppingcart
-```
+Logical grouping of components.
-```
-# Another set of resource attributes that describe a different service.
-namespace = Company
-service.name = Shop.shoppingcart
-```
+- [Service](service.md).
## Telemetry SDK
diff --git a/docs/resource/service.md b/docs/resource/service.md
new file mode 100644
index 0000000000..96d5a1c109
--- /dev/null
+++ b/docs/resource/service.md
@@ -0,0 +1,143 @@
+
+
+# Service semantic conventions
+
+Service is a logical component of an application that produces telemetry
+data (events, metrics, spans, etc.).
+
+In modern, distributed, application architectures:
+
+- A `service.namespace` is an entire system of components designed for
+ end-users or other applications to leverage.
+- A `service` is one of the logical, distinct components that make up the
+ application, typically running multiple instances of the same container image for load balancing.
+- A `service.instance` is a distinct instance of a service component, e.g. a
+ specific kubernetes container that is part of a kubernetes deployment which
+ offers a service.
+
+For example, suppose we have a Blog site that consists of a database
+and an HTTP server which uses the database:
+
+```mermaid
+flowchart LR
+ App(("`**service.namespace**
+ blog-site`"))
+ Db["`**service.name**
+ db`"]
+ Http["`**service.name**
+ http-server`"]
+ Http1["`**service.instance.id**
+ aabcd-1231`"]
+ Http2["`**service.instance.id**
+ aabcd-1234`"]
+ Db1["`**service.instance.id**
+ db-gbgfx`"]
+ Db --> Db1
+ Http --> Http1
+ Http --> Http2
+ App --> Db
+ App --> Http
+```
+
+Here, we can see the HTTP server has two instances that may use a load-balancer
+between them. Additionally, there's a single database instance.
+
+## Service
+
+
+
+
+
+
+
+
+**Status:** 
+
+**type:** `service`
+
+**Description:** A logical unit of an application or system that performs a specific function.
+| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+|---|---|---|---|---|---|---|
+| Identity | [`service.name`](/docs/registry/attributes/service.md) |  | `Required` | string | Logical name of the service. [1] | `shoppingcart` |
+| Description | [`service.version`](/docs/registry/attributes/service.md) |  | `Recommended` | string | The version string of the service component. The format is not defined by these conventions. | `2.0.0`; `a01dbef8a` |
+
+**[1] `service.name`:** MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`.
+
+
+
+
+
+## Service Instance
+
+
+
+
+
+
+
+
+**Status:** 
+
+**type:** `service.instance`
+
+**Description:** A unique instance of a logical service.
+| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+|---|---|---|---|---|---|---|
+| Identity | [`service.instance.id`](/docs/registry/attributes/service.md) |  | `Required` | string | The string ID of the service instance. [1] | `627cc493-f310-47de-96bd-71410b7dec09` |
+
+**[1] `service.instance.id`:** 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/latest/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.
+
+
+
+
+
+## Service Namespace
+
+
+
+
+
+
+
+
+**Status:** 
+
+**type:** `service.namespace`
+
+**Description:** Groups related services that compose a system or application under a common namespace.
+| Role | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+|---|---|---|---|---|---|---|
+| Identity | [`service.namespace`](/docs/registry/attributes/service.md) |  | `Required` | string | A namespace for `service.name`. [1] | `Shop` |
+
+**[1] `service.namespace`:** A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace.
+
+
+
+
diff --git a/model/service/entities.yaml b/model/service/entities.yaml
index 319eb39eae..ef000c9a8a 100644
--- a/model/service/entities.yaml
+++ b/model/service/entities.yaml
@@ -3,7 +3,11 @@ groups:
type: entity
name: service
brief: >
- A service instance.
+ A logical unit of an application or system that performs a specific function.
+ note: >
+ A service is a logical component used in a system, product or
+ application. Examples include a microservice, a database,
+ a Kubernetes deployment.
stability: stable
attributes:
- ref: service.name
@@ -11,7 +15,29 @@ groups:
role: identifying
- ref: service.version
role: descriptive
- - ref: service.namespace
- role: identifying
+ - id: entity.service.instance
+ type: entity
+ name: service.instance
+ brief: >
+ A unique instance of a logical service.
+ note: >
+ A `service.instance` uniquely identifies an instance of a logical service. For example,
+ a container that is part of a Kubernetes deployment
+ that offers a service.
+ stability: development
+ attributes:
- ref: service.instance.id
role: identifying
+ requirement_level: required
+ - id: entity.service.namespace
+ type: entity
+ name: service.namespace
+ brief: >
+ Groups related services that compose a system or application under a common namespace.
+ note: >
+ A `service.namespace` can be used to logically organize and group related services under a common namespace.
+ stability: development
+ attributes:
+ - ref: service.namespace
+ role: identifying
+ requirement_level: required
diff --git a/model/service/registry.yaml b/model/service/registry.yaml
index 9715378b19..9eeb1972d5 100644
--- a/model/service/registry.yaml
+++ b/model/service/registry.yaml
@@ -19,7 +19,7 @@ groups:
- id: service.version
type: string
brief: >
- The version string of the service API or implementation. The format is not defined by these conventions.
+ The version string of the service component. The format is not defined by these conventions.
examples: ["2.0.0", "a01dbef8a"]
stability: stable
- id: service.namespace