Documentation
¶
Overview ¶
Package tracing provides tracing integration with zipkin.
For thrift services, they should call StartSpanFromThriftContext with the context object injected by thrift library to get a root span for the thrift handler function, then call CreateChildSpan to create child-spans. This is handled by thriftbp.InjectServerSpan processor middleware, and that's one of the default middlewares added by NewBaseplateServer.
This package also implements opentracing defined interfaces. As a side effect, importing this package will call opentracing.SetGlobalTracer automatically with a Tracer implementation that does not send spans anywhere. Call InitGlobalTracer early in your main function to setup spans sampling.
Index ¶
- Constants
- func CloseTracer() error
- func InitFromConfig(cfg Config) (io.Closer, error)
- func InitGlobalTracer(cfg Config) error
- func InitGlobalTracerWithCloser(cfg Config) (io.Closer, error)
- func IsSpanHook(hook interface{}) bool
- func RegisterCreateServerSpanHooks(hooks ...CreateServerSpanHook)
- func ResetHooks()
- func SetMetricsTagsAllowList(list []string)
- func TestWrapper(tb testing.TB) (logger log.Wrapper, startFailing func())
- type AddSpanCounterHook
- type Config
- type CreateChildSpanHook
- type CreateServerSpanHook
- type ErrorReporterCreateServerSpanHook
- type FinishOptions
- type Headers
- type InvalidSpanTypeError
- type SetSpanTagHook
- type Span
- func (s *Span) AddCounter(key string, delta float64)
- func (s *Span) AddHooks(hooks ...interface{})
- func (s *Span) BaggageItem(restrictedKey string) string
- func (s *Span) Context() opentracing.SpanContext
- func (s *Span) Finish()
- func (s *Span) FinishWithOptions(opts opentracing.FinishOptions)
- func (s Span) Flags() int64
- func (s *Span) ForeachBaggageItem(handler func(k, v string) bool)
- func (s Span) ID() string
- func (s *Span) Log(data opentracing.LogData)
- func (s *Span) LogEvent(event string)
- func (s *Span) LogEventWithPayload(event string, payload interface{})
- func (s *Span) LogFields(fields ...otlog.Field)
- func (s *Span) LogKV(alternatingKeyValues ...interface{})
- func (s *Span) MetricsTags() map[string]string
- func (s Span) Name() string
- func (s Span) ParentID() string
- func (s Span) Sampled() bool
- func (s *Span) SetBaggageItem(restrictedKey, value string) opentracing.Span
- func (s *Span) SetDebug(v bool)
- func (s *Span) SetOperationName(operationName string) opentracing.Span
- func (s *Span) SetTag(key string, value interface{}) opentracing.Span
- func (s Span) SpanType() SpanType
- func (s Span) StartTime() time.Time
- func (s *Span) Stop(ctx context.Context, err error) error
- func (s Span) StopTime() time.Time
- func (s Span) TraceID() string
- func (s *Span) Tracer() opentracing.Tracer
- type SpanType
- type SpanTypeOption
- type StartSpanOption
- type StartSpanOptions
- type StartStopSpanHook
- type Tracer
- func (t *Tracer) Close() error
- func (t *Tracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error)
- func (t *Tracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error
- func (t *Tracer) Record(ctx context.Context, zs ZipkinSpan) error
- func (t *Tracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span
- type ZipkinBinaryAnnotation
- type ZipkinEndpointInfo
- type ZipkinSpan
- type ZipkinTimeAnnotation
Examples ¶
Constants ¶
const ( TagKeyClient = "client" TagKeyEndpoint = "endpoint" TagKeySuccess = "success" TagKeyPeerService = "peer.service" )
Well-known (special) span tag keys
const ( // Max size of serialized span in bytes. MaxSpanSize = 102400 // Max number of spans allowed in the message queue at one time. MaxQueueSize = 10000 // Prefix added to the queue name. QueueNamePrefix = "traces-" )
Configuration values for the message queue.
const ( ZipkinTimeAnnotationKeyClientReceive = "cr" ZipkinTimeAnnotationKeyClientSend = "cs" ZipkinTimeAnnotationKeyServerReceive = "sr" ZipkinTimeAnnotationKeyServerSend = "ss" )
Zipkin span well-known time annotation keys.
const ( // String values ZipkinBinaryAnnotationKeyComponent = "component" // Boolean values ZipkinBinaryAnnotationKeyDebug = "debug" ZipkinBinaryAnnotationKeyError = "error" ZipkinBinaryAnnotationKeyTimeOut = "timed_out" )
Zipkin span well-known binary annotation keys.
const ( // When set, this trace passes all samplers. FlagMaskDebug int64 = 1 )
FlagMask values.
Variables ¶
This section is empty.
Functions ¶
func CloseTracer ¶
func CloseTracer() error
CloseTracer tries to cast opentracing.GlobalTracer() into *Tracer, and calls its Close function.
See Tracer.Close for more details.
func InitFromConfig ¶
InitFromConfig is an alias to InitGlobalTracerWithCloser.
It returns an io.Closer that can be used to close out the tracer when the server is done executing.
func InitGlobalTracer ¶
InitGlobalTracer initializes opentracing's global tracer.
This function will try to get the first local IPv4 address of this machine as part of the span information send to the backend service. If it fails to do so, UndefinedIP will be used instead, and the error will be logged if logger is non-nil.
func InitGlobalTracerWithCloser ¶
InitGlobalTracerWithCloser is the combination of InitGlobalTracer and CloseTracer.
After successful initialization, the returned Closer would delegate to CloseTracer upon called.
func IsSpanHook ¶
func IsSpanHook(hook interface{}) bool
IsSpanHook returns true if hook implements at least one of the span Hook interfaces and false if it implements none.
func RegisterCreateServerSpanHooks ¶
func RegisterCreateServerSpanHooks(hooks ...CreateServerSpanHook)
RegisterCreateServerSpanHooks registers Hooks into the Baseplate request lifecycle.
This function and ResetHooks are not safe to call concurrently.
func ResetHooks ¶
func ResetHooks()
ResetHooks removes all global hooks and resets back to initial state.
This function and RegisterCreateServerSpanHooks are not safe to call concurrently.
func SetMetricsTagsAllowList ¶ added in v0.8.0
func SetMetricsTagsAllowList(list []string)
SetMetricsTagsAllowList sets the allow-list used to carry tags from spans to metrics.
"client" and "endpoint" are always included even if they are not in list.
You should only set the tags you really need in metrics and limit the size of this allow-list. A big allow-list both makes span operations slower, and increase metrics cardinality.
func TestWrapper ¶
TestWrapper is a log.Wrapper implementation can be used in tests.
It's similar to but different from log.TestWrapper. In InitGlobalTracer call logger could be called once for unable to find ip, and we don't want to fail the tests because of that. So in this implementation, initially this logger just print the message but don't fail the test, and only start failing the test after startFailing is called.
Types ¶
type AddSpanCounterHook ¶
type AddSpanCounterHook interface { // OnAddCounter is called by Span.AddCounter, after the counter is updated // on the Span. OnAddCounter(span *Span, key string, delta float64) error }
AddSpanCounterHook allows you to inject functionality after adding a counter on a span.
type Config ¶
type Config struct { // The name of the service that will be attached to every span. Namespace string `yaml:"namespace"` // SampleRate should be in the range of [0, 1]. // When SampleRate >= 1, all traces will be recoreded; // When SampleRate <= 0, none of the traces will be recorded, // except the ones with debug flag set. // // Please note that SampleRate only affect top level spans created inside this // service. For most services the sample status will be inherited from the // headers from the client. SampleRate float64 `yaml:"sampleRate"` // Logger, if non-nil, will be used to log additional informations Record // returned certain errors. Logger log.Wrapper `yaml:"logger"` // The max timeout applied to Record function. // // If the passed in context object has an earlier deadline set, // that deadline will be respected instead. // // If MaxRecordTimeout <= 0, // Record function would run in non-blocking mode, // that it fails immediately if the queue is full. MaxRecordTimeout time.Duration `yaml:"recordTimeout"` // The name of the message queue to be used to actually send sampled spans to // backend service (requires Baseplate.py tracing publishing sidecar with the // same name configured). // // QueueName should not contain "traces-" prefix, it will be auto added. // // If QueueName is empty, no spans will be sampled, // including the ones with debug flag set. QueueName string `yaml:"queueName"` // The max size of the message queue (number of messages). // // If it <=0 or > MaxQueueSize (the constant, 10000), // MaxQueueSize constant will be used instead. // // This is only used when QueueName is non-empty. MaxQueueSize int64 `yaml:"maxQueueSize"` // If UseHex is set to true, when generating new trace/span IDs we will use // hex instead of dec uint64. // // You should only set this to true if you know all of your upstream servers // can handle hex trace ids (Baseplate.go v0.8.0+ or Baseplate.py v2.0.0+). UseHex bool `yaml:"useHex"` // In test code, // this field can be used to set the message queue the tracer publishes to, // usually an *mqsend.MockMessageQueue. // // This field will be ignored when QueueName is non-empty, // to help avoiding footgun prod code. // // DO NOT USE IN PROD CODE. TestOnlyMockMessageQueue mqsend.MessageQueue `yaml:"-"` }
Config is the configuration struct for the tracing package containing configuration values to be used in InitGlobalTracer.
Can be deserialized from YAML.
type CreateChildSpanHook ¶
type CreateChildSpanHook interface { // OnCreateChild is called after a child Span is first created, before any // OnPostStart Hooks are called. // // OnCreateChild is the recommended place to register Hooks onto the // child Span. OnCreateChild(parent, child *Span) error }
CreateChildSpanHook allows you to inject functionality into the creation of a Baseplate span.
type CreateServerSpanHook ¶
type CreateServerSpanHook interface { // OnCreateServerSpan is called after a server Span is first created by // tracing.CreateServerSpan, before any OnPostStart Hooks are called. // // OnCreateServerSpan is the recommended place to register Hooks onto the // server Span. OnCreateServerSpan(span *Span) error }
CreateServerSpanHook allows you to inject functionality into the lifecycle of a Baseplate request.
type ErrorReporterCreateServerSpanHook ¶
type ErrorReporterCreateServerSpanHook struct{}
ErrorReporterCreateServerSpanHook registers each Server Span with an ErrorReporterSpanHook that will publish errors sent to OnPreStop to Sentry.
Example ¶
This example demonstrates how to use ErrorReporterCreateServerSpanHook.
// variables should be properly initialized in production code var ( parent *tracing.Span ) // initialize the ErrorReporterCreateServerSpanHook hook := tracing.ErrorReporterCreateServerSpanHook{} // register the hook with Baseplate tracing.RegisterCreateServerSpanHooks(hook) // Create a child server Span span := opentracing.StartSpan( "test", opentracing.ChildOf(parent), tracing.SpanTypeOption{Type: tracing.SpanTypeServer}, ) // Errors given to span.FinishWithOptions will be sent to Sentry span.FinishWithOptions(tracing.FinishOptions{ Err: errors.New("test error"), }.Convert())
Output:
func (ErrorReporterCreateServerSpanHook) OnCreateServerSpan ¶
func (h ErrorReporterCreateServerSpanHook) OnCreateServerSpan(span *Span) error
OnCreateServerSpan registers SentrySpanHook on a Server Span.
type FinishOptions ¶
FinishOptions are the options to be converted into opentracing.FinishOptions.
All fields are optional.
func (FinishOptions) Convert ¶
func (fo FinishOptions) Convert() opentracing.FinishOptions
Convert converts FinishOptions into opentracing.FinishOptions which can be used in Span.FinishWithOptions().
type Headers ¶
type Headers struct { // TraceID is the trace ID passed via upstream headers. TraceID string // SpanID is the span ID passed via upstream headers. SpanID string // Flags is the flags int passed via upstream headers as a string. Flags string // Sampled is whether this span was sampled by the upstream caller. Uses // a pointer to a bool so it can distinguish between set/not-set. Sampled *bool }
Headers is the argument struct for starting a Span from upstream headers.
func (Headers) AnySet ¶ added in v0.2.0
AnySet returns true if any of the values in the Headers are set, false otherwise.
func (Headers) ParseFlags ¶ added in v0.2.0
ParseFlags attempts to convert h.Flags into an int64, if it succeeds it returns the value and 'true'. If it fails, either because h.Flags is not set or it is malformed, ok will be 'false' and you should not rely on the ID returned.
If h.Flags was malformed, an error will be logged using the global tracer's logger but no error will be returned.
func (Headers) ParseSampled ¶ added in v0.2.0
ParseSampled returns the boolean value of h.Sampled and a flag specifying whether h.Sampled was set or not. If it not set, both "sampled" and "ok" will return "false" but that does not mean that "sampled" should be false, you should only used the returned value for "sampled" if "ok" is true.
func (Headers) ParseSpanID ¶ added in v0.2.0
ParseSpanID attempts to validate h.SpanID, if it succeeds it returns the value and 'true'. If it fails, either because h.SpanID is not set or it is malformed, ok will be 'false' and you should not rely on the ID returned.
If h.SpanID was malformed, an error will be logged using the global tracer's logger but no error will be returned.
func (Headers) ParseTraceID ¶ added in v0.2.0
ParseTraceID attempts to validate h.TraceID, if it succeeds it returns the value and 'true'. If it fails, either because h.TraceID is not set or it is malformed, ok will be 'false' and you should not rely on the ID returned.
If h.TraceID was malformed, an error will be logged using the global tracer's logger but no error will be returned.
type InvalidSpanTypeError ¶
InvalidSpanTypeError is the error type returned when trying to use a Span in a way that is incompatible with its type.
For example, trying to set a child span as a ServerSpan.
func (*InvalidSpanTypeError) Error ¶
func (e *InvalidSpanTypeError) Error() string
type SetSpanTagHook ¶
type SetSpanTagHook interface { // OnSetTag is called by Span.SetTag, after the tag is set on the Span. OnSetTag(span *Span, key string, value interface{}) error }
SetSpanTagHook allows you to inject functionality after setting a tag on a span.
type Span ¶
type Span struct {
// contains filtered or unexported fields
}
Span defines a tracing span.
func AsSpan ¶
func AsSpan(s opentracing.Span) *Span
AsSpan converts an opentracing.Span back to *Span.
This function never returns nil. If the passed in opentracing.Span is actually not implemented by *Span, a new *Span with empty name and local type will be created and returned. When that happens it will also be logged if the last InitGlobalTracer call was with a non-nil logger.
This function is provided for convenience calling functions not in opentracing Span API, for example:
span := opentracing.StartSpan(name, opts...) tracing.AsSpan(span).AddHooks(hooks...)
func StartSpanFromHeaders ¶
func StartSpanFromHeaders(ctx context.Context, name string, headers Headers) (context.Context, *Span)
StartSpanFromHeaders creates a server span from the passed in Headers. If no headers are set, then a new top-level server span will be created and returned.
Please note that "Sampled" header is default to false according to baseplate spec, so if the headers are incorrect, this span (and all its child-spans) will never be sampled, unless debug flag was set explicitly later.
If any headers are missing or malformed, they will be ignored. Malformed headers will be logged if InitGlobalTracer was last called with a non-nil logger.
func StartTopLevelServerSpan ¶ added in v0.2.0
StartTopLevelServerSpan initializes a new, top level server span.
This span will have a new TraceID and will be sampled based on your configured sample rate.
func (*Span) AddCounter ¶
AddCounter adds delta to a counter annotation and calls all OnAddCounter Hooks registered to the Span.
func (*Span) AddHooks ¶
func (s *Span) AddHooks(hooks ...interface{})
AddHooks adds hooks into the Span.
Any hooks that do not conform to at least one of the span hook interfaces will be discarded and an error will be logged.
It is recommended that you only call AddHooks on a Span within an OnCreateChild/OnCreateServerSpan hook so the Span is set up with all of its hooks as a part of its creation.
func (*Span) BaggageItem ¶
BaggageItem implements opentracing.Span.
As we don't support any extra baggage items, it always returns empty string.
func (*Span) Context ¶
func (s *Span) Context() opentracing.SpanContext
Context implements opentracing.Span.
It returns self as opentracing.SpanContext.
func (*Span) Finish ¶
func (s *Span) Finish()
Finish implements opentracing.Span.
It calls Stop with background context and nil error. If Stop returns an error, it will also be logged with the tracer's logger.
func (*Span) FinishWithOptions ¶
func (s *Span) FinishWithOptions(opts opentracing.FinishOptions)
FinishWithOptions implements opentracing.Span.
In this implementation we ignore all timestamps in opts, only extract context and error out of all the log fields, and ignore all other log fields.
Please use FinishOptions.Convert() to prepare the opts arg.
It calls Stop with context and error extracted from opts. If Stop returns an error, it will also be logged with the tracer's logger.
func (*Span) ForeachBaggageItem ¶
ForeachBaggageItem implements opentracing.SpanContext.
We don't support any extra baggage items, so it's a noop.
func (*Span) Log ¶
func (s *Span) Log(data opentracing.LogData)
Log implements opentracing.Span.
it's deprecated in the interface and is a no-op here.
func (*Span) LogEvent ¶
LogEvent implements opentracing.Span.
it's deprecated in the interface and is a no-op here.
func (*Span) LogEventWithPayload ¶
LogEventWithPayload implements opentracing.Span.
it's deprecated in the interface and is a noop here.
func (*Span) LogFields ¶
LogFields implements opentracing.Span.
In this implementation it's a no-op.
func (*Span) LogKV ¶
func (s *Span) LogKV(alternatingKeyValues ...interface{})
LogKV implements opentracing.Span.
In this implementation it's a no-op.
func (*Span) MetricsTags ¶ added in v0.8.0
MetricsTags returns a subset of span's tags filtered by the allow-list set from SetMetricsTagsAllowList().
func (*Span) SetBaggageItem ¶
SetBaggageItem implements opentracing.Span.
As we don't support any extra baggage items, it's a noop and just returns self.
func (*Span) SetOperationName ¶
SetOperationName implements opentracing.Span.
func (*Span) SetTag ¶
SetTag sets a binary tag annotation and calls all OnSetTag Hooks registered to the Span.
func (*Span) Stop ¶
Stop stops the Span, calls all registered OnPreStop Hooks, serializes the Span, and sends the serialized Span to a back-end that records the Span.
In most cases FinishWithOptions should be used instead, which calls Stop and auto logs the error returned by Stop. Stop is still provided in case there's need to handle the error differently.
func (Span) StopTime ¶ added in v0.3.0
StopTime the time that the span was stopped if it has been stopped, will be zero if it has not been stopped yet.
type SpanTypeOption ¶
type SpanTypeOption struct { // NOTE: If the Type is SpanTypeClient, // the name of the span is expected (by metricsbp.CreateServerSpanHook) // to be in the format of "service.endpoint", // so that it can get the client and endpoint tags correctly. Type SpanType // contains filtered or unexported fields }
SpanTypeOption implements StartSpanOption to set the type of the span.
Example (Client) ¶
This example demonstrates how to use SpanTypeOption to create a client span.
var ( // In real code this should be in the args of your function ctx context.Context // In real code this should be the named return of your function err error ) span, ctx := opentracing.StartSpanFromContext( ctx, "service.endpoint", // For example, "mysql.query" tracing.SpanTypeOption{ Type: tracing.SpanTypeClient, }, ) // NOTE: It's important to wrap span.FinishWithOptions in a lambda. // // If you just do this: // // // Bad example, DO NOT USE. // defer span.FinishWithOptions(tracing.FinishOptions{ // Ctx: ctx, // Err: err, // }.Convert()) // // Err will always be nil, // because the args of defer'd function are evaluated at the time of defer, // not time of execution. defer func() { span.FinishWithOptions(tracing.FinishOptions{ Ctx: ctx, Err: err, }.Convert()) }() // Do real work here.
Output:
func (SpanTypeOption) ApplyBP ¶
func (s SpanTypeOption) ApplyBP(sso *StartSpanOptions)
ApplyBP implements StartSpanOption.
type StartSpanOption ¶
type StartSpanOption interface {
opentracing.StartSpanOption
ApplyBP(*StartSpanOptions)
}
StartSpanOption defines additional options for baseplate spans.
type StartSpanOptions ¶
type StartSpanOptions struct { OpenTracingOptions opentracing.StartSpanOptions Type SpanType }
StartSpanOptions is the additional options for baseplate spans.
func (*StartSpanOptions) Apply ¶
func (sso *StartSpanOptions) Apply(opt opentracing.StartSpanOption)
Apply calls opt.Apply against sso.OpenTracingOptions.
If opt also implements StartSpanOptions, it also calls opt.ApplyBP against sso.
type StartStopSpanHook ¶
type StartStopSpanHook interface { // OnPostStart is called after a child Span is created and the OnCreateChild // Hooks on the parent Span are called. OnPostStart(span *Span) error // OnPreStop is called by Span.Stop, after setting any custom tags, but // before the span is stopped, serialized, or published. OnPreStop(span *Span, err error) error }
StartStopSpanHook allows you to inject functionality immediately after starting a span and immediately before stopping a span.
type Tracer ¶
type Tracer struct {
// contains filtered or unexported fields
}
A Tracer creates and manages spans.
func (*Tracer) Close ¶
Close closes the tracer's reporting.
After Close is called, no more spans will be sampled.
func (*Tracer) Extract ¶
Extract implements opentracing.Tracer.
Currently it always return opentracing.ErrInvalidCarrier as the error.
func (*Tracer) Inject ¶
Inject implements opentracing.Tracer.
Currently it always return opentracing.ErrInvalidCarrier as the error.
func (*Tracer) Record ¶
func (t *Tracer) Record(ctx context.Context, zs ZipkinSpan) error
Record records a span with the Recorder.
Span.Stop(), Span.Finish(), and Span.FinishWithOptions() call this function automatically. In most cases that should be enough and you should not call this function directly.
func (*Tracer) StartSpan ¶
func (t *Tracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span
StartSpan implements opentracing.Tracer.
For opentracing.StartSpanOptions, it only support the following options and will ignore all others:
- ChildOfRef (in which case the parent span must be of type *Span)
- StartTime
- Tags
It supports additional StartSpanOptions defined in this package.
If the new span's type is server, all registered CreateServerSpanHooks will be called as well.
Please note that trying to set span type via opentracing-go/ext package won't work, please use SpanTypeOption defined in this package instead.
type ZipkinBinaryAnnotation ¶
type ZipkinBinaryAnnotation struct { Endpoint ZipkinEndpointInfo `json:"endpoint"` Key string `json:"key"` Value interface{} `json:"value"` }
ZipkinBinaryAnnotation defines Zipkin's binary annotation json format.
type ZipkinEndpointInfo ¶
type ZipkinEndpointInfo struct { ServiceName string `json:"serviceName"` IPv4 string `json:"ipv4"` }
ZipkinEndpointInfo defines Zipkin's endpoint json format.
type ZipkinSpan ¶
type ZipkinSpan struct { // Required fields. TraceID string `json:"traceId"` Name string `json:"name"` SpanID string `json:"id"` Start timebp.TimestampMicrosecond `json:"timestamp"` Duration timebp.DurationMicrosecond `json:"duration"` // parentId is optional, ParentID string `json:"parentId,omitempty"` // Annotations are all optional. TimeAnnotations []ZipkinTimeAnnotation `json:"annotations,omitempty"` BinaryAnnotations []ZipkinBinaryAnnotation `json:"binaryAnnotations,omitempty"` }
ZipkinSpan defines a span in zipkin's json format.
It's used as an intermediate format before encoding to json string. It shouldn't be used directly.
type ZipkinTimeAnnotation ¶
type ZipkinTimeAnnotation struct { Endpoint ZipkinEndpointInfo `json:"endpoint"` Timestamp timebp.TimestampMicrosecond `json:"timestamp"` // In time annotations the value is actually the timestamp and the key is // actually the value. Key string `json:"value"` }
ZipkinTimeAnnotation defines Zipkin's time annotation json format.