telemetry

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 9 Imported by: 2

Documentation

Overview

Package telemetry holds the logging and tracing seams handlers reach through.

The interfaces are here, in core, so that a handler can log and trace without core depending on any particular implementation. The OpenTelemetry and structured-logging wiring lives behind them.

Index

Constants

View Source
const (
	// LogLevelEnvVar is the lowest level written: debug, info, warn or error.
	// Anything else, including an empty value, is info.
	LogLevelEnvVar = "CELERITY_LOG_LEVEL"
	// LogFormatEnvVar is json, human, or auto. Auto, which is the default,
	// writes human-readable records in a development session and JSON
	// everywhere else.
	LogFormatEnvVar = "CELERITY_LOG_FORMAT"
)

Environment variables a deployment configures logging with.

The same names the other SDKs read, so one deployment configures every language the same way.

View Source
const (
	FormatJSON  = "json"
	FormatHuman = "human"
	FormatAuto  = "auto"
)

Log formats a deployment can ask for.

View Source
const (
	TraceParentHeader = "traceparent"
	TraceStateHeader  = "tracestate"
)
View Source
const (
	TraceIDKey = "trace_id"
	SpanIDKey  = "span_id"
)

Log attributes naming the trace a record belongs to.

The names OpenTelemetry's own conventions use, so that a backend correlating logs with traces finds them without being told where to look.

Variables

This section is empty.

Functions

func Flush

func Flush(ctx context.Context) error

Flush hands over what is held, and does nothing where nothing is installed.

Nothing rather than an error: an application that exports no telemetry has nothing to flush, and that is a typical case rather than a misconfiguration.

func NewHandler

func NewHandler(out io.Writer, platform string) slog.Handler

NewHandler returns the handler NewLogger writes through.

Exported so that an application adding attributes of its own, or wrapping this in a handler that samples, starts from the same format rather than rebuilding it.

func NewLogger

func NewLogger(out io.Writer, platform string) *slog.Logger

NewLogger returns the logger an application writes through where it supplies none of its own.

JSON by default, because a deployed application's records are read by a log aggregator rather than by a person. Human-readable in a development session, where they are read by a person as they scroll past and JSON is noise around the one line they are looking for.

An application that wants something else passes it to [celerity.WithLogger], and anything slog can write through works, the format here is a default rather than a constraint.

func SetFlusher

func SetFlusher(f Flusher)

SetFlusher installs what Flush calls, replacing anything already installed.

Called from the init of the module that configured an exporter. An application exporting telemetry it set up itself installs its own, so that a shutdown flushes what the application built rather than nothing.

func SetTracer

func SetTracer(t Tracer)

SetTracer installs the tracer this process traces with, replacing any already installed.

Called from the init of the module holding an implementation, which is what lets the generated platform file be a blank import rather than wiring. An application supplying its own, or a test supplying a recorder, calls it directly.

func Traced

func Traced[T any](
	ctx context.Context,
	name string,
	attrs []Attr,
	fn func(context.Context, Span) (T, error),
) (T, error)

Traced runs fn inside a span, recording a failure and ending the span whatever happens.

What a resource operation uses, so that tracing one is a line rather than a span's whole lifecycle:

return telemetry.Traced(ctx, "celerity.bucket.get",
    []telemetry.Attr{telemetry.String("bucket.key", key)},
    func(ctx context.Context, _ telemetry.Span) (*bucket.Object, error) { ... })

The context fn is given is the span's, so anything it traces in turn is a child. The span is given as well, for what is only known once the call has been made, such as how many entries of a batch were taken, or how large an answer was. A panic ends the span and records nothing of its own before carrying on up, since the recovery that can describe it is the dispatch loop's.

func TracedCall

func TracedCall(
	ctx context.Context,
	name string,
	attrs []Attr,
	fn func(context.Context, Span) error,
) error

TracedCall is Traced for an operation that answers with nothing but a failure.

