...

Text file src/github.com/opentracing/opentracing-go/README.md

Documentation: github.com/opentracing/opentracing-go

     1[![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/opentracing/public) [![Build Status](https://travis-ci.org/opentracing/opentracing-go.svg?branch=master)](https://travis-ci.org/opentracing/opentracing-go) [![GoDoc](https://godoc.org/github.com/opentracing/opentracing-go?status.svg)](http://godoc.org/github.com/opentracing/opentracing-go)
     2[![Sourcegraph Badge](https://sourcegraph.com/github.com/opentracing/opentracing-go/-/badge.svg)](https://sourcegraph.com/github.com/opentracing/opentracing-go?badge)
     3
     4# OpenTracing API for Go
     5
     6This package is a Go platform API for OpenTracing.
     7
     8## Required Reading
     9
    10In order to understand the Go platform API, one must first be familiar with the
    11[OpenTracing project](https://opentracing.io) and
    12[terminology](https://opentracing.io/specification/) more specifically.
    13
    14## API overview for those adding instrumentation
    15
    16Everyday consumers of this `opentracing` package really only need to worry
    17about a couple of key abstractions: the `StartSpan` function, the `Span`
    18interface, and binding a `Tracer` at `main()`-time. Here are code snippets
    19demonstrating some important use cases.
    20
    21#### Singleton initialization
    22
    23The simplest starting point is `./default_tracer.go`. As early as possible, call
    24
    25```go
    26    import "github.com/opentracing/opentracing-go"
    27    import ".../some_tracing_impl"
    28
    29    func main() {
    30        opentracing.SetGlobalTracer(
    31            // tracing impl specific:
    32            some_tracing_impl.New(...),
    33        )
    34        ...
    35    }
    36```
    37
    38#### Non-Singleton initialization
    39
    40If you prefer direct control to singletons, manage ownership of the
    41`opentracing.Tracer` implementation explicitly.
    42
    43#### Creating a Span given an existing Go `context.Context`
    44
    45If you use `context.Context` in your application, OpenTracing's Go library will
    46happily rely on it for `Span` propagation. To start a new (blocking child)
    47`Span`, you can use `StartSpanFromContext`.
    48
    49```go
    50    func xyz(ctx context.Context, ...) {
    51        ...
    52        span, ctx := opentracing.StartSpanFromContext(ctx, "operation_name")
    53        defer span.Finish()
    54        span.LogFields(
    55            log.String("event", "soft error"),
    56            log.String("type", "cache timeout"),
    57            log.Int("waited.millis", 1500))
    58        ...
    59    }
    60```
    61
    62#### Starting an empty trace by creating a "root span"
    63
    64It's always possible to create a "root" `Span` with no parent or other causal
    65reference.
    66
    67```go
    68    func xyz() {
    69        ...
    70        sp := opentracing.StartSpan("operation_name")
    71        defer sp.Finish()
    72        ...
    73    }
    74```
    75
    76#### Creating a (child) Span given an existing (parent) Span
    77
    78```go
    79    func xyz(parentSpan opentracing.Span, ...) {
    80        ...
    81        sp := opentracing.StartSpan(
    82            "operation_name",
    83            opentracing.ChildOf(parentSpan.Context()))
    84        defer sp.Finish()
    85        ...
    86    }
    87```
    88
    89#### Serializing to the wire
    90
    91```go
    92    func makeSomeRequest(ctx context.Context) ... {
    93        if span := opentracing.SpanFromContext(ctx); span != nil {
    94            httpClient := &http.Client{}
    95            httpReq, _ := http.NewRequest("GET", "http://myservice/", nil)
    96
    97            // Transmit the span's TraceContext as HTTP headers on our
    98            // outbound request.
    99            opentracing.GlobalTracer().Inject(
   100                span.Context(),
   101                opentracing.HTTPHeaders,
   102                opentracing.HTTPHeadersCarrier(httpReq.Header))
   103
   104            resp, err := httpClient.Do(httpReq)
   105            ...
   106        }
   107        ...
   108    }
   109```
   110
   111#### Deserializing from the wire
   112
   113```go
   114    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
   115        var serverSpan opentracing.Span
   116        appSpecificOperationName := ...
   117        wireContext, err := opentracing.GlobalTracer().Extract(
   118            opentracing.HTTPHeaders,
   119            opentracing.HTTPHeadersCarrier(req.Header))
   120        if err != nil {
   121            // Optionally record something about err here
   122        }
   123
   124        // Create the span referring to the RPC client if available.
   125        // If wireContext == nil, a root span will be created.
   126        serverSpan = opentracing.StartSpan(
   127            appSpecificOperationName,
   128            ext.RPCServerOption(wireContext))
   129
   130        defer serverSpan.Finish()
   131
   132        ctx := opentracing.ContextWithSpan(context.Background(), serverSpan)
   133        ...
   134    }
   135```
   136
   137#### Conditionally capture a field using `log.Noop`
   138
   139In some situations, you may want to dynamically decide whether or not
   140to log a field.  For example, you may want to capture additional data,
   141such as a customer ID, in non-production environments:
   142
   143```go
   144    func Customer(order *Order) log.Field {
   145        if os.Getenv("ENVIRONMENT") == "dev" {
   146            return log.String("customer", order.Customer.ID)
   147        }
   148        return log.Noop()
   149    }
   150```
   151
   152#### Goroutine-safety
   153
   154The entire public API is goroutine-safe and does not require external
   155synchronization.
   156
   157## API pointers for those implementing a tracing system
   158
   159Tracing system implementors may be able to reuse or copy-paste-modify the `basictracer` package, found [here](https://github.com/opentracing/basictracer-go). In particular, see `basictracer.New(...)`.
   160
   161## API compatibility
   162
   163For 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.
   164
   165## Tracer test suite
   166
   167A test suite is available in the [harness](https://godoc.org/github.com/opentracing/opentracing-go/harness) package that can assist Tracer implementors to assert that their Tracer is working correctly.
   168
   169## Licensing
   170
   171[Apache 2.0 License](./LICENSE).

View as plain text