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 }