-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathotelprofiling.go
69 lines (57 loc) · 1.55 KB
/
otelprofiling.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
package otelprofiling
import (
"context"
"runtime/pprof"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/noop"
)
// tracerProvider satisfies open telemetry TracerProvider interface.
type tracerProvider struct {
noop.TracerProvider
tp trace.TracerProvider
}
type Option func(*tracerProvider)
// NewTracerProvider creates a new tracer provider that annotates pprof
// samples with span_id label. This allows to establish a relationship
// between pprof profiles and reported tracing spans.
func NewTracerProvider(tp trace.TracerProvider, options ...Option) trace.TracerProvider {
p := tracerProvider{
tp: tp,
}
for _, o := range options {
o(&p)
}
return &p
}
func (w *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
return &profileTracer{p: w, tr: w.tp.Tracer(name, opts...)}
}
type profileTracer struct {
noop.Tracer
p *tracerProvider
tr trace.Tracer
}
func (w *profileTracer) Start(ctx context.Context, spanName string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
ctx, span := w.tr.Start(ctx, spanName, opts...)
spanCtx := span.SpanContext()
traceID := spanCtx.TraceID().String()
s := spanWrapper{
Span: span,
ctx: ctx,
p: w.p,
}
if traceID != "" {
ctx = pprof.WithLabels(ctx, pprof.Labels("otel_traceid", traceID))
pprof.SetGoroutineLabels(ctx)
}
return ctx, &s
}
type spanWrapper struct {
trace.Span
ctx context.Context
p *tracerProvider
}
func (s spanWrapper) End(options ...trace.SpanEndOption) {
s.Span.End(options...)
pprof.SetGoroutineLabels(s.ctx)
}