Documentation
¶
Overview ¶
Package tracing records what a request does as a tree of timed spans, and exports them to OpenTelemetry collectors and the services that take OTLP, such as Grafana Tempo, Honeycomb, Jaeger or Datadog:
tracer := tracing.New(tracing.Options{Exporters: []tracing.Exporter{otlp.New(otlp.Options{})}})
tracing.SetDefault(tracer)
server, err := ternApp(kit.WithTracer(tracer))
kit starts a span for each request, and one for each load, action, endpoint and server render in it. Add your own with Start:
ctx, span := tracing.Start(ctx, "charge card", slog.String("order", id))
defer span.End()
Spans join the logs: a record logged inside a span carries its trace_id and span_id. Trace context follows work out of the process through Transport for HTTP requests and through the jobs queue, and comes in with a W3C traceparent header from a trusted proxy or service. Under tern dev, the log view shows each request's spans as a waterfall.
It is a small, dependency-free implementation of OpenTelemetry's tracing model, not its SDK: spans, events, status, parent-based sampling and W3C trace context.
Index ¶
- func ContextWith(ctx context.Context, span *Span) context.Context
- func Inject(r *http.Request)
- func OpenDB(driverName, dsn string) (*sql.DB, error)
- func Permanent(err error) error
- func SetDefault(t *Tracer)
- func Transport(base http.RoundTripper) http.RoundTripper
- func WrapConnector(c driver.Connector, system string) driver.Connector
- type Batch
- type DevSpan
- type Event
- type Exporter
- type ExporterFunc
- type Kind
- type Options
- type Span
- func (s *Span) AddEvent(name string, attrs ...slog.Attr)
- func (s *Span) Context() SpanContext
- func (s *Span) End()
- func (s *Span) IsRecording() bool
- func (s *Span) RecordError(err error)
- func (s *Span) SetAttrs(attrs ...slog.Attr)
- func (s *Span) SetName(name string)
- func (s *Span) SetStatus(code StatusCode, message string)
- type SpanContext
- type SpanData
- type SpanID
- type StartOption
- type Stats
- type Status
- type StatusCode
- type TraceID
- type Tracer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContextWith ¶
ContextWith returns ctx carrying span, and its IDs for the logs.
func Inject ¶
Inject sets the traceparent header for the span in r's context, so the service r goes to continues the trace.
func OpenDB ¶
OpenDB opens a database like sql.Open, with each query a client span inside the trace of the context it runs with:
db, err := tracing.OpenDB("sqlite", "app.db")
Queries without a span in their context, such as at startup, record nothing.
func SetDefault ¶
func SetDefault(t *Tracer)
SetDefault makes t the tracer of spans started without a parent, such as those of jobs and of code that doesn't run in a request.
func Transport ¶
func Transport(base http.RoundTripper) http.RoundTripper
Transport wraps base (http.DefaultTransport if nil) so each request is a client span, and carries the trace to the server it goes to:
client := &http.Client{Transport: tracing.Transport(nil)}
Types ¶
type DevSpan ¶
type DevSpan struct {
TraceID string `json:"trace"`
SpanID string `json:"span"`
Parent string `json:"parent,omitempty"`
Name string `json:"name"`
Kind string `json:"kind"`
Start time.Time `json:"start"`
Micros int64 `json:"us"`
Error string `json:"error,omitempty"`
RequestID string `json:"request_id,omitempty"`
Attrs map[string]any `json:"attrs,omitempty"`
}
DevSpan is a span as tern dev's log view reads it.
type Exporter ¶
An Exporter sends finished spans somewhere, in batches, from one goroutine. Return Permanent for errors that retrying won't fix.
type ExporterFunc ¶
ExporterFunc makes a function an Exporter.
type Kind ¶
type Kind int
Kind is what a span does, as OpenTelemetry has it.
type Options ¶
type Options struct {
// Exporters get every recorded span.
Exporters []Exporter
// Sample is the fraction of new traces recorded, from 0 to 1. Traces
// that come in from elsewhere keep their own decision. The default is
// TERN_TRACE_SAMPLE's, or 1: everything.
Sample float64
// Batch says how spans are batched for exporters.
Batch Batch
}
Options configures a tracer.
type Span ¶
type Span struct {
// contains filtered or unexported fields
}
Span is an operation being timed. A Span that isn't recorded (no tracer, or not sampled) still carries its IDs, so logs and outgoing requests keep the trace; its other methods do nothing. All methods are safe on a nil *Span.
func FromContext ¶
FromContext returns the span ctx carries, or nil.
func Start ¶
Start starts a span as a child of the span in ctx (or a remote parent), and returns ctx carrying it. The span is recorded by its parent's tracer, or the default one. End it when the work is done. With no tracer and no trace to continue, it returns ctx and a nil span, whose methods do nothing.
func (*Span) End ¶
func (s *Span) End()
End finishes the span and hands it to the exporters. Calls after the first do nothing.
func (*Span) IsRecording ¶
IsRecording reports whether the span will be exported.
func (*Span) RecordError ¶
RecordError records err as an exception event and marks the span failed. A nil err does nothing.
func (*Span) SetStatus ¶
func (s *Span) SetStatus(code StatusCode, message string)
SetStatus sets the span's outcome. An Error is kept over a later OK.
type SpanContext ¶
SpanContext is what travels between processes: the trace, the span, and whether the trace is recorded.
func ParseTraceparent ¶
func ParseTraceparent(s string) (SpanContext, bool)
ParseTraceparent reads a W3C traceparent header.
func (SpanContext) IsValid ¶
func (sc SpanContext) IsValid() bool
IsValid reports whether both IDs are set.
func (SpanContext) Traceparent ¶
func (sc SpanContext) Traceparent() string
Traceparent is the W3C traceparent header for sc.
type SpanData ¶
type SpanData struct {
Context SpanContext
Parent SpanID // zero for a root span
Name string
Kind Kind
Start time.Time
End time.Time
Attrs []slog.Attr
Events []Event
Status Status
}
SpanData is a finished span, as exporters get it.
type StartOption ¶
type StartOption func(*startConfig)
StartOption configures a span started with Start.
func AsRoot ¶
func AsRoot() StartOption
AsRoot starts a new trace, ignoring any span in the context.
func WithAttrs ¶
func WithAttrs(attrs ...slog.Attr) StartOption
WithAttrs sets attributes at the start.
func WithKind ¶
func WithKind(k Kind) StartOption
WithKind sets the span's kind. The default is Internal.
func WithRemoteParent ¶
func WithRemoteParent(sc SpanContext) StartOption
WithRemoteParent makes the span a child of a span in another process, from a traceparent header or a queued job.
func WithTracer ¶
func WithTracer(t *Tracer) StartOption
WithTracer records the span with t rather than the parent's tracer or the default.
type Stats ¶
type Stats struct {
Dropped uint64 // an exporter's queue was full
Failed uint64 // an exporter didn't take them after retrying
}
Stats counts spans a tracer didn't export.
type Status ¶
type Status struct {
Code StatusCode
Message string
}
Status is a span's outcome and, for errors, its message.
type StatusCode ¶
type StatusCode int
StatusCode is a span's outcome.
const ( Unset StatusCode = 0 OK StatusCode = 1 Error StatusCode = 2 )
The codes, numbered as in OTLP.
type Tracer ¶
type Tracer struct {
// contains filtered or unexported fields
}
Tracer records spans and hands them to exporters. Make one with New.
func DevOnly ¶
func DevOnly() *Tracer
DevOnly returns a tracer that records every span for tern dev's log view alone, or nil outside tern dev. kit uses it when the app has no tracer of its own.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package otlp exports spans to an OpenTelemetry collector, or any service that takes OTLP over HTTP (Grafana Tempo, Honeycomb, Jaeger, SigNoz, Datadog, New Relic…), as OTLP/HTTP JSON:
|
Package otlp exports spans to an OpenTelemetry collector, or any service that takes OTLP over HTTP (Grafana Tempo, Honeycomb, Jaeger, SigNoz, Datadog, New Relic…), as OTLP/HTTP JSON: |