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  }