1 package opentracing 2 3 import ( 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). 11 type 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. 27 type 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. 127 type 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. 134 type 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 161 type 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 168 func (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 } 190