Documentation ¶
Overview ¶
Package trace wraps standard tracing for outreach.
This package wraps honeycomb tracing ¶
Trace Initialization ¶
Applications should call `trace.StartTracing(serviceName)` and `trace.StopTracing()` in their `main` like so:
func main() { trace.StartTracing("example") defer trace.StopTracing() ... main app logic ... }
See https://github.com/getoutreach/gobox/blob/master/cmd/example/main.go.
Servers and incoming requests ¶
The httpx/pkg/handlers package wraps the required trace header parsing logic and so applications that use `handlers.Endpoint` do not have to do anything special here.
Custom http servers should wrap their request handling code like so:
trace.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) *roundtripperState { trace.StartSpan(r.Context(), "my endpoint") defer trace.End(r.Context()) ... do actual request handling ... }), "my endpoint")
Non-HTTP servers should wrap their request handling like so:
ctx = trace.StartTrace(ctx, "my endpoint") defer trace.End(ctx) ... do actual request handling ...
Clients should use a Client with the provided transport like so:
ctx = trace.StartTrace(ctx, "my call") defer trace.End(ctx) client := http.Client{Transport: trace.NewTransport(nil)} ... do actual call using the new client ...
Tracing calls ¶
Any interesting function (such as model fetches or redis fetches) should use the following pattern:
func MyInterestingRedisFunction(ctx context.Context, ...) error { ctx = trace.StartCall(ctx, "redis", RedisInfo{...}) defer trace.EndCall(ctx) .... actual work ... trace.AddInfo(ctx, xyzInfo) return trace.SetCallStatus(ctx, err) }
This automatically updates metrics ("call_request_secconds" is the counter with "redis" as the name label), writes to debug/error logs and also writes traces to our tracing infrastructure
Trace calls can be nested.
Creating spans ¶
Spans should rarely be needed but are available for when the metrics or default logging is not sufficient.
Spans are automatically considered `children` of the current trace or span (based on the `context`). The redis example above would look like so:
ctx = trace.StartTrace(ctx, "redis") defer trace.End(ctx) .... do actual redis call...
Adding tags ¶
Tags can be added to the `current` span (or trace or call) by simply calling `trace.AddInfo`. Note that this accepts the same types that logging accepts. For instance, to record an error with redis:
result, err := redis.Call(....) if err != nil { // if you are using trace.Call, then do trace.SetCallStatus // instead. trace.AddInfo(ctx, events.NewErrorInfo(err)) }
Index ¶
- Constants
- func AddInfo(ctx context.Context, args ...log.Marshaler)
- func AddSpanInfo(ctx context.Context, args ...log.Marshaler)
- func AsGRPCCall() call.Option
- func AsHTTPCall() call.Option
- func AsOutboundCall() call.Option
- func CloseTracer(ctx context.Context)
- func End(ctx context.Context)
- func EndCall(ctx context.Context)
- func EndTracing()deprecated
- func ForceTracing(ctx context.Context) context.Context
- func FromHeaders(ctx context.Context, hdrs map[string][]string, name string) context.Context
- func ID(ctx context.Context) string
- func IDs(ctx context.Context) log.Marshaler
- func InitTracer(ctx context.Context, serviceName string) error
- func NewHandler(handler http.Handler, operation string) http.Handler
- func NewTransport(old http.RoundTripper) http.RoundTripper
- func RegisterSpanProcessor(s sdktrace.SpanProcessor)
- func SetCallError(ctx context.Context, err error) error
- func SetCallStatus(ctx context.Context, err error) error
- func SetCallTypeGRPC(ctx context.Context) context.Contextdeprecated
- func SetCallTypeHTTP(ctx context.Context) context.Contextdeprecated
- func SetCallTypeOutbound(ctx context.Context) context.Contextdeprecated
- func SetSpanProcessorHook(hook func([]attribute.KeyValue))
- func StartCall(ctx context.Context, cType string, args ...log.Marshaler) context.Context
- func StartSpan(ctx context.Context, name string, args ...log.Marshaler) context.Context
- func StartSpanAsync(ctx context.Context, name string, args ...log.Marshaler) context.Contextdeprecated
- func StartTrace(ctx context.Context, name string) context.Context
- func StartTracing(serviceName string) errordeprecated
- func ToHeaders(ctx context.Context) map[string][]string
- func WithScheduledTime(t time.Time) call.Option
- type Annotator
- type Config
- type GlobalTags
- type Handler
- type Otel
Constants ¶
const ( // Header that enforces the tracing for particular request HeaderForceTracing = "X-Force-Trace" // Header used by OpenTelemetry to propagate traces OtelPropagationHeader = "Traceparent" )
Variables ¶
This section is empty.
Functions ¶
func AddInfo ¶
AddInfo updates the current span with the provided fields. If a call exists, it updates the call info args with the passed in log marshalers
This is not propagated to child spans automatically.
It does nothing if there isn't a current span.
func AddSpanInfo ¶ added in v1.21.0
AddSpanInfo updates the current span with the provided fields.
It does nothing if there isn't a current span.
func AsGRPCCall ¶ added in v1.31.0
AsGRPCCall set the call type to GRPC
func AsHTTPCall ¶ added in v1.31.0
AsHTTPCall set the call type to HTTP
func AsOutboundCall ¶ added in v1.31.0
AsOutboundCall set the call type to Outbound
func CloseTracer ¶
CloseTracer stops all tracing and sends any queued traces.
This should be called when an application is exiting, or when you want to terminate the tracer.
func EndCall ¶
EndCall calculates the duration of the call, writes to metrics, standard logs and closes the trace span.
This call should always be right after the StartCall in a defer pattern. See StartCall for the right pattern of usage.
EndCall, when called within a defer, catches any panics and rethrows them. Any panics are converted to errors and cause error logging to happen (as do any SetCallStatus calls)
func EndTracing
deprecated
func EndTracing()
Deprecated: Use CloseTracer() instead. EndTracing stops the tracing infrastructure.
This should be called at the exit of the application.
func ForceTracing ¶
ForceTracing will enforce tracing for processing started with returned context and all downstream services that will be invoken on the way.
func FromHeaders ¶
FromHeaders fetches trace info from a headers map
Only use for GRPC. Prefer NewHandler for http calls.
func ID ¶
ID returns an ID for use with external services to propagate tracing context. The ID returned will be the honeycomb trace ID (if honeycomb is enabled) or an empty string if neither are enabled.
func IDs ¶ added in v1.20.0
IDs returns a log-compatible tracing scope (IDs) data built from the context suitable for logging.
func InitTracer ¶
InitTracer starts all tracing infrastructure.
This needs to be called before sending any traces otherwise they will not be published.
func NewHandler ¶ added in v1.42.0
NewHandler creates a new handlers which reads propagated headers from the current trace context.
Usage:
trace.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) *roundtripperState { trace.StartSpan(r.Context(), "my endpoint") defer trace.End(r.Context()) ... do actual request handling ... }), "my endpoint")
func NewTransport ¶
func NewTransport(old http.RoundTripper) http.RoundTripper
NewTransport creates a new transport which propagates the current trace context.
Usage:
client := &http.Client{Transport: trace.NewTransport(nil)} resp, err := client.Get("/ping")
For most cases, use the httpx/pkg/fetch package as it also logs the request, updates latency metrics and adds traces with full info
Note: the request context must be derived from StartSpan/StartTrace etc.
func RegisterSpanProcessor ¶ added in v1.42.0
func RegisterSpanProcessor(s sdktrace.SpanProcessor)
func SetCallError ¶
SetCallError is deprecated and will directly call into SetCallStatus for backward compatibility
func SetCallStatus ¶
SetCallStatus can be optionally called to set status of the call. When the error occurs on the current call, the error will be traced. When the error is nil, no-op from this function
func SetCallTypeGRPC
deprecated
added in
v1.11.0
func SetCallTypeHTTP
deprecated
added in
v1.11.0
func SetCallTypeOutbound
deprecated
added in
v1.11.0
func SetSpanProcessorHook ¶ added in v1.42.0
SetSpanProcessorHook sets a hook to run when a span ends
func StartCall ¶
StartCall is used to start an internal call. For external calls please use StartExternalCall.
This takes care of standard logging, metrics and tracing for "calls"
Typical usage:
ctx = trace.StartCall(ctx, "sql", SQLEvent{Query: ...}) defer trace.EndCall(ctx) return trace.SetCallStatus(ctx, sqlCall(...));
The callType should be broad category (such as "sql", "redis" etc) as as these are used for metrics and cardinality issues come into play. Do note that commonly used call types are exported as constants in this package and should be used whenever possible. The most common call types are http (trace.CallTypeHTTP) and grpc (trace.CallTypeGRPC).
Use the extra args to add stuff to traces and logs and these can have more information as needed (including actual queries for instance).
The log includes a initial Debug entry and a final Error entry if the call failed (but no IDs entry if the call succeeded). Success or failure is determined by whether there was a SetCallStatus or not. (Panics detected in EndCall are considered errors).
StartCalls can be nested.
func StartSpanAsync
deprecated
added in
v1.25.0
func StartTracing
deprecated
Types ¶
type Annotator ¶ added in v1.42.0
type Annotator struct {
// contains filtered or unexported fields
}
Annotator is a SpanProcessor that adds service-level tags on every span
func (Annotator) OnEnd ¶ added in v1.42.0
func (a Annotator) OnEnd(s sdktrace.ReadOnlySpan)
type Config ¶
type Config struct { Otel `yaml:"OpenTelemetry"` GlobalTags `yaml:"GlobalTags,omitempty"` }
tracing config goes into trace.yaml
type GlobalTags ¶ added in v1.1.0
type GlobalTags struct {
DevEmail string `yaml:"DevEmail,omitempty"`
}
func (*GlobalTags) MarshalLog ¶ added in v1.1.0
func (g *GlobalTags) MarshalLog(addField func(key string, v interface{}))