Skip to content

Commit

Permalink
Propagation - Extract handles multiple values on carrier using same k…
Browse files Browse the repository at this point in the history
…ey (#4295)

Fixes #433

Discussed in 11/5/24 Spec SIG, and prototyped in Java and Go.

## Changes

Adds `GetAll` method to Getter, allowing for the retrieval of multiple
keys for the same value. For example, an HTTP request may have multiple
`baggage` headers.

As written in the changes, the implementation of `GetAll` is strictly
optional. This is for two reasons:
1. Backwards compatibility with existing types/interfaces
2. Carriers do not necessarily support returning multiple values for a
single key

## Links to Prototypes

This includes implementations of `GetAll()` in Java and Go, as well as
using the method in the W3C Baggage Propagators (multiple baggage
headers are allowed, [spec
reference](https://www.w3.org/TR/baggage/#baggage-http-header-format)).

- Java: open-telemetry/opentelemetry-java#6852
- Go: open-telemetry/opentelemetry-go#5973

* [x] Links to the prototypes (when adding or changing features)
* [x]
[`CHANGELOG.md`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/CHANGELOG.md)
file updated for non-trivial changes

---------

Co-authored-by: Trask Stalnaker <[email protected]>
Co-authored-by: jack-berg <[email protected]>
Co-authored-by: Robert Pająk <[email protected]>
  • Loading branch information
4 people authored Nov 28, 2024
1 parent 79380c6 commit 3ce4873
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ release.

### Context

- Adds optional `GetAll` method to `Getter` in Propagation API, allowing for the retrieval of multiple values for the same key.
[#4295](https://github.com/open-telemetry/opentelemetry-specification/pull/4295)

### Traces

- Add in-development support for `otlp/stdout` exporter via `OTEL_TRACES_EXPORTER`.
Expand Down
30 changes: 26 additions & 4 deletions specification/context/api-propagators.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Propagators API

**Status**: [Stable, Feature-Freeze](../document-status.md)
**Status**: [Stable](../document-status.md), except where otherwise specified.

<details>
<summary>Table of Contents</summary>
Expand All @@ -22,6 +22,7 @@
+ [Getter argument](#getter-argument)
- [Keys](#keys)
- [Get](#get)
- [GetAll](#getall)
- [Injectors and Extractors as Separate Interfaces](#injectors-and-extractors-as-separate-interfaces)
- [Composite Propagator](#composite-propagator)
* [Create a Composite Propagator](#create-a-composite-propagator)
Expand Down Expand Up @@ -196,11 +197,11 @@ Returns a new `Context` derived from the `Context` passed as argument.

#### Getter argument

Getter is an argument in `Extract` that get value from given field
Getter is an argument in `Extract` that gets value(s) from given field.

`Getter` allows a `TextMapPropagator` to read propagated fields from a carrier.

One of the ways to implement it is `Getter` class with `Get` and `Keys` methods
One of the ways to implement it is `Getter` class with methods `Get`, `Keys`, and `GetAll`
as described below. Languages may decide on alternative implementations and
expose corresponding methods as delegates or other ways.

Expand All @@ -227,7 +228,28 @@ Required arguments:
- the carrier of propagation fields, such as an HTTP request.
- the key of the field.

The Get function is responsible for handling case sensitivity. If the getter is intended to work with a HTTP request object, the getter MUST be case insensitive.
The Get function is responsible for handling case sensitivity. If the getter is intended to work with an HTTP request object, the getter MUST be case insensitive.

##### GetAll

**Status**: [Development](../document-status.md)

For many language implementations, the `GetAll` function will be added after the stable release of `Getter`.
For these languages, requiring implementations of `Getter` to include `GetAll` constitutes a breaking change
since instrumentation which previously functioned would fail. Language implementations should be cognizant
of this, and add `GetAll` in a way that retains backwards compatibility. For example, by providing a default
`GetAll` implementation based on Get, or by creating an extended `Getter` type.

If explicitly implemented, the `GetAll` function MUST return all values of the given propagation key.
It SHOULD return them in the same order as they appear in the carrier.
If the key doesn't exist, it SHOULD return an empty collection.

Required arguments:

- the carrier of propagation fields, such as an HTTP request.
- the key of the field.

The `GetAll` function is responsible for handling case sensitivity. If the getter is intended to work with an HTTP request object, the getter MUST be case insensitive.

## Injectors and Extractors as Separate Interfaces

Expand Down

0 comments on commit 3ce4873

Please sign in to comment.