Skip to content
OpenTracing API for Go
Go Makefile
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Adds issue template. (#183) Apr 12, 2018
ext Fix typo in comments (#222) Aug 31, 2019
harness Fix redundant import alias (#206) Feb 16, 2019
log improve documentation for log.Object() to emphasize the requirement t… Aug 29, 2019
mocktracer [mock] Return ErrInvalidSpanContext if span context is not MockSpanCo… Jul 4, 2019
.gitignore Fix lint and coverage (#202) Nov 29, 2018
.travis.yml Bump Go versions to 1.11/12 (#213) Mar 23, 2019 Update CHANGELOG Mar 23, 2019
LICENSE update license to Apache 2.0 (#181) Apr 6, 2018
Makefile Fix lint and coverage (#202) Nov 29, 2018 Change http to https for security links (#207) Feb 18, 2019
ext.go Add an extension to Tracer interface for custom go context creation (#… Sep 12, 2019
globaltracer.go Add support to GlobalTracer to indicate if a tracer has been register… Nov 29, 2018
globaltracer_test.go Add support to GlobalTracer to indicate if a tracer has been register… Nov 29, 2018
gocontext.go Add an extension to Tracer interface for custom go context creation (#… Sep 12, 2019
gocontext_test.go Add an extension to Tracer interface for custom go context creation (#… Sep 12, 2019
noop.go Improve noop impementation (#223) Sep 13, 2019
options_test.go Replace the Referee terminology Jul 25, 2016
propagation.go Use Set() instead of Add() in HTTPHeadersCarrier (#191) Sep 8, 2018
propagation_test.go Fix HTTPHeadersCarrier type name in the documentation (#104) Jul 30, 2016
span.go Span: add return type documentation (#162) Jun 6, 2018
testtracer_test.go Flesh out the LogFields and LogKV changes Sep 26, 2016
tracer.go Bump Go versions to 1.11/12 (#213) Mar 23, 2019

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 ""
    import ".../some_tracing_impl"

    func main() {
            // tracing impl specific:

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()
            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(
        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.

            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(
        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(

        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()


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.


Apache 2.0 License.

You can’t perform that action at this time.