github.com/xmidt-org/webpa-common@v1.11.9/tracing/spanner.go (about) 1 package tracing 2 3 import ( 4 "time" 5 ) 6 7 // Spanner acts as a factory for Spans 8 type Spanner interface { 9 // Start begins a new, unfinished span. The returned closure must be called 10 // to finished the span, recording it with a duration and the given error. The 11 // returned closure is idempotent and only records the duration and error of the first call. 12 // It always returns the same Span instance, and that instance is immutable once the 13 // closure is called. 14 Start(string) func(error) Span 15 } 16 17 // SpannerOption supplies a configuration option to a Spanner. 18 type SpannerOption func(*spanner) 19 20 // Now sets a now function on a spanner. If now is nil, this option does nothing. 21 // This options is primarily useful for testing, however it can be useful in production 22 // situations. For example, this option can be used to emit times with a consistent time zone, like UTC. 23 func Now(now func() time.Time) SpannerOption { 24 return func(sp *spanner) { 25 if now != nil { 26 sp.now = now 27 } 28 } 29 } 30 31 // Since sets a since function on a spanner. If since is nil, this option does nothing. 32 // This options is primarily useful for testing. 33 func Since(since func(time.Time) time.Duration) SpannerOption { 34 return func(sp *spanner) { 35 if since != nil { 36 sp.since = since 37 } 38 } 39 } 40 41 // NewSpanner constructs a new Spanner with the given options. By default, a Spanner 42 // will use time.Now() to get the current time and time.Since() to compute durations. 43 func NewSpanner(o ...SpannerOption) Spanner { 44 sp := &spanner{ 45 now: time.Now, 46 since: time.Since, 47 } 48 49 for _, option := range o { 50 option(sp) 51 } 52 53 return sp 54 } 55 56 // spanner is the internal spanner implementation. 57 type spanner struct { 58 now func() time.Time 59 since func(time.Time) time.Duration 60 } 61 62 func (sp *spanner) Start(name string) func(error) Span { 63 s := &span{ 64 name: name, 65 start: sp.now(), 66 } 67 68 return func(err error) Span { 69 s.finish(sp.since(s.start), err) 70 return s 71 } 72 }