api.go
8.1 KB
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package trace
import (
"context"
"time"
"google.golang.org/grpc/codes"
"go.opentelemetry.io/otel/api/kv"
)
type Provider interface {
// Tracer creates a named tracer that implements Tracer interface.
// If the name is an empty string then provider uses default name.
Tracer(name string) Tracer
}
type Tracer interface {
// Start a span.
Start(ctx context.Context, spanName string, opts ...StartOption) (context.Context, Span)
// WithSpan wraps the execution of the fn function with a span.
// It starts a new span, sets it as an active span in the context,
// executes the fn function and closes the span before returning the result of fn.
WithSpan(
ctx context.Context,
spanName string,
fn func(ctx context.Context) error,
opts ...StartOption,
) error
}
// EndConfig provides options to set properties of span at the time of ending
// the span.
type EndConfig struct {
EndTime time.Time
}
// EndOption applies changes to EndConfig that sets options when the span is ended.
type EndOption func(*EndConfig)
// WithEndTime sets the end time of the span to provided time t, when it is ended.
func WithEndTime(t time.Time) EndOption {
return func(c *EndConfig) {
c.EndTime = t
}
}
// ErrorConfig provides options to set properties of an error event at the time it is recorded.
type ErrorConfig struct {
Timestamp time.Time
StatusCode codes.Code
}
// ErrorOption applies changes to ErrorConfig that sets options when an error event is recorded.
type ErrorOption func(*ErrorConfig)
// WithErrorTime sets the time at which the error event should be recorded.
func WithErrorTime(t time.Time) ErrorOption {
return func(c *ErrorConfig) {
c.Timestamp = t
}
}
// WithErrorStatus indicates the span status that should be set when recording an error event.
func WithErrorStatus(s codes.Code) ErrorOption {
return func(c *ErrorConfig) {
c.StatusCode = s
}
}
type Span interface {
// Tracer returns tracer used to create this span. Tracer cannot be nil.
Tracer() Tracer
// End completes the span. No updates are allowed to span after it
// ends. The only exception is setting status of the span.
End(options ...EndOption)
// AddEvent adds an event to the span.
AddEvent(ctx context.Context, name string, attrs ...kv.KeyValue)
// AddEventWithTimestamp adds an event with a custom timestamp
// to the span.
AddEventWithTimestamp(ctx context.Context, timestamp time.Time, name string, attrs ...kv.KeyValue)
// IsRecording returns true if the span is active and recording events is enabled.
IsRecording() bool
// RecordError records an error as a span event.
RecordError(ctx context.Context, err error, opts ...ErrorOption)
// SpanContext returns span context of the span. Returned SpanContext is usable
// even after the span ends.
SpanContext() SpanContext
// SetStatus sets the status of the span in the form of a code
// and a message. SetStatus overrides the value of previous
// calls to SetStatus on the Span.
//
// The default span status is OK, so it is not necessary to
// explicitly set an OK status on successful Spans unless it
// is to add an OK message or to override a previous status on the Span.
SetStatus(codes.Code, string)
// SetName sets the name of the span.
SetName(name string)
// Set span attributes
SetAttributes(...kv.KeyValue)
// Set singular span attribute, with type inference.
SetAttribute(string, interface{})
}
// StartOption applies changes to StartConfig that sets options at span start time.
type StartOption func(*StartConfig)
// StartConfig provides options to set properties of span at the time of starting
// a new span.
type StartConfig struct {
Attributes []kv.KeyValue
StartTime time.Time
Links []Link
Record bool
NewRoot bool
SpanKind SpanKind
}
// Link is used to establish relationship between two spans within the same Trace or
// across different Traces. Few examples of Link usage.
// 1. Batch Processing: A batch of elements may contain elements associated with one
// or more traces/spans. Since there can only be one parent SpanContext, Link is
// used to keep reference to SpanContext of all elements in the batch.
// 2. Public Endpoint: A SpanContext in incoming client request on a public endpoint
// is untrusted from service provider perspective. In such case it is advisable to
// start a new trace with appropriate sampling decision.
// However, it is desirable to associate incoming SpanContext to new trace initiated
// on service provider side so two traces (from Client and from Service Provider) can
// be correlated.
type Link struct {
SpanContext
Attributes []kv.KeyValue
}
// SpanKind represents the role of a Span inside a Trace. Often, this defines how a Span
// will be processed and visualized by various backends.
type SpanKind int
const (
// As a convenience, these match the proto definition, see
// opentelemetry/proto/trace/v1/trace.proto
//
// The unspecified value is not a valid `SpanKind`. Use
// `ValidateSpanKind()` to coerce a span kind to a valid
// value.
SpanKindUnspecified SpanKind = 0
SpanKindInternal SpanKind = 1
SpanKindServer SpanKind = 2
SpanKindClient SpanKind = 3
SpanKindProducer SpanKind = 4
SpanKindConsumer SpanKind = 5
)
// ValidateSpanKind returns a valid span kind value. This will coerce
// invalid values into the default value, SpanKindInternal.
func ValidateSpanKind(spanKind SpanKind) SpanKind {
switch spanKind {
case SpanKindInternal,
SpanKindServer,
SpanKindClient,
SpanKindProducer,
SpanKindConsumer:
// valid
return spanKind
default:
return SpanKindInternal
}
}
// String returns the specified name of the SpanKind in lower-case.
func (sk SpanKind) String() string {
switch sk {
case SpanKindInternal:
return "internal"
case SpanKindServer:
return "server"
case SpanKindClient:
return "client"
case SpanKindProducer:
return "producer"
case SpanKindConsumer:
return "consumer"
default:
return "unspecified"
}
}
// WithStartTime sets the start time of the span to provided time t, when it is started.
// In absence of this option, wall clock time is used as start time.
// This option is typically used when starting of the span is delayed.
func WithStartTime(t time.Time) StartOption {
return func(c *StartConfig) {
c.StartTime = t
}
}
// WithAttributes sets attributes to span. These attributes provides additional
// data about the span.
// Multiple `WithAttributes` options appends the attributes preserving the order.
func WithAttributes(attrs ...kv.KeyValue) StartOption {
return func(c *StartConfig) {
c.Attributes = append(c.Attributes, attrs...)
}
}
// WithRecord specifies that the span should be recorded.
// Note that the implementation may still override this preference,
// e.g., if the span is a child in an unsampled trace.
func WithRecord() StartOption {
return func(c *StartConfig) {
c.Record = true
}
}
// WithNewRoot specifies that the current span or remote span context
// in context passed to `Start` should be ignored when deciding about
// a parent, which effectively means creating a span with new trace
// ID. The current span and the remote span context may be added as
// links to the span by the implementation.
func WithNewRoot() StartOption {
return func(c *StartConfig) {
c.NewRoot = true
}
}
// LinkedTo allows instantiating a Span with initial Links.
func LinkedTo(sc SpanContext, attrs ...kv.KeyValue) StartOption {
return func(c *StartConfig) {
c.Links = append(c.Links, Link{sc, attrs})
}
}
// WithSpanKind specifies the role a Span on a Trace.
func WithSpanKind(sk SpanKind) StartOption {
return func(c *StartConfig) {
c.SpanKind = sk
}
}