generated from honeycombio/.github
-
Notifications
You must be signed in to change notification settings - Fork 15
/
trace.go
124 lines (111 loc) · 3.81 KB
/
trace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package pipelines
import (
"context"
"crypto/tls"
"errors"
"fmt"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding/gzip"
"go.opentelemetry.io/contrib/propagators/b3"
"go.opentelemetry.io/contrib/propagators/ot"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/trace"
)
// NewTracePipeline creates a new trace pipeline from a config.
// It returns a shutdown function that should be called when terminating the pipeline.
func NewTracePipeline(c PipelineConfig) (func() error, error) {
opts := []trace.TracerProviderOption{
trace.WithResource(c.Resource),
trace.WithSampler(c.Sampler),
}
for _, sp := range c.SpanProcessors {
opts = append(opts, trace.WithSpanProcessor(sp))
}
// make sure the exporter is added last
spanExporter, err := newTraceExporter(c.Protocol, c.Endpoint, c.Insecure, c.Headers)
if err != nil {
return nil, fmt.Errorf("failed to create span exporter: %v", err)
}
bsp := trace.NewBatchSpanProcessor(spanExporter)
opts = append(opts, trace.WithSpanProcessor(bsp))
tp := trace.NewTracerProvider(opts...)
if err = configurePropagators(c); err != nil {
return nil, err
}
otel.SetTracerProvider(tp)
return func() error {
_ = bsp.Shutdown(context.Background())
return spanExporter.Shutdown(context.Background())
}, nil
}
//revive:disable:flag-parameter bools are fine for an internal function
func newTraceExporter(protocol Protocol, endpoint string, insecure bool, headers map[string]string) (*otlptrace.Exporter, error) {
switch protocol {
case ProtocolGRPC:
return newGRPCTraceExporter(endpoint, insecure, headers)
case ProtocolHTTPProtobuf:
return newHTTPTraceExporter(endpoint, insecure, headers)
case ProtocolHTTPJSON:
return nil, errors.New("http/json is currently unsupported")
default:
return nil, errors.New("'" + string(protocol) + "' is not a supported protocol")
}
}
func newGRPCTraceExporter(endpoint string, insecure bool, headers map[string]string) (*otlptrace.Exporter, error) {
secureOption := otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, ""))
if insecure {
secureOption = otlptracegrpc.WithInsecure()
}
return otlptrace.New(
context.Background(),
otlptracegrpc.NewClient(
secureOption,
otlptracegrpc.WithEndpoint(endpoint),
otlptracegrpc.WithHeaders(headers),
otlptracegrpc.WithCompressor(gzip.Name),
),
)
}
func newHTTPTraceExporter(endpoint string, insecure bool, headers map[string]string) (*otlptrace.Exporter, error) {
tlsconfig := &tls.Config{}
secureOption := otlptracehttp.WithTLSClientConfig(tlsconfig)
if insecure {
secureOption = otlptracehttp.WithInsecure()
}
return otlptrace.New(
context.Background(),
otlptracehttp.NewClient(
secureOption,
otlptracehttp.WithEndpoint(endpoint),
otlptracehttp.WithHeaders(headers),
otlptracehttp.WithCompression(otlptracehttp.GzipCompression),
),
)
}
// configurePropagators configures B3 propagation by default.
func configurePropagators(c PipelineConfig) error {
propagatorsMap := map[string]propagation.TextMapPropagator{
"b3": b3.New(b3.WithInjectEncoding(b3.B3MultipleHeader)),
"baggage": propagation.Baggage{},
"tracecontext": propagation.TraceContext{},
"ottrace": ot.OT{},
}
var props []propagation.TextMapPropagator
for _, key := range c.Propagators {
prop := propagatorsMap[key]
if prop != nil {
props = append(props, prop)
}
}
if len(props) == 0 {
return fmt.Errorf("invalid configuration: unsupported propagators. Supported options: b3,baggage,tracecontext,ottrace")
}
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
props...,
))
return nil
}