# Semantic conventions for Google Cloud Pub/Sub

**Status**: [Development][DocumentStatus]

The Semantic Conventions for [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) extend and override the [Messaging Semantic Conventions](README.md).

> [!IMPORTANT]
>
> Existing messaging instrumentations that are using
> [v1.24.0 of this document](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-spans.md)
> (or prior):
>
> * SHOULD NOT change the version of the messaging conventions that they emit by default
>   until the messaging semantic conventions are marked stable.
>   Conventions include, but are not limited to, attributes,
>   metric and span names, span kind and unit of measure.
> * SHOULD introduce an environment variable `OTEL_SEMCONV_STABILITY_OPT_IN`
>   in the existing major version as a comma-separated list of category-specific values
>   (e.g., http, databases, messaging). The list of values includes:
>   * `messaging` - emit the new, stable messaging conventions,
>     and stop emitting the old experimental messaging conventions
>     that the instrumentation emitted previously.
>   * `messaging/dup` - emit both the old and the stable messaging conventions,
>     allowing for a seamless transition.
>   * The default behavior (in the absence of one of these values) is to continue
>     emitting whatever version of the old experimental messaging conventions
>     the instrumentation was emitting previously.
>   * Note: `messaging/dup` has higher precedence than `messaging` in case both values are present
> * SHOULD maintain (security patching at a minimum) the existing major version
>   for at least six months after it starts emitting both sets of conventions.
> * SHOULD drop the environment variable in the next major version.
> * SHOULD emit the new, stable values for span name, span kind and similar "single"
> valued concepts when `messaging/dup` is present in the list.

`messaging.system` MUST be set to `"gcp_pubsub"` and SHOULD be provided **at span creation time**.

## Span attributes

For Google Cloud Pub/Sub, the following additional attributes are defined:

<!-- semconv messaging.gcp_pubsub -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->

**Attributes:**

