...
1
16
17 package tracing
18
19 import (
20 "context"
21 "time"
22
23 "go.opentelemetry.io/otel/attribute"
24 "go.opentelemetry.io/otel/trace"
25
26 utiltrace "k8s.io/utils/trace"
27 )
28
29 const instrumentationScope = "k8s.io/component-base/tracing"
30
31
32
33 func Start(ctx context.Context, name string, attributes ...attribute.KeyValue) (context.Context, *Span) {
34
35
36 ctx, otelSpan := trace.SpanFromContext(ctx).TracerProvider().Tracer(instrumentationScope).Start(ctx, name, trace.WithAttributes(attributes...))
37
38 utilSpan := utiltrace.FromContext(ctx).Nest(name, attributesToFields(attributes)...)
39
40 return utiltrace.ContextWithTrace(ctx, utilSpan), &Span{
41 otelSpan: otelSpan,
42 utilSpan: utilSpan,
43 }
44 }
45
46
47
48
49
50 type Span struct {
51 otelSpan trace.Span
52 utilSpan *utiltrace.Trace
53 }
54
55
56 func (s *Span) AddEvent(name string, attributes ...attribute.KeyValue) {
57 s.otelSpan.AddEvent(name, trace.WithAttributes(attributes...))
58 if s.utilSpan != nil {
59 s.utilSpan.Step(name, attributesToFields(attributes)...)
60 }
61 }
62
63
64 func (s *Span) End(logThreshold time.Duration) {
65 s.otelSpan.End()
66 if s.utilSpan != nil {
67 s.utilSpan.LogIfLong(logThreshold)
68 }
69 }
70
71
72
73 func (s *Span) RecordError(err error, attributes ...attribute.KeyValue) {
74 s.otelSpan.RecordError(err, trace.WithAttributes(attributes...))
75 }
76
77 func attributesToFields(attributes []attribute.KeyValue) []utiltrace.Field {
78 fields := make([]utiltrace.Field, len(attributes))
79 for i := range attributes {
80 attr := attributes[i]
81 fields[i] = utiltrace.Field{Key: string(attr.Key), Value: attr.Value.AsInterface()}
82 }
83 return fields
84 }
85
86
87
88 func SpanFromContext(ctx context.Context) *Span {
89 return &Span{
90 otelSpan: trace.SpanFromContext(ctx),
91 utilSpan: utiltrace.FromContext(ctx),
92 }
93 }
94
95
96 func ContextWithSpan(ctx context.Context, s *Span) context.Context {
97 return trace.ContextWithSpan(utiltrace.ContextWithTrace(ctx, s.utilSpan), s.otelSpan)
98 }
99
View as plain text