diff --git a/api/server/fntracer.go b/api/server/fntracer.go index 6abe92044..ce65c6944 100644 --- a/api/server/fntracer.go +++ b/api/server/fntracer.go @@ -2,7 +2,6 @@ package server import ( "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/log" "strings" ) @@ -10,121 +9,52 @@ import ( // its main purpose is to wrap the underlying Span in a FnSpan, // which adds some extra behaviour required for sending tracing spans to prometheus type FnTracer struct { - wrappedTracer opentracing.Tracer + opentracing.Tracer } // NewFnTracer returns a new FnTracer which wraps the specified Tracer -func NewFnTracer(tracerToWrap opentracing.Tracer) opentracing.Tracer { - newTracer := &FnTracer{} - newTracer.wrappedTracer = tracerToWrap - return newTracer +func NewFnTracer(t opentracing.Tracer) opentracing.Tracer { + return &FnTracer{t} } // FnTracer implements opentracing.Tracer -func (thisFnTracer FnTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span { - return NewFnSpan(thisFnTracer.wrappedTracer.StartSpan(operationName, opts...)) -} - -// FnTracer implements opentracing.Tracer -func (thisFnTracer FnTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error { - return thisFnTracer.wrappedTracer.Inject(sm, format, carrier) - -} - -// FnTracer implements opentracing.Tracer -func (thisFnTracer FnTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) { - return thisFnTracer.wrappedTracer.Extract(format, carrier) +// Override StartSpan to wrap the returned Span in a FnSpan +func (fnt FnTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span { + return NewFnSpan(fnt.Tracer.StartSpan(operationName, opts...)) } // FnSpan is a custom Span that wraps another span // which adds some extra behaviour required for sending tracing spans to prometheus type FnSpan struct { - wrappedSpan opentracing.Span + opentracing.Span } // NewFnSpan returns a new FnSpan which wraps the specified Span -func NewFnSpan(spanToWrap opentracing.Span) opentracing.Span { - newSpan := &FnSpan{} - newSpan.wrappedSpan = spanToWrap - return newSpan +func NewFnSpan(s opentracing.Span) opentracing.Span { + return &FnSpan{s} } // FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) Finish() { - thisFnSpan.copyBaggageItemsToTags() - thisFnSpan.wrappedSpan.Finish() +func (fns FnSpan) Finish() { + fns.copyBaggageItemsToTags() + fns.Span.Finish() } // FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) FinishWithOptions(opts opentracing.FinishOptions) { - thisFnSpan.copyBaggageItemsToTags() - thisFnSpan.wrappedSpan.FinishWithOptions(opts) +func (fns FnSpan) FinishWithOptions(opts opentracing.FinishOptions) { + fns.copyBaggageItemsToTags() + fns.Span.FinishWithOptions(opts) } -func (thisFnSpan FnSpan) copyBaggageItemsToTags() { +func (fns FnSpan) copyBaggageItemsToTags() { // copy baggage items (which are inherited from the parent) with keys starting with "fn" to tags // the PrometheusCollector will send these to Prometheus // need to do this because the collector can't access baggage items, but it can access tags // whereas here we can access the parent's baggage items, but not its tags - thisFnSpan.Context().ForeachBaggageItem(func(k, v string) bool { + fns.Context().ForeachBaggageItem(func(k, v string) bool { if strings.HasPrefix(k, "fn") { - thisFnSpan.SetTag(k, v) + fns.SetTag(k, v) } return true }) } - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) Context() opentracing.SpanContext { - return thisFnSpan.wrappedSpan.Context() -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) SetOperationName(operationName string) opentracing.Span { - return thisFnSpan.wrappedSpan.SetOperationName(operationName) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) SetTag(key string, value interface{}) opentracing.Span { - return thisFnSpan.wrappedSpan.SetTag(key, value) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) LogFields(fields ...log.Field) { - thisFnSpan.wrappedSpan.LogFields(fields...) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) LogKV(alternatingKeyValues ...interface{}) { - thisFnSpan.wrappedSpan.LogKV(alternatingKeyValues...) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) SetBaggageItem(restrictedKey, value string) opentracing.Span { - return thisFnSpan.wrappedSpan.SetBaggageItem(restrictedKey, value) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) BaggageItem(restrictedKey string) string { - return thisFnSpan.wrappedSpan.BaggageItem(restrictedKey) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) Tracer() opentracing.Tracer { - return thisFnSpan.wrappedSpan.Tracer() -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) LogEvent(event string) { - thisFnSpan.wrappedSpan.LogEvent(event) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) LogEventWithPayload(event string, payload interface{}) { - thisFnSpan.wrappedSpan.LogEventWithPayload(event, payload) -} - -// FnSpan implements opentracing.Span -func (thisFnSpan FnSpan) Log(data opentracing.LogData) { - thisFnSpan.wrappedSpan.Log(data) -} diff --git a/api/server/prom_zip_collector.go b/api/server/prom_zip_collector.go index e2d4fcd9d..a8034329a 100644 --- a/api/server/prom_zip_collector.go +++ b/api/server/prom_zip_collector.go @@ -1,22 +1,33 @@ package server import ( - "github.com/fnproject/fn/api/agent" "github.com/openzipkin/zipkin-go-opentracing" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore" "github.com/prometheus/client_golang/prometheus" "strings" + "time" ) -// Each span name is published as a separate Histogram metric -// Using metric names of the form fn_span__duration_seconds -var histogramVecMap = make(map[string]*prometheus.HistogramVec) +// PrometheusCollector is a custom Collector +// which sends ZipKin traces to Prometheus +type PrometheusCollector struct { + + // Each span name is published as a separate Histogram metric + // Using metric names of the form fn_span__duration_seconds + histogramVecMap map[string]*prometheus.HistogramVec +} + +// NewPrometheusCollector returns a new PrometheusCollector +func NewPrometheusCollector() (zipkintracer.Collector, error) { + pc := &PrometheusCollector{make(map[string]*prometheus.HistogramVec)} + return pc, nil +} // Return the HistogramVec corresponding to the specified spanName. // If a HistogramVec does not already exist for specified spanName then one is created and configured with the specified labels // otherwise the labels parameter is ignored. -func getHistogramVecForSpanName(spanName string, labels []string) *prometheus.HistogramVec { - thisHistogramVec, found := histogramVecMap[spanName] +func (pc PrometheusCollector) getHistogramVecForSpanName(spanName string, labels []string) *prometheus.HistogramVec { + thisHistogramVec, found := pc.histogramVecMap[spanName] if !found { thisHistogramVec = prometheus.NewHistogramVec( prometheus.HistogramOpts{ @@ -25,33 +36,19 @@ func getHistogramVecForSpanName(spanName string, labels []string) *prometheus.Hi }, labels, ) - histogramVecMap[spanName] = thisHistogramVec + pc.histogramVecMap[spanName] = thisHistogramVec prometheus.MustRegister(thisHistogramVec) } return thisHistogramVec } -// PrometheusCollector is a custom Collector -// which sends ZipKin traces to Prometheus -type PrometheusCollector struct { - a agent.Agent -} - -// NewPrometheusCollector returns a new PrometheusCollector -func NewPrometheusCollector(agent agent.Agent) (zipkintracer.Collector, error) { - pc := &PrometheusCollector{} - pc.a = agent - return pc, nil -} - // PrometheusCollector implements Collector. func (pc PrometheusCollector) Collect(span *zipkincore.Span) error { // extract any label values from the span labelKeys, labelValueMap := getLabels(span) - getHistogramVecForSpanName(span.GetName(), labelKeys).With(labelValueMap).Observe(float64(span.GetDuration()) / 1000000) - + pc.getHistogramVecForSpanName(span.GetName(), labelKeys).With(labelValueMap).Observe((time.Duration(span.GetDuration()) * time.Microsecond).Seconds()) return nil } diff --git a/api/server/server.go b/api/server/server.go index d6d865e73..1576ada30 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -129,7 +129,7 @@ func (s *Server) setTracer() { var collector zipkintracer.Collector // custom Zipkin collector to send tracing spans to Prometheus - promCollector, promErr := NewPrometheusCollector(s.Agent) + promCollector, promErr := NewPrometheusCollector() if promErr != nil { logrus.WithError(promErr).Fatalln("couldn't start Prometheus trace collector") }