Documentation ¶
Overview ¶
Package tracetools provides an abstraction across tracing systems (OpenTelemetry, DataDog).
It is intended for internal use by buildkite-agent only.
Index ¶
Examples ¶
Constants ¶
const ( BackendDatadog = "datadog" BackendOpenTelemetry = "opentelemetry" BackendNone = "" )
const EnvVarTraceContextKey = "BUILDKITE_TRACE_CONTEXT"
EnvVarTraceContextKey is the env var key that will be used to store/retrieve the encoded trace context information into env var maps.
Variables ¶
var ValidTracingBackends = map[string]struct{}{ BackendDatadog: {}, BackendOpenTelemetry: {}, BackendNone: {}, }
Functions ¶
func DecodeTraceContext ¶
DecodeTraceContext will decode, deserialize, and extract the tracing data from the given env var map.
func EncodeTraceContext ¶
EncodeTraceContext will serialize and encode tracing data into a string and place it into the given env vars map.
Example ¶
// Start and configure the tracer to use the propagator. t := opentracer.New( // These args are just to ensure nothing actually gets sent if the test // platform actually has a DD agent running locally. // This is an unlikely, local, non-default agent address. tracer.WithAgentAddr("10.0.0.1:65534"), tracer.WithLogger(&nullLogger{}), ) opentracing.SetGlobalTracer(t) defer tracer.Stop() childEnv := map[string]string{} // Pretend this is the parent process' code func() { span := opentracing.StartSpan("parent process") defer span.Finish() span.SetBaggageItem("asd", "zxc") // Do stuff.. time.Sleep(time.Millisecond * 20) // Now say we want to launch a child process. // Prepare it's env vars. This will be the carrier for the tracing data. if err := EncodeTraceContext(span, childEnv); err != nil { fmt.Println("oops an error for parent process trace injection") } // Now childEnv will contain the encoded data set with the env var key. // Print stuff out for the purpose of the example test. if childEnv["BUILDKITE_TRACE_CONTEXT"] == "" { fmt.Println("oops empty tracing data in env vars") } else { fmt.Println("prepared child env carrier data") } // Normally, you'd now launch a child process with code like: // cmd := exec.Command("echo", "hello", "i", "am", "a", "child") // cmd.Env = ... // Propagate the env vars here // cmd.Run() // The important thing is the Env propagation }() // Pretend this is the child process' code func() { // Make sure tracing is setup the same way (same env var key) // Normally you'd use os.Environ or similar here (the list of strings is // supported). We're just reusing childEnv for test simplicity. sctx, err := DecodeTraceContext(childEnv) if err != nil { fmt.Println("oops an error for child process trace extraction") } else { fmt.Println("extracted tracing data for child process") } sctx.ForeachBaggageItem(func(k, v string) bool { fmt.Printf("bag: %s=%s\n", k, v) return true }) // Now you can start a 'root' span for the child that will also be linked to // the parent process. span := opentracing.StartSpan("child process", opentracing.ChildOf(sctx)) defer span.Finish() // Do stuff... time.Sleep(time.Millisecond * 30) }()
Output: prepared child env carrier data extracted tracing data for child process bag: asd=zxc
Types ¶
type NoopSpan ¶ added in v3.36.0
type NoopSpan struct{}
NoopSpan is an implementation of the Span interface that does nothing for every method implemented The intended use case is for instances where the user doesn't have tracing enabled - using NoopSpan, we can still act as though tracing is enabled, but every time we do something tracing related, nothing happens.
func (*NoopSpan) AddAttributes ¶ added in v3.36.0
AddAttributes is a noop
func (*NoopSpan) FinishWithError ¶ added in v3.36.0
FinishWithError is a noop
func (*NoopSpan) RecordError ¶ added in v3.36.0
RecordError is a noop
type OpenTelemetrySpan ¶ added in v3.36.0
func NewOpenTelemetrySpan ¶ added in v3.36.0
func NewOpenTelemetrySpan(base trace.Span) *OpenTelemetrySpan
func (*OpenTelemetrySpan) AddAttributes ¶ added in v3.36.0
func (s *OpenTelemetrySpan) AddAttributes(attributes map[string]string)
AddAttributes adds the given attributes to the OpenTelemetry span. Only string attributes are accepted.
func (*OpenTelemetrySpan) FinishWithError ¶ added in v3.36.0
func (s *OpenTelemetrySpan) FinishWithError(err error)
FinishWithError adds error information to the OpenTelemetry span if error isn't nil, and records the span as having finished
func (*OpenTelemetrySpan) RecordError ¶ added in v3.36.0
func (s *OpenTelemetrySpan) RecordError(err error)
RecordError records an error on the given OpenTelemetry span. No-op when error is nil
type OpenTracingSpan ¶ added in v3.36.0
type OpenTracingSpan struct {
Span opentracing.Span
}
func NewOpenTracingSpan ¶ added in v3.36.0
func NewOpenTracingSpan(base opentracing.Span) *OpenTracingSpan
func (*OpenTracingSpan) AddAttributes ¶ added in v3.36.0
func (s *OpenTracingSpan) AddAttributes(attributes map[string]string)
AddAttributes adds the given map of attributes to the span as OpenTracing tags
func (*OpenTracingSpan) FinishWithError ¶ added in v3.36.0
func (s *OpenTracingSpan) FinishWithError(err error)
FinishWithError adds error information to the OpenTracingSpan if error isn't nil, and records the span as having finished
func (*OpenTracingSpan) RecordError ¶ added in v3.36.0
func (s *OpenTracingSpan) RecordError(err error)
RecordError records an error on the given span
type Span ¶ added in v3.36.0
func StartSpanFromContext ¶
func StartSpanFromContext(ctx context.Context, operation string, tracingBackend string) (Span, context.Context)
StartSpanFromContext will start a span appropriate to the given tracing backend from the given context with the given operation name. It will also do some common/repeated setup on the span to keep code a little more DRY. If an unknown tracing backend is specified, it will return a span that noops on every operation