blob: 5c8c26ea2eb795c639094fc575ca4fa813f01bba [file] [log] [blame]
Abhay Kumar40252eb2025-10-13 13:25:53 +00001// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4package propagation // import "go.opentelemetry.io/otel/propagation"
5
6import (
7 "context"
8 "net/http"
9)
10
11// TextMapCarrier is the storage medium used by a TextMapPropagator.
12// See ValuesGetter for how a TextMapCarrier can get multiple values for a key.
13type TextMapCarrier interface {
14 // DO NOT CHANGE: any modification will not be backwards compatible and
15 // must never be done outside of a new major release.
16
17 // Get returns the value associated with the passed key.
18 Get(key string) string
19 // DO NOT CHANGE: any modification will not be backwards compatible and
20 // must never be done outside of a new major release.
21
22 // Set stores the key-value pair.
23 Set(key string, value string)
24 // DO NOT CHANGE: any modification will not be backwards compatible and
25 // must never be done outside of a new major release.
26
27 // Keys lists the keys stored in this carrier.
28 Keys() []string
29 // DO NOT CHANGE: any modification will not be backwards compatible and
30 // must never be done outside of a new major release.
31}
32
33// ValuesGetter can return multiple values for a single key,
34// with contrast to TextMapCarrier.Get which returns a single value.
35type ValuesGetter interface {
36 // DO NOT CHANGE: any modification will not be backwards compatible and
37 // must never be done outside of a new major release.
38
39 // Values returns all values associated with the passed key.
40 Values(key string) []string
41 // DO NOT CHANGE: any modification will not be backwards compatible and
42 // must never be done outside of a new major release.
43}
44
45// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
46// medium for propagated key-value pairs.
47type MapCarrier map[string]string
48
49// Compile time check that MapCarrier implements the TextMapCarrier.
50var _ TextMapCarrier = MapCarrier{}
51
52// Get returns the value associated with the passed key.
53func (c MapCarrier) Get(key string) string {
54 return c[key]
55}
56
57// Set stores the key-value pair.
58func (c MapCarrier) Set(key, value string) {
59 c[key] = value
60}
61
62// Keys lists the keys stored in this carrier.
63func (c MapCarrier) Keys() []string {
64 keys := make([]string, 0, len(c))
65 for k := range c {
66 keys = append(keys, k)
67 }
68 return keys
69}
70
71// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier and ValuesGetter interfaces.
72type HeaderCarrier http.Header
73
74// Compile time check that HeaderCarrier implements ValuesGetter.
75var _ TextMapCarrier = HeaderCarrier{}
76
77// Compile time check that HeaderCarrier implements TextMapCarrier.
78var _ ValuesGetter = HeaderCarrier{}
79
80// Get returns the first value associated with the passed key.
81func (hc HeaderCarrier) Get(key string) string {
82 return http.Header(hc).Get(key)
83}
84
85// Values returns all values associated with the passed key.
86func (hc HeaderCarrier) Values(key string) []string {
87 return http.Header(hc).Values(key)
88}
89
90// Set stores the key-value pair.
91func (hc HeaderCarrier) Set(key string, value string) {
92 http.Header(hc).Set(key, value)
93}
94
95// Keys lists the keys stored in this carrier.
96func (hc HeaderCarrier) Keys() []string {
97 keys := make([]string, 0, len(hc))
98 for k := range hc {
99 keys = append(keys, k)
100 }
101 return keys
102}
103
104// TextMapPropagator propagates cross-cutting concerns as key-value text
105// pairs within a carrier that travels in-band across process boundaries.
106type TextMapPropagator interface {
107 // DO NOT CHANGE: any modification will not be backwards compatible and
108 // must never be done outside of a new major release.
109
110 // Inject set cross-cutting concerns from the Context into the carrier.
111 Inject(ctx context.Context, carrier TextMapCarrier)
112 // DO NOT CHANGE: any modification will not be backwards compatible and
113 // must never be done outside of a new major release.
114
115 // Extract reads cross-cutting concerns from the carrier into a Context.
116 // Implementations may check if the carrier implements ValuesGetter,
117 // to support extraction of multiple values per key.
118 Extract(ctx context.Context, carrier TextMapCarrier) context.Context
119 // DO NOT CHANGE: any modification will not be backwards compatible and
120 // must never be done outside of a new major release.
121
122 // Fields returns the keys whose values are set with Inject.
123 Fields() []string
124 // DO NOT CHANGE: any modification will not be backwards compatible and
125 // must never be done outside of a new major release.
126}
127
128type compositeTextMapPropagator []TextMapPropagator
129
130func (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
131 for _, i := range p {
132 i.Inject(ctx, carrier)
133 }
134}
135
136func (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
137 for _, i := range p {
138 ctx = i.Extract(ctx, carrier)
139 }
140 return ctx
141}
142
143func (p compositeTextMapPropagator) Fields() []string {
144 unique := make(map[string]struct{})
145 for _, i := range p {
146 for _, k := range i.Fields() {
147 unique[k] = struct{}{}
148 }
149 }
150
151 fields := make([]string, 0, len(unique))
152 for k := range unique {
153 fields = append(fields, k)
154 }
155 return fields
156}
157
158// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
159// group of passed TextMapPropagator. This allows different cross-cutting
160// concerns to be propagates in a unified manner.
161//
162// The returned TextMapPropagator will inject and extract cross-cutting
163// concerns in the order the TextMapPropagators were provided. Additionally,
164// the Fields method will return a de-duplicated slice of the keys that are
165// set with the Inject method.
166func NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {
167 return compositeTextMapPropagator(p)
168}