Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .chloggen/postgresql-application-name-propagation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
change_type: enhancement
component: db
note: Add context propagation for PostgreSQL via `SET application_name`.
issues: [2162]
subtext:
32 changes: 32 additions & 0 deletions docs/db/postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ linkTitle: PostgreSQL
<!-- toc -->

- [Spans](#spans)
- [Context propagation](#context-propagation)
- [SET application_name](#set-application_name)
- [Metrics](#metrics)

<!-- tocstop -->
Expand Down Expand Up @@ -165,6 +167,36 @@ and SHOULD be provided **at span creation time** (if provided at all):
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

## Context propagation

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

### SET application_name

Instrumentations MAY propagate context using [`SET application_name`](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-APPLICATION-NAME) by injecting fixed-length part of span context (trace-id, span-id, trace-flags, protocol version) before executing a query. For example, when using W3C Trace Context, only a string representation of [`traceparent`](https://www.w3.org/TR/trace-context/#traceparent-header) SHOULD be injected. Context injection SHOULD NOT be enabled by default, but instrumentation MAY allow users to opt into it.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never says to restore or clear the prior value afterwards. PostgreSQL SET is session-scoped, and application_name is commonly set at connection time and surfaced in pg_stat_activity/logs, so on pooled connections this would overwrite the caller’s configured app name and can leak stale trace IDs into later operations. I think the spec needs either explicit restore/reset semantics or a clear incompatibility warning.

Copy link
Copy Markdown
Member

@pellared pellared Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make an explicit design choice here:

  1. Either this convention is W3C Trace Context-specific, in which case the spec should say so directly and normatively define application_name as carrying only traceparent.
  2. Or we want this to support arbitrary propagators, in which case we should define application_name as a context propagation carrier, similar to the env-carriers spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md.

Right now the text sits in between those two models. It says “for example, when using W3C Trace Context” but does not actually define carrier semantics for non-W3C propagators.

If we choose the generic route, the carrier should be format-agnostic and treat the value as an opaque string, while the propagator remains responsible for key selection, encoding, validation, and any truncation behavior. We would also need to specify how a multi-field propagator maps into a single application_name string with a tight length limit.

My preference is to decide this explicitly in the spec rather than leave it implicit in instrumentation behavior. Given application_name size is limited. I think this should be always the one representation; the same as for traceparent or some other custom one. We may consider adding some _TP_ (which would stand for traceparent) prefix following what Datadog implementation does.


Variable context parts (`tracestate`, `baggage`) SHOULD NOT be injected since `application_name` value length (63 characters in a standard build) is limited to less than [`NAMEDATALEN`](https://www.postgresql.org/docs/current/runtime-config-preset.html#GUC-MAX-IDENTIFIER-LENGTH) characters .

Instrumentations that propagate context MUST execute `SET application_name` on the same physical connection as the SQL statement.

The `application_name` value is visible in [`pg_stat_activity`](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW) and can be included in PostgreSQL server logs via `%a` in [`log_line_prefix`](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-LINE-PREFIX).

Example:

For a query `SELECT * FROM songs` where `traceparent` is `00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01`:

Run the following command on the same physical connection as the SQL statement:

```sql
SET application_name = '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01';
```

Then run the query:

```sql
SELECT * FROM songs;
```

## Metrics

PostgreSQL client instrumentations SHOULD collect metrics according to the general
Expand Down
Loading