blob: 0d3fb53418382d1c05b27ed16ce540b469303a9c [file] [log] [blame]
Matteo Scandoloa4285862020-12-01 18:10:10 -08001package opentracing
2
3import (
4 "time"
5
6 "github.com/opentracing/opentracing-go/log"
7)
8
9// SpanContext represents Span state that must propagate to descendant Spans and across process
10// boundaries (e.g., a <trace_id, span_id, sampled> tuple).
11type SpanContext interface {
12 // ForeachBaggageItem grants access to all baggage items stored in the
13 // SpanContext.
14 // The handler function will be called for each baggage key/value pair.
15 // The ordering of items is not guaranteed.
16 //
17 // The bool return value indicates if the handler wants to continue iterating
18 // through the rest of the baggage items; for example if the handler is trying to
19 // find some baggage item by pattern matching the name, it can return false
20 // as soon as the item is found to stop further iterations.
21 ForeachBaggageItem(handler func(k, v string) bool)
22}
23
24// Span represents an active, un-finished span in the OpenTracing system.
25//
26// Spans are created by the Tracer interface.
27type Span interface {
28 // Sets the end timestamp and finalizes Span state.
29 //
30 // With the exception of calls to Context() (which are always allowed),
31 // Finish() must be the last call made to any span instance, and to do
32 // otherwise leads to undefined behavior.
33 Finish()
34 // FinishWithOptions is like Finish() but with explicit control over
35 // timestamps and log data.
36 FinishWithOptions(opts FinishOptions)
37
38 // Context() yields the SpanContext for this Span. Note that the return
39 // value of Context() is still valid after a call to Span.Finish(), as is
40 // a call to Span.Context() after a call to Span.Finish().
41 Context() SpanContext
42
43 // Sets or changes the operation name.
44 //
45 // Returns a reference to this Span for chaining.
46 SetOperationName(operationName string) Span
47
48 // Adds a tag to the span.
49 //
50 // If there is a pre-existing tag set for `key`, it is overwritten.
51 //
52 // Tag values can be numeric types, strings, or bools. The behavior of
53 // other tag value types is undefined at the OpenTracing level. If a
54 // tracing system does not know how to handle a particular value type, it
55 // may ignore the tag, but shall not panic.
56 //
57 // Returns a reference to this Span for chaining.
58 SetTag(key string, value interface{}) Span
59
60 // LogFields is an efficient and type-checked way to record key:value
61 // logging data about a Span, though the programming interface is a little
62 // more verbose than LogKV(). Here's an example:
63 //
64 // span.LogFields(
65 // log.String("event", "soft error"),
66 // log.String("type", "cache timeout"),
67 // log.Int("waited.millis", 1500))
68 //
69 // Also see Span.FinishWithOptions() and FinishOptions.BulkLogData.
70 LogFields(fields ...log.Field)
71
72 // LogKV is a concise, readable way to record key:value logging data about
73 // a Span, though unfortunately this also makes it less efficient and less
74 // type-safe than LogFields(). Here's an example:
75 //
76 // span.LogKV(
77 // "event", "soft error",
78 // "type", "cache timeout",
79 // "waited.millis", 1500)
80 //
81 // For LogKV (as opposed to LogFields()), the parameters must appear as
82 // key-value pairs, like
83 //
84 // span.LogKV(key1, val1, key2, val2, key3, val3, ...)
85 //
86 // The keys must all be strings. The values may be strings, numeric types,
87 // bools, Go error instances, or arbitrary structs.
88 //
89 // (Note to implementors: consider the log.InterleavedKVToFields() helper)
90 LogKV(alternatingKeyValues ...interface{})
91
92 // SetBaggageItem sets a key:value pair on this Span and its SpanContext
93 // that also propagates to descendants of this Span.
94 //
95 // SetBaggageItem() enables powerful functionality given a full-stack
96 // opentracing integration (e.g., arbitrary application data from a mobile
97 // app can make it, transparently, all the way into the depths of a storage
98 // system), and with it some powerful costs: use this feature with care.
99 //
100 // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to
101 // *future* causal descendants of the associated Span.
102 //
103 // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and
104 // value is copied into every local *and remote* child of the associated
105 // Span, and that can add up to a lot of network and cpu overhead.
106 //
107 // Returns a reference to this Span for chaining.
108 SetBaggageItem(restrictedKey, value string) Span
109
110 // Gets the value for a baggage item given its key. Returns the empty string
111 // if the value isn't found in this Span.
112 BaggageItem(restrictedKey string) string
113
114 // Provides access to the Tracer that created this Span.
115 Tracer() Tracer
116
117 // Deprecated: use LogFields or LogKV
118 LogEvent(event string)
119 // Deprecated: use LogFields or LogKV
120 LogEventWithPayload(event string, payload interface{})
121 // Deprecated: use LogFields or LogKV
122 Log(data LogData)
123}
124
125// LogRecord is data associated with a single Span log. Every LogRecord
126// instance must specify at least one Field.
127type LogRecord struct {
128 Timestamp time.Time
129 Fields []log.Field
130}
131
132// FinishOptions allows Span.FinishWithOptions callers to override the finish
133// timestamp and provide log data via a bulk interface.
134type FinishOptions struct {
135 // FinishTime overrides the Span's finish time, or implicitly becomes
136 // time.Now() if FinishTime.IsZero().
137 //
138 // FinishTime must resolve to a timestamp that's >= the Span's StartTime
139 // (per StartSpanOptions).
140 FinishTime time.Time
141
142 // LogRecords allows the caller to specify the contents of many LogFields()
143 // calls with a single slice. May be nil.
144 //
145 // None of the LogRecord.Timestamp values may be .IsZero() (i.e., they must
146 // be set explicitly). Also, they must be >= the Span's start timestamp and
147 // <= the FinishTime (or time.Now() if FinishTime.IsZero()). Otherwise the
148 // behavior of FinishWithOptions() is undefined.
149 //
150 // If specified, the caller hands off ownership of LogRecords at
151 // FinishWithOptions() invocation time.
152 //
153 // If specified, the (deprecated) BulkLogData must be nil or empty.
154 LogRecords []LogRecord
155
156 // BulkLogData is DEPRECATED.
157 BulkLogData []LogData
158}
159
160// LogData is DEPRECATED
161type LogData struct {
162 Timestamp time.Time
163 Event string
164 Payload interface{}
165}
166
167// ToLogRecord converts a deprecated LogData to a non-deprecated LogRecord
168func (ld *LogData) ToLogRecord() LogRecord {
169 var literalTimestamp time.Time
170 if ld.Timestamp.IsZero() {
171 literalTimestamp = time.Now()
172 } else {
173 literalTimestamp = ld.Timestamp
174 }
175 rval := LogRecord{
176 Timestamp: literalTimestamp,
177 }
178 if ld.Payload == nil {
179 rval.Fields = []log.Field{
180 log.String("event", ld.Event),
181 }
182 } else {
183 rval.Fields = []log.Field{
184 log.String("event", ld.Event),
185 log.Object("payload", ld.Payload),
186 }
187 }
188 return rval
189}