-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtracing.go
125 lines (108 loc) · 3.85 KB
/
tracing.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
125
package tracing
import (
"context"
"github.com/deixis/spine/contextutil"
"github.com/deixis/spine/log"
"github.com/deixis/spine/stats"
opentracing "github.com/opentracing/opentracing-go"
)
// Tracer follows the opentracing standard https://opentracing.io
type Tracer opentracing.Tracer
// TracerOption configures how we set up a job
type TracerOption func(*TracerOptions)
// TracerOptions configure a Tracer.
type TracerOptions struct {
Logger log.Logger
Stats stats.Stats
}
// WithLogger injects a `Logger` to `Tracer`
func WithLogger(l log.Logger) TracerOption {
return func(o *TracerOptions) {
o.Logger = l
}
}
// WithStats injects a `Stats` to `Tracer`
func WithStats(s stats.Stats) TracerOption {
return func(o *TracerOptions) {
o.Stats = s
}
}
// StartSpanFromContext starts and returns a Span with `operationName`, using
// any Span found within `ctx` as a ChildOfRef. If no such parent could be
// found, StartSpanFromContext creates a root (parentless) Span.
//
// The second return value is a context.Context object built around the
// returned Span.
//
// Example usage:
//
// SomeFunction(ctx context.Context, ...) {
// sp, ctx := tracing.StartSpanFromContext(ctx, "SomeFunction")
// defer sp.Finish()
// ...
// }
func StartSpanFromContext(
ctx context.Context, operationName string, opts ...opentracing.StartSpanOption,
) (opentracing.Span, context.Context) {
if parent := SpanFromContext(ctx); parent != nil {
opts = append(opts, opentracing.ChildOf(parent.Context()))
}
span := FromContext(ctx).StartSpan(operationName, opts...)
return span, opentracing.ContextWithSpan(ctx, span)
}
// StartSpan creates, starts, and returns a new Span with the given
// `operationName` and incorporate the given StartSpanOption `opts`.
//
// StartSpan calls `StartSpan` on the context `Tracer`
func StartSpan(
ctx context.Context, operationName string, opts ...opentracing.StartSpanOption,
) (span opentracing.Span) {
return FromContext(ctx).StartSpan(operationName, opts...)
}
// Inject takes the `sm` SpanContext instance and injects it for
// propagation within `carrier`. The actual type of `carrier` depends on
// the value of `format`.
//
// Inject calls `Inject` on the context `Tracer`
func Inject(
ctx context.Context, sm opentracing.SpanContext, format interface{}, carrier interface{},
) error {
return FromContext(ctx).Inject(sm, format, carrier)
}
// Extract returns a SpanContext instance given `format` and `carrier`.
//
// Extract calls `Extract` on the context `Tracer`
func Extract(
ctx context.Context, format interface{}, carrier interface{},
) (opentracing.SpanContext, error) {
return FromContext(ctx).Extract(format, carrier)
}
// ContextWithSpan returns a new `context.Context` that holds a reference to
// `span`'s SpanContext.
func ContextWithSpan(ctx context.Context, span opentracing.Span) context.Context {
return opentracing.ContextWithSpan(ctx, span)
}
// SpanFromContext returns the `Span` previously associated with `ctx`, or
// `nil` if no such `Span` could be found.
//
// NOTE: context.Context != SpanContext: the former is Go's intra-process
// context propagation mechanism, and the latter houses OpenTracing's per-Span
// identity and baggage information.
func SpanFromContext(ctx context.Context) opentracing.Span {
return opentracing.SpanFromContext(ctx)
}
type contextKey struct{}
var activeContextKey = contextKey{}
// FromContext returns a `Tracer` instance associated with `ctx`, or
// the `opentracing.GlobalTracer` if no `Tracer` instance could be found.
func FromContext(ctx contextutil.ValueContext) Tracer {
val := ctx.Value(activeContextKey)
if o, ok := val.(Tracer); ok {
return o
}
return opentracing.GlobalTracer()
}
// WithContext returns a copy of parent in which the `Tracer` is stored
func WithContext(ctx context.Context, t Tracer) context.Context {
return context.WithValue(ctx, activeContextKey, t)
}