blob: 8e3bd8d4654ccd059f90c398b100e94ed6dc7a8e [file] [log] [blame]
Joey Armstronge8c091f2023-01-17 16:56:26 -05001// Copyright The OpenTelemetry Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package otel
16
17import "context"
18
19// TextMapCarrier is the storage medium used by a TextMapPropagator.
20type TextMapCarrier interface {
21 // Get returns the value associated with the passed key.
22 Get(key string) string
23 // Set stores the key-value pair.
24 Set(key string, value string)
25}
26
27// TextMapPropagator propagates cross-cutting concerns as key-value text
28// pairs within a carrier that travels in-band across process boundaries.
29type TextMapPropagator interface {
30 // Inject set cross-cutting concerns from the Context into the carrier.
31 Inject(ctx context.Context, carrier TextMapCarrier)
32 // Extract reads cross-cutting concerns from the carrier into a Context.
33 Extract(ctx context.Context, carrier TextMapCarrier) context.Context
34 // Fields returns the keys who's values are set with Inject.
35 Fields() []string
36}
37
38type compositeTextMapPropagator []TextMapPropagator
39
40func (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {
41 for _, i := range p {
42 i.Inject(ctx, carrier)
43 }
44}
45
46func (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {
47 for _, i := range p {
48 ctx = i.Extract(ctx, carrier)
49 }
50 return ctx
51}
52
53func (p compositeTextMapPropagator) Fields() []string {
54 unique := make(map[string]struct{})
55 for _, i := range p {
56 for _, k := range i.Fields() {
57 unique[k] = struct{}{}
58 }
59 }
60
61 fields := make([]string, 0, len(unique))
62 for k := range unique {
63 fields = append(fields, k)
64 }
65 return fields
66}
67
68// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
69// group of passed TextMapPropagator. This allows different cross-cutting
70// concerns to be propagates in a unified manner.
71//
72// The returned TextMapPropagator will inject and extract cross-cutting
73// concerns in the order the TextMapPropagators were provided. Additionally,
74// the Fields method will return a de-duplicated slice of the keys that are
75// set with the Inject method.
76func NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {
77 return compositeTextMapPropagator(p)
78}