github.com/mailgun/holster/v4@v4.20.0/tracing/prometheus.go (about)

     1  package tracing
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/prometheus/client_golang/prometheus"
     7  	"go.opentelemetry.io/otel/codes"
     8  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
     9  )
    10  
    11  // MetricSpanProcessor implements SpanProcessor as a middleware to track
    12  // via Prometheus metrics before export.
    13  type MetricSpanProcessor struct {
    14  	next sdktrace.SpanProcessor
    15  }
    16  
    17  var (
    18  	traceCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
    19  		Name: "holster_tracing_counter",
    20  		Help: "Count of traces generated by holster `tracing` package.",
    21  	}, []string{"error"})
    22  	spanCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
    23  		Name: "holster_tracing_spans",
    24  		Help: "Count of trace spans generated by holster `tracing` package.",
    25  	}, []string{"error"})
    26  
    27  	// Metrics contains Prometheus metrics available for use.
    28  	Metrics = []prometheus.Collector{
    29  		traceCounter,
    30  		spanCounter,
    31  	}
    32  )
    33  
    34  func NewMetricSpanProcessor(next sdktrace.SpanProcessor) *MetricSpanProcessor {
    35  	return &MetricSpanProcessor{
    36  		next: next,
    37  	}
    38  }
    39  
    40  func (p *MetricSpanProcessor) OnStart(parent context.Context, s sdktrace.ReadWriteSpan) {
    41  	p.next.OnStart(parent, s)
    42  }
    43  
    44  func (p *MetricSpanProcessor) OnEnd(s sdktrace.ReadOnlySpan) {
    45  	var errorVec string
    46  	if s.Status().Code == codes.Error {
    47  		errorVec = "true"
    48  	}
    49  
    50  	if !s.Parent().HasTraceID() {
    51  		traceCounter.WithLabelValues(errorVec).Add(1)
    52  	}
    53  
    54  	spanCounter.WithLabelValues(errorVec).Add(1)
    55  
    56  	p.next.OnEnd(s)
    57  }
    58  
    59  func (p *MetricSpanProcessor) Shutdown(ctx context.Context) error {
    60  	return p.next.Shutdown(ctx)
    61  }
    62  
    63  func (p *MetricSpanProcessor) ForceFlush(ctx context.Context) error {
    64  	return p.next.ForceFlush(ctx)
    65  }