Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ release.

### Context

- Add `EnvVarPropagator` decorator with examples for environment variables as context carrier specification. ([#4484](https://github.com/open-telemetry/opentelemetry-specification/pull/4484))

### Traces

### Metrics
Expand All @@ -17,6 +19,8 @@ release.

### Baggage

- Add `EnvVarPropagator` decorator with examples for environment variables as context carrier specification. ([#4484](https://github.com/open-telemetry/opentelemetry-specification/pull/4484))

### Resource

### Profiles
Expand Down
79 changes: 79 additions & 0 deletions specification/context/env-carriers.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
+ [Process Spawning](#process-spawning)
+ [Security](#security)
+ [Case Sensitivity](#case-sensitivity)
- [Propagator API](#propagator-api)
* [Environment Variable Propagator Decorator](#environment-variable-propagator-decorator)
+ [Examples](#examples)
- [Go](#go)
- [Python](#python)
- [Swift](#swift)

<!-- tocstop -->

Expand Down Expand Up @@ -149,3 +155,76 @@ Windows.
- For maximum compatibility, implementations MUST:
- Use uppercase names consistently (`TRACEPARENT` not `TraceParent`).
- Use the canonical case when setting environment variables.

## Propagator API

### Environment Variable Propagator Decorator

The `EnvVarPropagator` is a [decorator][dec] that wraps a `TextMapPropagator`,
handling the injection and extraction of context and baggage into and from
environment variables.
Comment on lines +163 to +165
Copy link
Member

Choose a reason for hiding this comment

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

This document doesn't really address things like interactions with span linking and configuration of the global propagators. There are some difficult details that we had to deal with for the X-Ray Lambda Propagator.


The `EnvVarPropagator` SHOULD be configurable to match platform-specific
restrictions and handle environment variable naming conventions as described in
the [Environment Variable Names](#environment-variable-names) and [Format
Restrictions](#format-restrictions) sections.
Comment on lines +161 to +170
Copy link
Member

@pellared pellared Apr 28, 2025

Choose a reason for hiding this comment

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

I do not understand why we need a propagator decorator. Isn't this something that is needed for Python propagator design?

Don't we simply need a new carrier implementation where environmental variables are the medium?

Copy link
Member

Choose a reason for hiding this comment

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


The `EnvVarPropagator` MAY define an `EnvVarCarrier` type that implements the
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to see some implementations of this across languages.

My suspicion is that there is not a great abstraction around ENV + fork() you can use here, so instead I think non-normative recommendations for how to use TextMapPropagator and then language-specific implementations may be better.

`TextMap` carrier interface when calling `Inject` and `Extract` operations.

#### Examples

##### Go

```go
type TextMapPropagator interface {
// Includes Inject, Extract, and Fields
...
}

type EnvVarPropagator func(TextMapPropagator) TextMapPropagator

Choose a reason for hiding this comment

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

I'm a little confused by the type selection in this example. What do you think about using embedding here like so?

type EnvVarPropagator struct {
    TextMapPropagator
}


func (envp EnvVarPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
env := os.Environ()
// Inject context into environment variable copy
...
}
Comment on lines +187 to +191

Choose a reason for hiding this comment

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

I'm not too familiar with the Propagators API, but I noticed the Inject method in the TextMapPropagator interface doesn't return anything. So I'm curious what future implementors should do with the scoped copy of environment variables? Set them to the mutable carrier?


func (envp EnvVarPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
// Extract context from environment variables
...
}
...
```
Comment on lines +179 to +198
Copy link
Member

@pellared pellared Apr 28, 2025

Choose a reason for hiding this comment

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

This doesn't currently demonstrate the intended concept. Could you create a prototype (e.g., a draft PR) in https://github.com/open-telemetry/opentelemetry-go instead?

Also, the current design isn't quite convincing. Shouldn't we be implementing a TextMapCarrier that works with environment variables? After all, the document is titled "Environment Variables as Context Propagation Carriers", which strongly suggests that direction.


##### Python

```python
class EnvVarPropagator(TextMapPropagator):
def inject(self, context, carrier):
env_dict = os.environ.copy()
# Inject context into environment variables
...

def extract(self, carrier):
# Extract context from environment variables
...
```

##### Swift

```swift
public struct EnvVarPropagator: TextMapPropagator {
public func inject(...) {
// Inject context into environment variables
...
}

public func extract(...) -> SpanContext? {
// Extract context from environment variables
...
}
}
```

[dec]: https://wikipedia.org/wiki/Decorator_pattern