github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/collector.go (about) 1 // (c) Copyright IBM Corp. 2023 2 3 package instana 4 5 import ( 6 "context" 7 8 ot "github.com/opentracing/opentracing-go" 9 ) 10 11 // TracerLogger represents the Instana Go collector and is composed by a tracer, a logger and a reference to the legacy sensor. 12 type TracerLogger interface { 13 Tracer 14 LeveledLogger 15 LegacySensor() *Sensor 16 SensorLogger 17 } 18 19 // Collector is used to inject tracing information into requests 20 type Collector struct { 21 t Tracer 22 LeveledLogger 23 *Sensor 24 } 25 26 var _ TracerLogger = (*Collector)(nil) 27 28 // InitCollector creates a new [Collector] 29 func InitCollector(opts *Options) TracerLogger { 30 31 // if instana.C is already an instance of Collector, we just return 32 if _, ok := C.(*Collector); ok { 33 C.Warn("InitCollector was previously called. instana.C is reused") 34 return C 35 } 36 37 if opts == nil { 38 opts = &Options{ 39 Recorder: NewRecorder(), 40 } 41 } 42 43 if opts.Recorder == nil { 44 opts.Recorder = NewRecorder() 45 } 46 47 StartMetrics(opts) 48 49 tracer := &tracerS{ 50 recorder: opts.Recorder, 51 } 52 53 C = &Collector{ 54 t: tracer, 55 LeveledLogger: defaultLogger, 56 Sensor: NewSensorWithTracer(tracer), 57 } 58 59 return C 60 } 61 62 // Extract() returns a SpanContext instance given `format` and `carrier`. It matches [opentracing.Tracer.Extract]. 63 func (c *Collector) Extract(format interface{}, carrier interface{}) (ot.SpanContext, error) { 64 return c.t.Extract(format, carrier) 65 } 66 67 // Inject() takes the `sm` SpanContext instance and injects it for 68 // propagation within `carrier`. The actual type of `carrier` depends on 69 // the value of `format`. It matches [opentracing.Tracer.Inject] 70 func (c *Collector) Inject(sm ot.SpanContext, format interface{}, carrier interface{}) error { 71 return c.t.Inject(sm, format, carrier) 72 } 73 74 // Create, start, and return a new Span with the given `operationName` and 75 // incorporate the given StartSpanOption `opts`. (Note that `opts` borrows 76 // from the "functional options" pattern, per 77 // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis) 78 // 79 // It matches [opentracing.Tracer.StartSpan]. 80 func (c *Collector) StartSpan(operationName string, opts ...ot.StartSpanOption) ot.Span { 81 return c.t.StartSpan(operationName, opts...) 82 } 83 84 // StartSpanWithOptions creates and starts a span by setting Instana relevant data within the span. 85 // It matches [instana.Tracer.StartSpanWithOptions]. 86 func (c *Collector) StartSpanWithOptions(operationName string, opts ot.StartSpanOptions) ot.Span { 87 return c.t.StartSpanWithOptions(operationName, opts) 88 } 89 90 // Options gets the current tracer options 91 // It matches [instana.Tracer.Options]. 92 func (c *Collector) Options() TracerOptions { 93 return c.t.Options() 94 } 95 96 // Flush sends all finished spans to the agent 97 // It matches [instana.Tracer.Flush]. 98 func (c *Collector) Flush(ctx context.Context) error { 99 return c.t.Flush(ctx) 100 } 101 102 // Debug logs a debug message by calling [LeveledLogger] underneath 103 func (c *Collector) Debug(v ...interface{}) { 104 c.LeveledLogger.Debug(v...) 105 } 106 107 // Info logs an info message by calling [LeveledLogger] underneath 108 func (c *Collector) Info(v ...interface{}) { 109 c.LeveledLogger.Info(v...) 110 } 111 112 // Warn logs a warning message by calling [LeveledLogger] underneath 113 func (c *Collector) Warn(v ...interface{}) { 114 c.LeveledLogger.Warn(v...) 115 } 116 117 // Error logs a error message by calling [LeveledLogger] underneath 118 func (c *Collector) Error(v ...interface{}) { 119 c.LeveledLogger.Error(v...) 120 } 121 122 // SetLogger changes the [Sensor] logger and [LeveledLogger] both to satisfy [TracerLogger] 123 func (c *Collector) SetLogger(l LeveledLogger) { 124 c.Sensor.SetLogger(l) 125 c.LeveledLogger = l 126 } 127 128 // LegacySensor returns a reference to [Sensor] that can be used for old instrumentations that still require it. 129 // 130 // Example: 131 // 132 // // Instrumenting HTTP incoming calls 133 // c := instana.InitCollector("my-service") 134 // http.HandleFunc("/", instana.TracingNamedHandlerFunc(c.LegacySensor(), "", "/{name}", handle)) 135 func (c *Collector) LegacySensor() *Sensor { 136 return c.Sensor 137 }