func WithLogger

func WithLogger(ctx context.Context, l Logger) context.Context

WithLogger returns a context carrying a logger, with the event's identifiers already attached by the framework.

func WithTraceContext

func WithTraceContext(ctx context.Context, tc TraceContext) context.Context

WithTraceContext returns a context carrying the trace context a dispatch arrived with.

Types

type Attr

type Attr struct {
	Key   string
	Value any
}

Attr is one key and value recorded on a span.

The value is typed by the constructors rather than by the field, so that an implementation translating to its own representation has something to switch on and a caller cannot record a value no backend accepts.

func Bool

func Bool(key string, value bool) Attr

Bool records a true-or-false attribute.

func Float64

func Float64(key string, value float64) Attr

Float64 records a number attribute that is not whole.

func Int

func Int(key string, value int) Attr

Int records a whole-number attribute.

func Int64

func Int64(key string, value int64) Attr

Int64 records a whole-number attribute.

func String

func String(key, value string) Attr

String records a string attribute.

type Flusher

type Flusher func(ctx context.Context) error

Flusher hands over whatever telemetry is held but not yet exported.

A batch of spans is held so that exporting is not a network call per span, which means a process that stops without flushing loses what it had not sent. Two places have to ask for it, a runtime shutting down, and a serverless invocation returning, because an execution environment is frozen between invocations rather than left running and a batch sitting in one is a batch nobody sends.

type Logger

type Logger = *slog.Logger

Logger is the logging seam.

It is slog.Handler-shaped rather than an interface of its own so that any slog handler an application already has works unchanged.

func LoggerFrom

func LoggerFrom(ctx context.Context) Logger

LoggerFrom returns the logger for the event being handled.

It never returns nil: without one it falls back to slog's default, so a handler can log unconditionally.

type Span

type Span interface {
	// SetAttributes adds to what the span records, for something not known
	// when it started.
	SetAttributes(attrs ...Attr)
	// RecordError marks the span as failed and records what failed.
	RecordError(err error)
	// End stops the span. Every span has to be ended, and ending one twice is
	// the implementation's to tolerate rather than the caller's to avoid.
	End()
	// Context identifies the span within the trace it belongs to, so that a log
	// written during it can be found from the trace and the trace from the log.
	Context() SpanContext
}

Span is one timed operation.

type SpanContext

type SpanContext struct {
	TraceID string
	SpanID  string
}

SpanContext identifies one span within one trace.

Strings rather than the byte arrays a tracing library holds them as, because what they are for here is being written into a log record and read back by a person or a query. The zero value is what a span that is not being recorded answers with, which is also what an application exporting nothing gets.

func (SpanContext) Recorded

func (c SpanContext) Recorded() bool

Recorded reports whether the span belongs to a trace that is being recorded.

type TraceContext

type TraceContext map[string]string

TraceContext carries W3C traceparent and tracestate across the process boundary, which is how a trace started upstream of the runtime continues through a handler.

func TraceContextFrom

func TraceContextFrom(ctx context.Context) (TraceContext, bool)

TraceContextFrom returns the trace context the event arrived with.

type Tracer

type Tracer interface {
	Start(ctx context.Context, name string, attrs ...Attr) (context.Context, Span)
}

Tracer starts spans.

Shaped after OpenTelemetry's own tracer, since that is what a Go application already traces with and what the implementation behind this seam adapts to. It is declared here so that core doesn't depend on a tracing library, an application that traces nothing links none, and one that does links the module holding it.

A span is started with the context it belongs to and returns a new one carrying it, which is what makes the next span a child of this one. Most callers will use Traced rather than this.

func CurrentTracer

func CurrentTracer() Tracer

CurrentTracer returns the installed tracer, and a tracer that records nothing where none is installed.

Never nil, so a caller traces unconditionally and an application that linked no implementation pays a call that does nothing rather than a branch at every call site.

Directories

Path Synopsis
otel module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL