Categorygithub.com/opentracing/opentracing-go
modulepackage
1.2.0
Repository: https://github.com/opentracing/opentracing-go.git
Documentation: pkg.go.dev

# README

Gitter chat Build Status GoDoc Sourcegraph Badge

OpenTracing API for Go

This package is a Go platform API for OpenTracing.

Required Reading

In order to understand the Go platform API, one must first be familiar with the OpenTracing project and terminology more specifically.

API overview for those adding instrumentation

Everyday consumers of this opentracing package really only need to worry about a couple of key abstractions: the StartSpan function, the Span interface, and binding a Tracer at main()-time. Here are code snippets demonstrating some important use cases.

Singleton initialization

The simplest starting point is ./default_tracer.go. As early as possible, call

    import "github.com/opentracing/opentracing-go"
    import ".../some_tracing_impl"

    func main() {
        opentracing.SetGlobalTracer(
            // tracing impl specific:
            some_tracing_impl.New(...),
        )
        ...
    }

Non-Singleton initialization

If you prefer direct control to singletons, manage ownership of the opentracing.Tracer implementation explicitly.

Creating a Span given an existing Go context.Context

If you use context.Context in your application, OpenTracing's Go library will happily rely on it for Span propagation. To start a new (blocking child) Span, you can use StartSpanFromContext.

    func xyz(ctx context.Context, ...) {
        ...
        span, ctx := opentracing.StartSpanFromContext(ctx, "operation_name")
        defer span.Finish()
        span.LogFields(
            log.String("event", "soft error"),
            log.String("type", "cache timeout"),
            log.Int("waited.millis", 1500))
        ...
    }

Starting an empty trace by creating a "root span"

It's always possible to create a "root" Span with no parent or other causal reference.

    func xyz() {
        ...
        sp := opentracing.StartSpan("operation_name")
        defer sp.Finish()
        ...
    }

Creating a (child) Span given an existing (parent) Span

    func xyz(parentSpan opentracing.Span, ...) {
        ...
        sp := opentracing.StartSpan(
            "operation_name",
            opentracing.ChildOf(parentSpan.Context()))
        defer sp.Finish()
        ...
    }

Serializing to the wire

    func makeSomeRequest(ctx context.Context) ... {
        if span := opentracing.SpanFromContext(ctx); span != nil {
            httpClient := &http.Client{}
            httpReq, _ := http.NewRequest("GET", "http://myservice/", nil)

            // Transmit the span's TraceContext as HTTP headers on our
            // outbound request.
            opentracing.GlobalTracer().Inject(
                span.Context(),
                opentracing.HTTPHeaders,
                opentracing.HTTPHeadersCarrier(httpReq.Header))

            resp, err := httpClient.Do(httpReq)
            ...
        }
        ...
    }

Deserializing from the wire

    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        var serverSpan opentracing.Span
        appSpecificOperationName := ...
        wireContext, err := opentracing.GlobalTracer().Extract(
            opentracing.HTTPHeaders,
            opentracing.HTTPHeadersCarrier(req.Header))
        if err != nil {
            // Optionally record something about err here
        }

        // Create the span referring to the RPC client if available.
        // If wireContext == nil, a root span will be created.
        serverSpan = opentracing.StartSpan(
            appSpecificOperationName,
            ext.RPCServerOption(wireContext))

        defer serverSpan.Finish()

        ctx := opentracing.ContextWithSpan(context.Background(), serverSpan)
        ...
    }

Conditionally capture a field using log.Noop

In some situations, you may want to dynamically decide whether or not to log a field. For example, you may want to capture additional data, such as a customer ID, in non-production environments:

    func Customer(order *Order) log.Field {
        if os.Getenv("ENVIRONMENT") == "dev" {
            return log.String("customer", order.Customer.ID)
        }
        return log.Noop()
    }

Goroutine-safety

The entire public API is goroutine-safe and does not require external synchronization.

API pointers for those implementing a tracing system

Tracing system implementors may be able to reuse or copy-paste-modify the basictracer package, found here. In particular, see basictracer.New(...).

API compatibility

