This package supports distributed tracing of requests by linking together all of the parts of work that go into fulfilling a request.
For example, with a HTML front-end talking to back-end HTTPS APIs, it will link the original front-end request with any/all HTTP requests made to the back-end. Also, it can link together deeper requests made by the back-end to other APIs and services.
Currently this library requires the jaeger-lib dependency to be pinned
at v1.5.0
.
To configure tracing of incoming HTTP requests:
-
Set
JAEGER_*
environment variables. -
Initialise tracer:
closer, tracer, err := tracing.Tracer(log) if err != nil { log.WithError(err).Log() } else { defer closer.Close() }
The returned
io.Closer
is used to ensure that traces are sent to the server before the process exits.Initialising the tracer installs it as the Opentracing global tracer.
-
Use the returned
tracer
middleware with your HTTP handlers:http.ListenAndServe(tracer(handler))
If you're using
server.Compose
, add the tracer to the bottom of your stack, just aboveserver.DefaultMiddleware
. This will make the tracing system available to other middleware such aserrornotifier
(see below).
The middleware will automatically continue spans if the incoming HTTP request has span propagation headers.
To pass tracing headers downstream when making HTTP requests use
Inject
:
// Transmit the span's TraceContext as HTTP headers on our
// outbound request.
opentracing.GlobalTracer().Inject(
span.Context(),
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(httpReq.Header))
this package exports a Span
function that is used to add more detail
to a trace. When you perform some kind of sub-operation, such as an
SQL query, or API call to another service, wrap the call in a call to
Span
:
tracing.Span(ctx, "<operation name>", func(ctx context.Context, span opentracing.Span) error {
httpReq := ...
// Add info to the span
ext.HTTPMethod.Set(span, httpReq.Method)
ext.HTTPUrl.Set(span, httpReq.URL.String())
ext.SpanKind.Set(span, ext.SpanKindRPCClientEnum)
// Propagate trace id to back-end service
opentracing.GlobalTracer().Inject(
span.Context(),
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(httpReq.Header))
// perform your operation, and update span with any details
resp, err := doOperation(httpReq)
if err != nil {
// `tracing.Span` will automatically mark the span as an
// error and log the error message, if we return an error.
return err
}
if opFailed(resp) {
// manually mark the span as an error if there was some kind
// of logical problem
ext.Error.Set(span, true)
span.LogKV("error", "the operation failed!!")
}
return nil
})
This package uses OpenTracing and is configured to use a Jaeger server by default. The OpenTracing site has a good overview of the concepts.