| Key | Stability | [Requirement Level](/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`messaging.operation.name`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The system-specific name of the messaging operation. [1] | `ack`; `nack`; `send` |
| [`error.type`](/docs/specs/semconv/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the messaging operation has failed. | string | Describes a class of error the operation ended with. [2] | `amqp:decode-error`; `KAFKA_STORAGE_ERROR`; `channel-error` |
| [`messaging.batch.message_count`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [3] | int | The number of messages sent, received, or processed in the scope of the batching operation. [4] | `0`; `1`; `2` |
| [`messaging.destination.name`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [5] | string | The message destination name [6] | `MyQueue`; `MyTopic` |
| [`messaging.gcp_pubsub.message.ordering_key`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If the message type has an ordering key set. | string | The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. | `ordering_key` |
| [`messaging.operation.type`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If applicable. | string | A string identifying the type of the messaging operation. [7] | `create`; `send`; `receive` |
| [`server.address`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If available. | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`messaging.destination.subscription.name`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | Google Pub/Sub [subscription name](https://cloud.google.com/pubsub/docs/subscription-overview). | `subscription-a` |
| [`messaging.gcp_pubsub.message.ack_deadline`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | int | The ack deadline in seconds set for the modify ack deadline request. | `10` |
| [`messaging.gcp_pubsub.message.ack_id`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The ack id for a given message. | `ack_id` |
| [`messaging.gcp_pubsub.message.delivery_attempt`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | int | The delivery attempt for a given message. | `2` |
| [`messaging.message.id`](/docs/specs/semconv/registry/attributes/messaging.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` If span describes operation on a single message. | string | A value used by the messaging system as an identifier for the message, represented as a string. | `452a7c7c7c7048c2f887f61572b18fc2` |
| [`server.port`](/docs/specs/semconv/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Server port number. [9] | `80`; `8080`; `443` |

**[1] `messaging.operation.name`:** The `messaging.operation.name` has the following list of well-known values in the context of Google Pub/Sub.
If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

- `ack` and `nack` for settlement operations
- `send` for publishing operations
- `modack` for extending the lease for a single message or batch of messages
- `subscribe` for operations that represent the time from after the message was received to when the message is acknowledged, negatively acknowledged, or expired.
- `create` and `receive` for [common messaging operations](/docs/specs/semconv/messaging/messaging-spans.md#operation-types)

**[2] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality.

When `error.type` is set to a type (e.g., an exception type), its
canonical class name identifying the type within the artifact SHOULD be used.

Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low.
Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
should be prepared for `error.type` to have high cardinality at query time when no
additional filters are applied.

If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.

If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes),
it's RECOMMENDED to:

- Use a domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not.

**[3] `messaging.batch.message_count`:** If the span describes an operation on a batch of messages.

**[4] `messaging.batch.message_count`:** Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs.

**[5] `messaging.destination.name`:** If span describes operation on a single message or if the value applies to all messages in the batch.

**[6] `messaging.destination.name`:** Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If
the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.

**[7] `messaging.operation.type`:** If a custom value is used, it MUST be of low cardinality.

**[8] `server.address`:** Server domain name of the broker if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.

**[9] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.

The following attributes can be important for making sampling decisions
and SHOULD be provided **at span creation time** (if provided at all):

* [`messaging.destination.name`](/docs/specs/semconv/registry/attributes/messaging.md)
* [`messaging.destination.subscription.name`](/docs/specs/semconv/registry/attributes/messaging.md)
* [`messaging.operation.name`](/docs/specs/semconv/registry/attributes/messaging.md)
* [`messaging.operation.type`](/docs/specs/semconv/registry/attributes/messaging.md)
* [`server.address`](/docs/specs/semconv/registry/attributes/server.md)
* [`server.port`](/docs/specs/semconv/registry/attributes/server.md)

---

`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
| --- | --- | --- |
| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |

---

`messaging.operation.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
| --- | --- | --- |
| `create` | A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch sending scenarios. | ![Development](https://img.shields.io/badge/-development-blue) |
| `process` | One or more messages are processed by a consumer. | ![Development](https://img.shields.io/badge/-development-blue) |
| `receive` | One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. | ![Development](https://img.shields.io/badge/-development-blue) |
| `send` | One or more messages are provided for sending to an intermediary. If a single message is sent, the context of the "Send" span can be used as the creation context and no "Create" span needs to be created. | ![Development](https://img.shields.io/badge/-development-blue) |
| `settle` | One or more messages are settled. | ![Development](https://img.shields.io/badge/-development-blue) |

<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

## Examples

### Asynchronous batch publish example

Given is a process P that asynchronously publishes 2 messages in a batch to a topic T on Pub/Sub.

```mermaid
flowchart LR;
  subgraph PRODUCER
  direction LR
  CA[Span Create A]
  CB[Span Create B]
  P[Span Send A B]
  end
  CA-. link .-P;
  CB-. link .-P;

  classDef producer fill:green
  class P,CA,CB producer
  classDef normal fill:green
  class PA,PB,D1 normal
  linkStyle 0,1 color:green,stroke:green
```

| Field or Attribute | Producer Span Create A | Producer Span Create B | Producer Span Send A B |
| --- | --- | --- | --- |
| Span name | `create T` | `create T` | `send T` |
| Parent | | | |
| Links | | | Span Create A, Span Create B |
| SpanKind | `PRODUCER` | `PRODUCER` | `CLIENT` |
| Status | `Ok` | `Ok` | `Ok` |
| `messaging.batch.message_count` | | | 2 |
| `messaging.destination.name` | `"T"` | `"T"` | `"T"` |
| `messaging.operation.name` | `"create"` | `"create"` | `"send"` |
| `messaging.operation.type` | `"create"` | `"create"` | `"send"` |
| `messaging.message.id` | `"a1"` | `"a2"` | |
| `messaging.message.envelope.size` | `1` | `1` | |
| `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` |

### Unary pull example

```mermaid
flowchart TD;
  subgraph CONSUMER
  direction LR
  R1[Receive A]
  SM1[Ack A]
  EM1[Modack A]
  end
  subgraph PRODUCER
  direction LR
  CM1[Create A]
  PM1[Send]
  end
  %% Link 0
  CM1-. link .-PM1;
  %% Link 1
  CM1-. link .-R1;
  %% Link 2
  R1-. link .-SM1;
  %% Link 3
  R1-. link .-EM1;

  %% Style the node and corresponding link
  %% Producer links and nodes
  classDef producer fill:green
  class PM1,CM1 producer
  linkStyle 0 color:green,stroke:green

  %% Consumer links and nodes
  classDef consumer fill:#49fcdc
  class R1 consumer
  linkStyle 1 color:#49fcdc,stroke:#49fcdc

  classDef ack fill:#577eb5
  class SM1 ack
  linkStyle 2 color:#577eb5,stroke:#577eb5

  classDef modack fill:#0560f2
  class EM1 modack
  linkStyle 3 color:#0560f2,stroke:#0560f2
```

| Field or Attribute | Producer Span Create A | Producer Span Send | Consumer Span Receive A | Consumer Span Modack A | Consumer Span Ack A |
| --- | --- | --- | --- | --- | --- |
| Span name | `create T` | `send T` | `receive S` | `modack S` | `ack S` |
| Parent | | | | | |
| Links | | Span Create A | Span Create A | Span Receive A | Span Receive A |
| SpanKind | `PRODUCER` | `PRODUCER` | `CONSUMER` | `CLIENT` | `CLIENT` |
| Status | `Ok` | `Ok` | `Ok` | `Ok` | `Ok` |
| `messaging.destination.name` | `"T"` | `"T"` | `"S"` | `"S"` | `"S"` |
| `messaging.system` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` | `"gcp_pubsub"` |
| `messaging.operation.name` | `"create"` | `"send"` | `"receive"` | `"modack"` | `"ack"` |
| `messaging.operation.type` | `"create"` | `"send"` | `"receive"` | | `"settle"` |
| `messaging.message.id` | `"a1"` | | `"a1"` | | |
| `messaging.message.envelope.size` | `1` | `1` | `1` | | |
| `messaging.gcp_pubsub.message.ack_id` | | | | `"ack_id1"` | `"ack_id1"` |
| `messaging.gcp_pubsub.message.delivery_attempt` | | | | `0` | |
| `messaging.gcp_pubsub.message.ack_deadline` | | | | | `0` |

[DocumentStatus]: /docs/specs/otel/document-status