For the time being, "mild" backwards-incompatible changes may be made without changing the major version number. As OpenTracing and opentracing-go mature, backwards compatibility will become more of a priority.

Tracer test suite

A test suite is available in the harness package that can assist Tracer implementors to assert that their Tracer is working correctly.

Licensing

Apache 2.0 License.

# Packages

Package harness provides a suite of API compatibility checks.

# Functions

ChildOf returns a StartSpanOption pointing to a dependent parent span.
ContextWithSpan returns a new `context.Context` that holds a reference to the span.
FollowsFrom returns a StartSpanOption pointing to a parent Span that caused the child Span but does not directly depend on its result in any way.
GlobalTracer returns the global singleton `Tracer` implementation.
InitGlobalTracer is deprecated.
IsGlobalTracerRegistered returns a `bool` to indicate if a tracer has been globally registered.
SetGlobalTracer sets the [singleton] opentracing.Tracer returned by GlobalTracer().
SpanFromContext returns the `Span` previously associated with `ctx`, or `nil` if no such `Span` could be found.
StartSpan defers to `Tracer.StartSpan`.
StartSpanFromContext starts and returns a Span with `operationName`, using any Span found within `ctx` as a ChildOfRef.
StartSpanFromContextWithTracer starts and returns a span with `operationName` using a span found within the context as a ChildOfRef.

# Constants

Binary represents SpanContexts as opaque binary data.
ChildOfRef refers to a parent Span that caused *and* somehow depends upon the new child Span.
FollowsFromRef refers to a parent Span that does not depend in any way on the result of the new child Span.
HTTPHeaders represents SpanContexts as HTTP header string pairs.
TextMap represents SpanContexts as key:value string pairs.

# Variables

ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Extract() implementations expect a different type of `carrier` than they are given.
ErrInvalidSpanContext errors occur when Tracer.Inject() is asked to operate on a SpanContext which it is not prepared to handle (for example, since it was created by a different tracer implementation).
ErrSpanContextCorrupted occurs when the `carrier` passed to Tracer.Extract() is of the expected type but is corrupted.
ErrSpanContextNotFound occurs when the `carrier` passed to Tracer.Extract() is valid and uncorrupted but has insufficient information to extract a SpanContext.
ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or Tracer.Extract() is not recognized by the Tracer implementation.

# Structs

FinishOptions allows Span.FinishWithOptions callers to override the finish timestamp and provide log data via a bulk interface.
LogData is DEPRECATED.
LogRecord is data associated with a single Span log.
A NoopTracer is a trivial, minimum overhead implementation of Tracer for which all operations are no-ops.
SpanReference is a StartSpanOption that pairs a SpanReferenceType and a referenced SpanContext.
StartSpanOptions allows Tracer.StartSpan() callers and implementors a mechanism to override the start timestamp, specify Span References, and make a single Tag or multiple Tags available at Span start time.
Tag may be passed as a StartSpanOption to add a tag to new spans, or its Set method may be used to apply the tag to an existing Span, for example: tracer.StartSpan("opName", Tag{"Key", value}) or Tag{"key", value}.Set(span).

# Interfaces

Span represents an active, un-finished span in the OpenTracing system.
SpanContext represents Span state that must propagate to descendant Spans and across process boundaries (e.g., a <trace_id, span_id, sampled> tuple).
StartSpanOption instances (zero or more) may be passed to Tracer.StartSpan.
TextMapReader is the Extract() carrier for the TextMap builtin format.
TextMapWriter is the Inject() carrier for the TextMap builtin format.
Tracer is a simple, thin interface for Span creation and SpanContext propagation.
TracerContextWithSpanExtension is an extension interface that the implementation of the Tracer interface may want to implement.

# Type aliases

BuiltinFormat is used to demarcate the values within package `opentracing` that are intended for use with the Tracer.Inject() and Tracer.Extract() methods.
HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader.
SpanReferenceType is an enum type describing different categories of relationships between two Spans.
StartTime is a StartSpanOption that sets an explicit start timestamp for the new Span.
Tags are a generic map from an arbitrary string key to an opaque value type.
TextMapCarrier allows the use of regular map[string]string as both TextMapWriter and TextMapReader.