span.go 6.4 KB

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