forked from vitessio/vitess
-
Notifications
You must be signed in to change notification settings - Fork 1
/
trace.go
101 lines (86 loc) · 3.88 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
// Copyright 2014, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package trace contains a helper interface that allows various tracing
// tools to be plugged in to components using this interface. If no plugin is
// registered, the default one makes all trace calls into no-ops.
package trace
import (
"golang.org/x/net/context"
)
// Span represents a unit of work within a trace. After creating a Span with
// NewSpan(), call one of the Start methods to mark the beginning of the work
// represented by this Span. Call Finish() when that work is done to record the
// Span. A Span may be reused by calling Start again.
type Span interface {
// StartLocal marks the beginning of a span representing time spent doing
// work locally.
StartLocal(label string)
// StartClient marks the beginning of a span representing time spent acting as
// a client and waiting for a response.
StartClient(label string)
// StartServer marks the beginning of a span representing time spent doing
// work in service of a remote client request.
StartServer(label string)
// Finish marks the span as complete.
Finish()
// Annotate records a key/value pair associated with a Span. It should be
// called between Start and Finish.
Annotate(key string, value interface{})
}
// NewSpan creates a new Span with the currently installed tracing plugin.
// If no tracing plugin is installed, it returns a fake Span that does nothing.
func NewSpan(parent Span) Span {
return spanFactory.New(parent)
}
// FromContext returns the Span from a Context if present. The bool return
// value indicates whether a Span was present in the Context.
func FromContext(ctx context.Context) (Span, bool) {
return spanFactory.FromContext(ctx)
}
// NewContext returns a context based on parent with a new Span value.
func NewContext(parent context.Context, span Span) context.Context {
return spanFactory.NewContext(parent, span)
}
// NewSpanFromContext returns a new Span whose parent is the Span from the given
// Context if present, or a new Span with no parent if not.
func NewSpanFromContext(ctx context.Context) Span {
if parent, ok := FromContext(ctx); ok {
return NewSpan(parent)
}
return NewSpan(nil)
}
// CopySpan creates a new context from parentCtx, with only the trace span
// copied over from spanCtx, if it has any. If not, parentCtx is returned.
func CopySpan(parentCtx, spanCtx context.Context) context.Context {
if span, ok := FromContext(spanCtx); ok {
return NewContext(parentCtx, span)
}
return parentCtx
}
// SpanFactory is an interface for creating spans or extracting them from Contexts.
type SpanFactory interface {
New(parent Span) Span
FromContext(ctx context.Context) (Span, bool)
NewContext(parent context.Context, span Span) context.Context
}
var spanFactory SpanFactory = fakeSpanFactory{}
// RegisterSpanFactory should be called by a plugin during init() to install a
// factory that creates Spans for that plugin's tracing framework. Each call to
// RegisterSpanFactory will overwrite any previous setting. If no factory is
// registered, the default fake factory will produce Spans whose methods are all
// no-ops.
func RegisterSpanFactory(sf SpanFactory) {
spanFactory = sf
}
type fakeSpanFactory struct{}
func (fakeSpanFactory) New(parent Span) Span { return fakeSpan{} }
func (fakeSpanFactory) FromContext(ctx context.Context) (Span, bool) { return nil, false }
func (fakeSpanFactory) NewContext(parent context.Context, span Span) context.Context { return parent }
// fakeSpan implements Span with no-op methods.
type fakeSpan struct{}
func (fakeSpan) StartLocal(string) {}
func (fakeSpan) StartClient(string) {}
func (fakeSpan) StartServer(string) {}
func (fakeSpan) Finish() {}
func (fakeSpan) Annotate(string, interface{}) {}