mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Various changes in response to comments
This commit is contained in:
@@ -2,7 +2,6 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
"github.com/opentracing/opentracing-go/log"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,121 +9,52 @@ import (
|
|||||||
// its main purpose is to wrap the underlying Span in a FnSpan,
|
// its main purpose is to wrap the underlying Span in a FnSpan,
|
||||||
// which adds some extra behaviour required for sending tracing spans to prometheus
|
// which adds some extra behaviour required for sending tracing spans to prometheus
|
||||||
type FnTracer struct {
|
type FnTracer struct {
|
||||||
wrappedTracer opentracing.Tracer
|
opentracing.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFnTracer returns a new FnTracer which wraps the specified Tracer
|
// NewFnTracer returns a new FnTracer which wraps the specified Tracer
|
||||||
func NewFnTracer(tracerToWrap opentracing.Tracer) opentracing.Tracer {
|
func NewFnTracer(t opentracing.Tracer) opentracing.Tracer {
|
||||||
newTracer := &FnTracer{}
|
return &FnTracer{t}
|
||||||
newTracer.wrappedTracer = tracerToWrap
|
|
||||||
return newTracer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FnTracer implements opentracing.Tracer
|
// FnTracer implements opentracing.Tracer
|
||||||
func (thisFnTracer FnTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
|
// Override StartSpan to wrap the returned Span in a FnSpan
|
||||||
return NewFnSpan(thisFnTracer.wrappedTracer.StartSpan(operationName, opts...))
|
func (fnt FnTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
|
||||||
}
|
return NewFnSpan(fnt.Tracer.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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FnSpan is a custom Span that wraps another span
|
// FnSpan is a custom Span that wraps another span
|
||||||
// which adds some extra behaviour required for sending tracing spans to prometheus
|
// which adds some extra behaviour required for sending tracing spans to prometheus
|
||||||
type FnSpan struct {
|
type FnSpan struct {
|
||||||
wrappedSpan opentracing.Span
|
opentracing.Span
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFnSpan returns a new FnSpan which wraps the specified Span
|
// NewFnSpan returns a new FnSpan which wraps the specified Span
|
||||||
func NewFnSpan(spanToWrap opentracing.Span) opentracing.Span {
|
func NewFnSpan(s opentracing.Span) opentracing.Span {
|
||||||
newSpan := &FnSpan{}
|
return &FnSpan{s}
|
||||||
newSpan.wrappedSpan = spanToWrap
|
|
||||||
return newSpan
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FnSpan implements opentracing.Span
|
// FnSpan implements opentracing.Span
|
||||||
func (thisFnSpan FnSpan) Finish() {
|
func (fns FnSpan) Finish() {
|
||||||
thisFnSpan.copyBaggageItemsToTags()
|
fns.copyBaggageItemsToTags()
|
||||||
thisFnSpan.wrappedSpan.Finish()
|
fns.Span.Finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FnSpan implements opentracing.Span
|
// FnSpan implements opentracing.Span
|
||||||
func (thisFnSpan FnSpan) FinishWithOptions(opts opentracing.FinishOptions) {
|
func (fns FnSpan) FinishWithOptions(opts opentracing.FinishOptions) {
|
||||||
thisFnSpan.copyBaggageItemsToTags()
|
fns.copyBaggageItemsToTags()
|
||||||
thisFnSpan.wrappedSpan.FinishWithOptions(opts)
|
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
|
// copy baggage items (which are inherited from the parent) with keys starting with "fn" to tags
|
||||||
// the PrometheusCollector will send these to Prometheus
|
// the PrometheusCollector will send these to Prometheus
|
||||||
// need to do this because the collector can't access baggage items, but it can access tags
|
// 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
|
// 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") {
|
if strings.HasPrefix(k, "fn") {
|
||||||
thisFnSpan.SetTag(k, v)
|
fns.SetTag(k, v)
|
||||||
}
|
}
|
||||||
return true
|
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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fnproject/fn/api/agent"
|
|
||||||
"github.com/openzipkin/zipkin-go-opentracing"
|
"github.com/openzipkin/zipkin-go-opentracing"
|
||||||
"github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
|
"github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Each span name is published as a separate Histogram metric
|
// PrometheusCollector is a custom Collector
|
||||||
// Using metric names of the form fn_span_<span-name>_duration_seconds
|
// which sends ZipKin traces to Prometheus
|
||||||
var histogramVecMap = make(map[string]*prometheus.HistogramVec)
|
type PrometheusCollector struct {
|
||||||
|
|
||||||
|
// Each span name is published as a separate Histogram metric
|
||||||
|
// Using metric names of the form fn_span_<span-name>_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.
|
// 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
|
// 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.
|
// otherwise the labels parameter is ignored.
|
||||||
func getHistogramVecForSpanName(spanName string, labels []string) *prometheus.HistogramVec {
|
func (pc PrometheusCollector) getHistogramVecForSpanName(spanName string, labels []string) *prometheus.HistogramVec {
|
||||||
thisHistogramVec, found := histogramVecMap[spanName]
|
thisHistogramVec, found := pc.histogramVecMap[spanName]
|
||||||
if !found {
|
if !found {
|
||||||
thisHistogramVec = prometheus.NewHistogramVec(
|
thisHistogramVec = prometheus.NewHistogramVec(
|
||||||
prometheus.HistogramOpts{
|
prometheus.HistogramOpts{
|
||||||
@@ -25,33 +36,19 @@ func getHistogramVecForSpanName(spanName string, labels []string) *prometheus.Hi
|
|||||||
},
|
},
|
||||||
labels,
|
labels,
|
||||||
)
|
)
|
||||||
histogramVecMap[spanName] = thisHistogramVec
|
pc.histogramVecMap[spanName] = thisHistogramVec
|
||||||
prometheus.MustRegister(thisHistogramVec)
|
prometheus.MustRegister(thisHistogramVec)
|
||||||
}
|
}
|
||||||
return 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.
|
// PrometheusCollector implements Collector.
|
||||||
func (pc PrometheusCollector) Collect(span *zipkincore.Span) error {
|
func (pc PrometheusCollector) Collect(span *zipkincore.Span) error {
|
||||||
|
|
||||||
// extract any label values from the span
|
// extract any label values from the span
|
||||||
labelKeys, labelValueMap := getLabels(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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func (s *Server) setTracer() {
|
|||||||
var collector zipkintracer.Collector
|
var collector zipkintracer.Collector
|
||||||
|
|
||||||
// custom Zipkin collector to send tracing spans to Prometheus
|
// custom Zipkin collector to send tracing spans to Prometheus
|
||||||
promCollector, promErr := NewPrometheusCollector(s.Agent)
|
promCollector, promErr := NewPrometheusCollector()
|
||||||
if promErr != nil {
|
if promErr != nil {
|
||||||
logrus.WithError(promErr).Fatalln("couldn't start Prometheus trace collector")
|
logrus.WithError(promErr).Fatalln("couldn't start Prometheus trace collector")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user