mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-27 02:54:27 +01:00
Add initial support for opentracing by using the `jaeger` package.
Since opentracing uses the `context` package, add a `context.Context`
as the first parameter to all the functions that we might want to
trace. Trace "spans" (trace points) are then added by extracting the
trace details from the specified context parameter.
Notes:
- Although the tracer is created in `main()`, the "root span"
(aka the first trace point) is not added until `beforeSubcommands()`.
This is by design and is a compromise: by delaying the creation of the
root span, the spans become much more readable since using the web-based
JaegerUI, you will see traces like this:
```
kata-runtime: kata-runtime create
------------ -------------------
^ ^
| |
Trace name First span name
(which clearly shows the CLI command that was run)
```
Creating the span earlier means it is necessary to expand 'n' spans in
the UI before you get to see the name of the CLI command that was run.
In adding support, this became very tedious, hence my design decision to
defer the creation of the root span until after signal handling has been
setup and after CLI options have been parsed, but still very early in
the code path.
- At this stage, the tracing stops at the `virtcontainers` call
boundary.
- Tracing is "always on" as there doesn't appear to be a way to toggle
it. However, its resolves to a "nop" unless the tracer can talk to a
jaeger agent.
Note that this commit required a bit of rework to `beforeSubcommands()`
to reduce the cyclomatic complexity.
Fixes #557.
Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
154 lines
4.7 KiB
Go
154 lines
4.7 KiB
Go
// Copyright (c) 2017 Uber Technologies, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package jaeger
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/opentracing/opentracing-go"
|
|
|
|
"github.com/uber/jaeger-client-go/internal/baggage"
|
|
"github.com/uber/jaeger-client-go/internal/throttler"
|
|
)
|
|
|
|
// TracerOption is a function that sets some option on the tracer
|
|
type TracerOption func(tracer *Tracer)
|
|
|
|
// TracerOptions is a factory for all available TracerOption's
|
|
var TracerOptions tracerOptions
|
|
|
|
type tracerOptions struct{}
|
|
|
|
// Metrics creates a TracerOption that initializes Metrics on the tracer,
|
|
// which is used to emit statistics.
|
|
func (tracerOptions) Metrics(m *Metrics) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.metrics = *m
|
|
}
|
|
}
|
|
|
|
// Logger creates a TracerOption that gives the tracer a Logger.
|
|
func (tracerOptions) Logger(logger Logger) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.logger = logger
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) CustomHeaderKeys(headerKeys *HeadersConfig) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
if headerKeys == nil {
|
|
return
|
|
}
|
|
textPropagator := newTextMapPropagator(headerKeys.applyDefaults(), tracer.metrics)
|
|
tracer.addCodec(opentracing.TextMap, textPropagator, textPropagator)
|
|
|
|
httpHeaderPropagator := newHTTPHeaderPropagator(headerKeys.applyDefaults(), tracer.metrics)
|
|
tracer.addCodec(opentracing.HTTPHeaders, httpHeaderPropagator, httpHeaderPropagator)
|
|
}
|
|
}
|
|
|
|
// TimeNow creates a TracerOption that gives the tracer a function
|
|
// used to generate timestamps for spans.
|
|
func (tracerOptions) TimeNow(timeNow func() time.Time) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.timeNow = timeNow
|
|
}
|
|
}
|
|
|
|
// RandomNumber creates a TracerOption that gives the tracer
|
|
// a thread-safe random number generator function for generating trace IDs.
|
|
func (tracerOptions) RandomNumber(randomNumber func() uint64) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.randomNumber = randomNumber
|
|
}
|
|
}
|
|
|
|
// PoolSpans creates a TracerOption that tells the tracer whether it should use
|
|
// an object pool to minimize span allocations.
|
|
// This should be used with care, only if the service is not running any async tasks
|
|
// that can access parent spans after those spans have been finished.
|
|
func (tracerOptions) PoolSpans(poolSpans bool) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.options.poolSpans = poolSpans
|
|
}
|
|
}
|
|
|
|
// Deprecated: HostIPv4 creates a TracerOption that identifies the current service/process.
|
|
// If not set, the factory method will obtain the current IP address.
|
|
// The TracerOption is deprecated; the tracer will attempt to automatically detect the IP.
|
|
func (tracerOptions) HostIPv4(hostIPv4 uint32) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.hostIPv4 = hostIPv4
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) Injector(format interface{}, injector Injector) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.injectors[format] = injector
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) Extractor(format interface{}, extractor Extractor) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.extractors[format] = extractor
|
|
}
|
|
}
|
|
|
|
func (t tracerOptions) Observer(observer Observer) TracerOption {
|
|
return t.ContribObserver(&oldObserver{obs: observer})
|
|
}
|
|
|
|
func (tracerOptions) ContribObserver(observer ContribObserver) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.observer.append(observer)
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) Gen128Bit(gen128Bit bool) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.options.gen128Bit = gen128Bit
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) HighTraceIDGenerator(highTraceIDGenerator func() uint64) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.options.highTraceIDGenerator = highTraceIDGenerator
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) ZipkinSharedRPCSpan(zipkinSharedRPCSpan bool) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.options.zipkinSharedRPCSpan = zipkinSharedRPCSpan
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) Tag(key string, value interface{}) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.tags = append(tracer.tags, Tag{key: key, value: value})
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) BaggageRestrictionManager(mgr baggage.RestrictionManager) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.baggageRestrictionManager = mgr
|
|
}
|
|
}
|
|
|
|
func (tracerOptions) DebugThrottler(throttler throttler.Throttler) TracerOption {
|
|
return func(tracer *Tracer) {
|
|
tracer.debugThrottler = throttler
|
|
}
|
|
}
|