-
Notifications
You must be signed in to change notification settings - Fork 0
/
tracing.go
150 lines (120 loc) · 4.54 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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package tracing
import (
"context"
"net/http"
"github.com/omegaup/go-base/v3/logging"
)
type key int
var transactionKey key
// TransportType is used in Transaction.AcceptDistributedTraceHeaders to
// represent the type of connection that the trace payload was transported
// over.
type TransportType string
const (
// TransportQueue represents that the transaction was performed over a queue.
TransportQueue TransportType = "Queue"
)
// An Arg represents a name-value pair.
type Arg struct {
Name string
Value interface{}
}
// A Segment is a part of a transaction used to instrument
// functions, methods, and blocks of code.
type Segment interface {
// End marks the segment as finished.
End()
}
// A Transaction represents one logical unit of work: either an
// inbound web request or background task.
type Transaction interface {
// WithMetadata wraps the logger with the transaction metadata.
WithMetadata(log logging.Logger) logging.Logger
// SetName sets the current transaction's name.
SetName(name string)
// AddAttributes adds any attributes after the transaction was created.
AddAttributes(args ...Arg)
// StartSegment creates a new Segment inside the transaction.
StartSegment(name string) Segment
// NoticeError associates an error with the transaction.
NoticeError(err error)
// InsertDistributedTraceHeaders links transactions by adding Distributed
// Trace headers into the headers so that a child transaction can accept
// them.
InsertDistributedTraceHeaders(h http.Header)
// AcceptDistributedTraceHeaders links transactions by accepting Distributed
// Trace headers from the parent transaction.
AcceptDistributedTraceHeaders(t TransportType, h http.Header)
// End marks the transaction as finished.
End()
}
// Provider is the interface that can create Transactions.
type Provider interface {
// StartTransaction starts a new Transaction with the provided name and
// arguments.
StartTransaction(name string, args ...Arg) Transaction
// StartWebTransaction starts a new web Transaction with the provided name
// and arguments.
StartWebTransaction(
name string,
w http.ResponseWriter,
r *http.Request,
args ...Arg,
) (Transaction, http.ResponseWriter, *http.Request)
// WrapHandle is a convenience function for wrapping an http.Handler and
// adding all necessary tracing information.
WrapHandle(pattern string, handler http.Handler) (string, http.Handler)
}
// NewContext associates the transaction with the provided context.
// FromContext can then be used to retrieve the transaction.
func NewContext(ctx context.Context, txn Transaction) context.Context {
return context.WithValue(ctx, transactionKey, txn)
}
// FromContext returns the current Transaction associated with the Context.
func FromContext(ctx context.Context) Transaction {
if ctx == nil {
return &noopTransaction{}
}
txn, ok := ctx.Value(transactionKey).(Transaction)
if !ok {
return &noopTransaction{}
}
return txn
}
type noopProvider struct{}
// NewNoOpProvider returns a new provider that does nothing.
func NewNoOpProvider() Provider {
return &noopProvider{}
}
func (p *noopProvider) StartTransaction(name string, args ...Arg) Transaction {
return &noopTransaction{}
}
func (p *noopProvider) StartWebTransaction(name string, w http.ResponseWriter, r *http.Request, args ...Arg) (Transaction, http.ResponseWriter, *http.Request) {
return &noopTransaction{}, w, r
}
func (p *noopProvider) TransactionFromContext(ctx context.Context) Transaction {
return NewNoOpTransaction()
}
func (p *noopProvider) WrapHandle(pattern string, handler http.Handler) (string, http.Handler) {
return pattern, handler
}
type noopTransaction struct{}
// NewNoOpTransaction returns a Transaction that does nothing. Useful for tests.
func NewNoOpTransaction() Transaction {
return &noopTransaction{}
}
func (t *noopTransaction) WithMetadata(log logging.Logger) logging.Logger {
return log
}
func (t *noopTransaction) SetName(name string) {}
func (t *noopTransaction) AddAttributes(args ...Arg) {}
func (t *noopTransaction) StartSegment(name string) Segment {
return &noopSegment{}
}
func (t *noopTransaction) NoticeError(err error) {}
func (t *noopTransaction) InsertDistributedTraceHeaders(h http.Header) {}
func (t *noopTransaction) AcceptDistributedTraceHeaders(tt TransportType, h http.Header) {}
func (t *noopTransaction) End() {}
type noopSegment struct{}
func (s *noopSegment) AddAttributes(args ...Arg) {}
func (s *noopSegment) End() {}