mirror of https://github.com/knative/caching.git
137 lines
3.1 KiB
Go
137 lines
3.1 KiB
Go
package tracing
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
|
|
zipkinmodel "github.com/openzipkin/zipkin-go/model"
|
|
zipkinreporter "github.com/openzipkin/zipkin-go/reporter"
|
|
"go.opencensus.io/exporter/zipkin"
|
|
"go.opencensus.io/trace"
|
|
"knative.dev/pkg/tracing/config"
|
|
)
|
|
|
|
// ConfigOption is the interface for adding additional exporters and configuring opencensus tracing.
|
|
type ConfigOption func(*config.Config)
|
|
|
|
// OpenCensusTracer is responsible for managing and updating configuration of OpenCensus tracing
|
|
type OpenCensusTracer struct {
|
|
curCfg *config.Config
|
|
configOptions []ConfigOption
|
|
zipkinReporter zipkinreporter.Reporter
|
|
zipkinExporter trace.Exporter
|
|
}
|
|
|
|
// OpenCensus tracing keeps state in globals and therefore we can only run one OpenCensusTracer
|
|
var (
|
|
octMutex sync.Mutex
|
|
globalOct *OpenCensusTracer
|
|
)
|
|
|
|
func NewOpenCensusTracer(configOptions ...ConfigOption) *OpenCensusTracer {
|
|
return &OpenCensusTracer{
|
|
configOptions: configOptions,
|
|
}
|
|
}
|
|
|
|
func (oct *OpenCensusTracer) ApplyConfig(cfg *config.Config) error {
|
|
err := oct.acquireGlobal()
|
|
defer octMutex.Unlock()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Short circuit if our config hasnt changed
|
|
if oct.curCfg != nil && oct.curCfg.Equals(cfg) {
|
|
return nil
|
|
}
|
|
|
|
// Apply config options
|
|
for _, configOpt := range oct.configOptions {
|
|
configOpt(cfg)
|
|
}
|
|
|
|
// Set config
|
|
trace.ApplyConfig(*createOCTConfig(cfg))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (oct *OpenCensusTracer) Finish() error {
|
|
err := oct.acquireGlobal()
|
|
defer octMutex.Unlock()
|
|
if err != nil {
|
|
return errors.New("Finish called on OpenTracer which is not the global OpenCensusTracer.")
|
|
}
|
|
|
|
for _, configOpt := range oct.configOptions {
|
|
configOpt(nil)
|
|
}
|
|
globalOct = nil
|
|
|
|
return nil
|
|
}
|
|
|
|
func (oct *OpenCensusTracer) acquireGlobal() error {
|
|
octMutex.Lock()
|
|
|
|
if globalOct == nil {
|
|
globalOct = oct
|
|
} else if globalOct != oct {
|
|
return errors.New("A OpenCensusTracer already exists and only one can be run at a time.")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createOCTConfig(cfg *config.Config) *trace.Config {
|
|
octCfg := trace.Config{}
|
|
|
|
if cfg.Enable {
|
|
if cfg.Debug {
|
|
octCfg.DefaultSampler = trace.AlwaysSample()
|
|
} else {
|
|
octCfg.DefaultSampler = trace.ProbabilitySampler(cfg.SampleRate)
|
|
}
|
|
} else {
|
|
octCfg.DefaultSampler = trace.NeverSample()
|
|
}
|
|
|
|
return &octCfg
|
|
}
|
|
|
|
func WithZipkinExporter(reporterFact ZipkinReporterFactory, endpoint *zipkinmodel.Endpoint) ConfigOption {
|
|
return func(cfg *config.Config) {
|
|
var (
|
|
reporter zipkinreporter.Reporter
|
|
exporter trace.Exporter
|
|
)
|
|
|
|
if cfg != nil && cfg.Enable {
|
|
// Initialize our reporter / exporter
|
|
// do this before cleanup to minimize time where we have duplicate exporters
|
|
reporter, err := reporterFact(cfg)
|
|
if err != nil {
|
|
// TODO(greghaynes) log this error
|
|
return
|
|
}
|
|
exporter := zipkin.NewExporter(reporter, endpoint)
|
|
trace.RegisterExporter(exporter)
|
|
}
|
|
|
|
// We know this is set because we are called with acquireGlobal lock held
|
|
oct := globalOct
|
|
if oct.zipkinExporter != nil {
|
|
trace.UnregisterExporter(oct.zipkinExporter)
|
|
}
|
|
|
|
if oct.zipkinReporter != nil {
|
|
// TODO(greghaynes) log this error
|
|
_ = oct.zipkinReporter.Close()
|
|
}
|
|
|
|
oct.zipkinReporter = reporter
|
|
oct.zipkinExporter = exporter
|
|
}
|
|
}
|