This package is a Go platform API for OpenTracing.
In order to understand the Go platform API, one must first be familiar with the OpenTracing project and terminology more generally.
Everyday consumers of this opentracing
package really only need to worry
about a couple of key abstractions: the StartTrace
function, the Span
interface, and binding a Tracer
at main()
-time. Here are code snippets
demonstrating some important use cases.
The simplest starting point is ./default_tracer.go
. As early as possible, call
import ".../opentracing-go"
import ".../some_tracing_impl"
func main() {
tracerImpl := some_tracing_impl.New(...) // tracing impl specific
opentracing.InitGlobalTracer(tracerImpl)
...
}
If you prefer direct control to singletons, manage ownership of the
opentracing.Tracer
implementation explicitly.
func xyz() {
...
sp := opentracing.StartTrace("span_name")
defer sp.Finish()
sp.Info("called xyz")
...
}
func xyz(parentSpan opentracing.Span, ...) {
...
sp := opentracing.JoinTrace("span_name", parentSpan)
defer sp.Finish()
sp.Info("called xyz")
...
}
Additionally, this example demonstrates how to get a context.Context
associated with any opentracing.Span
instance.
func xyz(goCtx context.Context, ...) {
...
sp, goCtx := opentracing.JoinTrace("span_name", goCtx).AddToGoContext(goCtx)
defer sp.Finish()
sp.Info("called xyz")
...
}
func makeSomeRequest(ctx context.Context) ... {
if span := opentracing.SpanFromGoContext(ctx); span != nil {
httpClient := &http.Client{}
httpReq, _ := http.NewRequest("GET", "http://myservice/", nil)
// Transmit the span's TraceContext as an HTTP header on our
// outbound request.
opentracing.AddTraceContextToHeader(
span.TraceContext(),
httpReq.Header,
opentracing.DefaultTracer())
resp, err := httpClient.Do(httpReq)
...
}
...
}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// Grab the TraceContext from the HTTP header using the
// opentracing helper.
reqTraceCtx, err := opentracing.TraceContextFromHeader(
req.Header, opentracing.GlobalTracer())
var serverSpan opentracing.Span
var goCtx context.Context = ...
if err != nil {
// Just make a root span.
serverSpan, goCtx = opentracing.StartTrace("serverSpan").AddToGoContext(goCtx)
} else {
// Make a new server-side span that's a child of the span/context sent
// over the wire.
serverSpan, goCtx = opentracing.JoinTrace(
"serverSpan", reqTraceCtx).AddToGoContext(goCtx)
}
defer serverSpan.Finish()
...
}
The entire public API is goroutine-safe and does not require external synchronization.
There should be no need for most tracing system implementors to worry about the
opentracing.Span
or opentracing.Tracer
interfaces directly:
standardtracer.New(...)
should work well enough in most circumstances.
In order to integrate with standardtracer
, tracing system authors are
expected to provide implementations of:
opentracing.TraceContext
opentracing.TraceContextSource
standardtracer.Recorder
For a small working example, see ../examples/dapperish/*.go
.