Help us shape the future of Go! Take the 2026 Go Developer Survey

tracing

package module
v0.1.61 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package traces runs trace plugins: kinds of capture that each declare a params form and a record schema, and emit records a record store keeps.

Index

Examples

Constants

View Source
const ProfilePrefix = "traces/"

ProfilePrefix names every trace session's profile, traces/<kind>, which keys its authorization and restart.

View Source
const TruncatedColumn = "truncated"

TruncatedColumn is the column WithTruncation lists the cut values' paths in.

Variables

View Source
var (
	ErrUnknownKind   = errors.New("unknown trace kind")
	ErrInvalidParams = errors.New("invalid trace params")
	// ErrNoCapture is a session id that names no capture the runtime is
	// running: unknown, ended, or not a trace capture.
	ErrNoCapture = errors.New("no running trace capture")
)
View Source
var ErrCheckpointParams = errors.New("invalid checkpoint params")

ErrCheckpointParams is a checkpoint whose params its kind refuses, or never reads: a kind that takes no readings, or reads none of them.

View Source
var ErrInvalidRef = errors.New("invalid trace ref")

ErrInvalidRef refuses a TraceRef that names no window.

View Source
var ErrUnknownFormat = errors.New("unknown export format")

ErrUnknownFormat refuses an export in a format its kind does not offer.

View Source
var NDJSON = ExportFormat{Name: "ndjson", Ext: "ndjson", MIME: "application/x-ndjson"}

NDJSON is the format every kind exports in: its rows as stored, one JSON object per line.

Functions

func DecodeCheckpointParams

func DecodeCheckpointParams(ctx context.Context, into any) (bool, error)

DecodeCheckpointParams decodes the params of the checkpoint a Checkpointer reads under into into, refusing unknown fields, and reports whether its host gave any.

func ReadRecords

func ReadRecords[R any](ctx context.Context, r *Runtime, ref TraceRef, fn func(R) error) error

ReadRecords reads the records of ref's window as the kind's Records reads them back, refusing an R that is not the kind's record type.

func StreamOf

func StreamOf(ctx context.Context) string

StreamOf is the stream a capture's records are written to, from the context its Prepare and Handle run under. A kind that writes companion streams, such as bodies kept apart from its records, names them after it.

func WithCheckpointParams

func WithCheckpointParams(ctx context.Context, params json.RawMessage) context.Context

WithCheckpointParams has the checkpoints marked under ctx carry params, a JSON object the checkpointed kind decodes with DecodeCheckpointParams, such as which part of the capture to read and why. Empty params, or null, are none.

Types

type Capabilities

type Capabilities struct {
	Live       bool `json:"live,omitempty"`
	Historical bool `json:"historical,omitempty"`
	Follow     bool `json:"follow,omitempty"`
}

Capabilities say how a kind captures: Live captures what happens while a session runs, Historical reads what already happened and ends by itself, Follow goes on to capture what happens next.

type Checkpointer

type Checkpointer[P, R any] interface {
	Checkpoint(ctx dbcontext.Context, params P, records Emitter[R]) error
}

Checkpointer is a TraceHandler that takes a reading at each checkpoint its host marks in a running capture, such as the end of each step a span covers: the value of an expression, the state of a cache. Its records are committed before the checkpoint returns.

type Emitter

type Emitter[R any] interface {
	// Emit waits while the session's buffer is full, and returns ctx's error
	// once it is done.
	Emit(ctx context.Context, record R) error
	// TryEmit never waits: a record a full buffer cannot take is dropped and
	// counted, so a handler called on someone else's goroutine never stalls it.
	TryEmit(record R) bool
	// Report replaces the kind's own summary of its capture, what it counts
	// beyond the records it emits, such as events its source lost. The
	// session shows the latest report with its progress and keeps the last.
	Report(summary any)
	// Warn adds a warning the session ends with.
	Warn(message string)
	// Describe names the session by what the capture set up on its source,
	// with the statements or settings that set it up. A session records them
	// once, as it starts running, so only a Preparer's Prepare describes it.
	Describe(handle string, metadata ...query.SessionMetadata)
	// Export hands the processes the capture observes an environment
	// variable, such as the address of a proxy it listens on. A session
	// records its exports once, as it starts running, so only a Preparer's
	// Prepare exports: a name that is no environment variable name, or one
	// exported twice, refuses the start, and an export once the capture runs
	// is left out and warns the session. A host reads them from the session's
	// status (query.SessionStatus.Exports) as soon as Runtime.Start returns.
	Export(name, value string)
}

Emitter takes a handler's records.

type ExportFormat

type ExportFormat struct {
	Name string `json:"name"`
	Ext  string `json:"ext"`
	MIME string `json:"mime"`
}

ExportFormat is a format a kind's records download in: its name, the extension of the file it downloads as, and its media type.

type Exporter

type Exporter[R any] interface {
	Formats() []ExportFormat
	// Export writes rows, a window's records as Records reads them back, in
	// format, one of Formats.
	Export(format string, rows iter.Seq[R], w io.Writer) error
}

Exporter is a TraceHandler that downloads its records in formats of its own, beyond NDJSON, such as HAR for HTTP exchanges.

type Handler

type Handler[P, R any] struct {
	// contains filtered or unexported fields
}

Handler is a TraceHandler as a TracePlugin, with the processing its records get before they are stored.

func NewHandler

func NewHandler[P, R any](handler TraceHandler[P, R], capabilities Capabilities) *Handler[P, R]

NewHandler makes handler a plugin with capabilities.

Example
// A minimal trace kind written outside this package: its params, its record
// schema, and a capture that emits until stopped, registered on a catalog.

package main

import (
	"fmt"
	"time"

	dbcontext "github.com/flanksource/commons-db/context"
	"github.com/flanksource/commons-db/recordstore/recordresults"
	"github.com/flanksource/commons-db/tracing"
)

// HeartbeatParams is the form a client fills to start a heartbeat capture.
type HeartbeatParams struct {
	Every string `json:"every,omitempty" clicky:"title=Every"`
}

// Heartbeat is one record a heartbeat capture stores.
type Heartbeat struct {
	At   time.Time `json:"at" pretty:"label=At"`
	Beat int       `json:"beat"`
}

type heartbeats struct{}

func (heartbeats) Params() HeartbeatParams { return HeartbeatParams{Every: "1s"} }

func (heartbeats) Schema() recordresults.ResultType[Heartbeat] {
	return recordresults.ResultType[Heartbeat]{Title: "Heartbeats", TimeColumn: "at"}
}

func (heartbeats) Handle(ctx dbcontext.Context, params HeartbeatParams, records tracing.Emitter[Heartbeat], _ tracing.Records[Heartbeat]) error {
	every, err := time.ParseDuration(params.Every)
	if err != nil {
		return err
	}
	for beat := 1; ; beat++ {
		select {
		case <-ctx.Done():
			return nil
		case <-time.After(every):
		}
		if err := records.Emit(ctx, Heartbeat{At: time.Now().UTC(), Beat: beat}); err != nil {
			return err
		}
	}
}

func main() {
	kinds := tracing.NewKinds()
	if err := kinds.RegisterKind("heartbeat", tracing.NewHandler[HeartbeatParams, Heartbeat](heartbeats{}, tracing.Capabilities{Live: true})); err != nil {
		panic(err)
	}
	infos, err := kinds.List()
	if err != nil {
		panic(err)
	}
	for _, info := range infos {
		fmt.Println(info.Name, info.Title, info.Params.Properties["every"].Default, len(info.Columns))
	}
}
Output:
heartbeat Heartbeats 1s 2

func (*Handler[P, R]) Capabilities

func (h *Handler[P, R]) Capabilities() Capabilities

func (*Handler[P, R]) ExportFormats

func (h *Handler[P, R]) ExportFormats() []ExportFormat

ExportFormats are the formats the kind exports in: NDJSON, then its own.

func (*Handler[P, R]) Params

func (h *Handler[P, R]) Params() (*rpc.OpenAPISchema, error)

func (*Handler[P, R]) Schema

func (h *Handler[P, R]) Schema(kind string) (recordstore.KindSchema, error)

func (*Handler[P, R]) Title

func (h *Handler[P, R]) Title() string

func (*Handler[P, R]) ValidateParams

func (h *Handler[P, R]) ValidateParams(params json.RawMessage) error

func (*Handler[P, R]) WithDeduplication

func (h *Handler[P, R]) WithDeduplication(key func(R) string, window func(P) time.Duration) *Handler[P, R]

WithDeduplication drops a record whose key a session already emitted within the window its params give; a window of zero or less keeps every record.

func (*Handler[P, R]) WithDefaults

func (h *Handler[P, R]) WithDefaults(defaults P) *Handler[P, R]

WithDefaults starts the kind's form and its captures from defaults rather than the handler's own Params, as a host that knows its connections does.

func (*Handler[P, R]) WithJSONProcessor

func (h *Handler[P, R]) WithJSONProcessor(paths ...string) *Handler[P, R]

WithJSONProcessor parses the text fields at paths, dotted JSON names such as "response.content.text", when they hold a JSON object or array, so their fields are stored, masked and filtered as structure. Records read back through Records hold that JSON as text again. Each path must name a string field of R.

func (*Handler[P, R]) WithSecretMasking

func (h *Handler[P, R]) WithSecretMasking(keep ...string) *Handler[P, R]

WithSecretMasking masks secrets in every record (maskSecrets), never masking the keys named in keep, at any depth.

func (*Handler[P, R]) WithTruncation

func (h *Handler[P, R]) WithTruncation(maxBytes int) *Handler[P, R]

WithTruncation cuts every string in a record longer than maxBytes, listing what it cut in the record's Truncation, which R must embed.

type KindInfo

type KindInfo struct {
	Name         string             `json:"name"`
	Title        string             `json:"title"`
	Capabilities Capabilities       `json:"capabilities"`
	Params       *rpc.OpenAPISchema `json:"params"`
	Columns      []query.ColumnDef  `json:"columns"`
	// ExportFormats are the formats a window of the kind's records downloads
	// in, NDJSON first.
	ExportFormats []ExportFormat `json:"exportFormats"`
}

KindInfo describes one registered kind.

type Kinds

type Kinds struct {
	// contains filtered or unexported fields
}

Kinds is the trace plugins a host serves, by kind name.

func NewKinds

func NewKinds() *Kinds

func (*Kinds) Format

func (k *Kinds) Format(kind, format string) (ExportFormat, error)

Format is the export format named format of kind, refusing an unknown kind (ErrUnknownKind) and a format the kind does not offer (ErrUnknownFormat).

func (*Kinds) Get

func (k *Kinds) Get(name string) (TracePlugin, bool)

Get finds the plugin registered as name.

func (*Kinds) List

func (k *Kinds) List() ([]KindInfo, error)

List describes every registered kind, by name.

func (*Kinds) RegisterKind

func (k *Kinds) RegisterKind(name string, plugin TracePlugin) error

RegisterKind serves plugin as kind name, refusing a plugin whose params or schema could not be described, and a name already taken.

func (*Kinds) RegisterResultTypes

func (k *Kinds) RegisterResultTypes(registry *recordresults.Registry) error

RegisterResultTypes declares every kind's result type into registry, which is how a results store opened with it (recordresults.OpenOptions.Register) knows the kinds' schemas and serves their <prefix>/<kind> profiles.

type Preparer

type Preparer[P, R any] interface {
	Prepare(ctx dbcontext.Context, params P, records Emitter[R]) (prepared dbcontext.Context, release func() error, err error)
}

Preparer is a TraceHandler whose capture must be set up before its session runs: a subscription that must not miss a record, or a server-side session whose failure should refuse the start. Prepare runs as the session starts, before it reports running; Handle then runs under the context Prepare returns, which can carry what it set up, and release runs once Handle has returned, or at once if the capture never started. A release that fails is the session's error, its records still committed and sealed.

type Records

type Records[R any] interface {
	Scan(ctx context.Context, afterSeq int64, fn func(seq int64, record R) error) error
}

Records reads back the records a session has committed.

type Runtime

type Runtime struct {
	Kinds    *Kinds
	Sessions *query.SessionRegistry
	Probes   *probe.Manager
	// Results is the store the captures' records are committed to, opened
	// with Kinds.RegisterResultTypes.
	Results *recordresults.Results

	// PollEvery is how often a running capture's records are committed.
	// Zero is a second.
	PollEvery time.Duration
	// BufferRows caps the records a capture holds before they are committed.
	// Zero is 10,000; it is never more than one sample of the probe commits.
	BufferRows int
	// BufferBytes caps the bytes of records a capture holds before they are
	// committed, measured by their keys and text. Zero is 64MiB.
	BufferBytes int
	// contains filtered or unexported fields
}

Runtime starts captures of the kinds it serves.

func (*Runtime) Checkpoint

func (r *Runtime) Checkpoint(ctx context.Context, managed *query.ManagedSession) error

Checkpoint marks a checkpoint in a running capture: a kind that is a Checkpointer takes its reading, and the session is then sampled, so the reading and anything the capture emitted before it are committed when Checkpoint returns. The session's background polls are not checkpoints. Params ctx carries (WithCheckpointParams) go to the kind's reading; ones it refuses or never reads are ErrCheckpointParams.

func (*Runtime) CheckpointSession

func (r *Runtime) CheckpointSession(ctx context.Context, id string) error

CheckpointSession is Checkpoint for the running capture of session id, for a host that holds only the id, such as a client of the sessions API. An id that names no capture this runtime is running is ErrNoCapture.

func (*Runtime) Export

func (r *Runtime) Export(ctx context.Context, ref TraceRef, format string, w io.Writer) error

Export writes ref's window to w in format, one of its kind's ExportFormats.

func (*Runtime) Mark

func (r *Runtime) Mark(ctx context.Context, managed *query.ManagedSession) (int64, error)

Mark checkpoints managed (Checkpoint) and returns the seq its stream has committed through: 0 for a stream that has committed nothing yet. Records the capture emitted before Mark are at or below it, so two marks bound a window exactly.

func (*Runtime) Read

func (r *Runtime) Read(ctx context.Context, ref TraceRef, fn func(seq int64, row recordstore.Row) error) error

Read reads the rows of ref's window as stored, in seq order.

func (*Runtime) Restarter

func (r *Runtime) Restarter(base func() dbcontext.Context) query.RestartFunc

Restarter re-arms an ended trace session as a new capture of its kind with its params, under a context base gives the restart's request.

func (*Runtime) Start

func (r *Runtime) Start(ctx dbcontext.Context, request StartRequest) (*query.ManagedSession, error)

Start begins a capture of request.Kind into a new stream, as a managed session that ends at StopAt, on a stop, or when a historical capture is done. It refuses an unknown kind (ErrUnknownKind) and params the kind refuses (ErrInvalidParams) before any session exists.

func (*Runtime) Summarize

func (r *Runtime) Summarize(ctx context.Context, ref TraceRef) (map[string]any, error)

Summarize is the kind's summary of ref's window: what its Summarizer makes of the records, and always their count.

type StartRequest

type StartRequest struct {
	Kind   string
	Params json.RawMessage
	// StopAt ends the capture; nil runs it for the registry's longest duration.
	StopAt    *time.Time
	Labels    map[string]string
	Principal string
	RestartOf string
}

StartRequest is one capture to start.

type Summarizer

type Summarizer[R any] interface {
	Summarize(rows iter.Seq[R]) (map[string]any, error)
}

Summarizer is a TraceHandler that summarizes a window of its records, as the variables an assertion over the window reads. The summary's count is always the window's records, whatever Summarize says.

type Summary

type Summary struct {
	Emitted      int64 `json:"emitted"`
	Deduplicated int64 `json:"deduplicated,omitempty"`
	Dropped      int64 `json:"dropped,omitempty"`
	Unencodable  int64 `json:"unencodable,omitempty"`
	Collapsed    int64 `json:"collapsed,omitempty"`
	// Report is the kind's own summary, as it last reported it.
	Report any `json:"report,omitempty"`
}

Summary counts what a capture's handler emitted: the records buffered for the store, those it lost before they got there, and the copies of a key one page collapsed, which the store never saw.

type TraceHandler

type TraceHandler[P, R any] interface {
	// Params are the defaults a session starts from; P's type is the params
	// form a client renders.
	Params() P
	// Schema declares how R's records are stored and read: its title, time
	// and key columns, indexes. R's own columns are reflected from its fields.
	Schema() recordresults.ResultType[R]
	// Handle captures until ctx is done, or until its source is exhausted,
	// emitting each record. It may read back the records it already emitted.
	Handle(ctx dbcontext.Context, params P, records Emitter[R], store Records[R]) error
}

TraceHandler is a trace kind's implementation over its params P and its records R.

type TracePlugin

type TracePlugin interface {
	// Title is the kind's human name.
	Title() string
	// Params is the JSON schema of the kind's params, with their defaults: the
	// form a client renders to start a capture.
	Params() (*rpc.OpenAPISchema, error)
	// Schema is the record-store schema the kind's records are stored under
	// when it is registered as kind.
	Schema(kind string) (recordstore.KindSchema, error)
	Capabilities() Capabilities
	// ValidateParams decodes params as a session start would, refusing what
	// the session would refuse.
	ValidateParams(params json.RawMessage) error
	// ExportFormats are the formats the kind's records download in: NDJSON,
	// then those of a kind that is an Exporter.
	ExportFormats() []ExportFormat
	// contains filtered or unexported methods
}

TracePlugin is a trace kind as the kinds catalog holds it.

type TraceRef

type TraceRef struct {
	Kind     string `json:"kind"`
	Stream   string `json:"stream"`
	AfterSeq int64  `json:"afterSeq,omitempty"`
	ToSeq    int64  `json:"toSeq,omitempty"`
}

TraceRef names a window of a capture's records: the rows of kind's stream after seq AfterSeq, through seq ToSeq. An AfterSeq of 0 starts at the stream's first row, a ToSeq of 0 runs to its last. A host takes both from Runtime.Mark. A kind whose later rows replace earlier ones, by key, moves a replaced row to the seq of its replacement, so a window holds the rows that last changed within it.

func (TraceRef) Params

func (r TraceRef) Params() map[string]any

Params are the params of the kind's result profile, traces/<kind>, that read the ref's window.

func (TraceRef) Validate

func (r TraceRef) Validate() error

Validate refuses a ref without a kind or stream, or whose window holds a negative seq or ends before it starts.

type Truncation

type Truncation struct {
	Truncated []string `json:"truncated,omitempty" pretty:"label=Truncated"`
}

Truncation is the column a record embeds to carry the paths of the values WithTruncation cut, which a kind that truncates must declare.

type Validator

type Validator interface {
	Validate() error
}

Validator is implemented by params that check themselves once decoded.

Directories

Path Synopsis
Package goprof is a trace kind that reads the pprof profiles of the Go processes of a tree at each checkpoint its host marks: over a process's net/http/pprof server or gops agent, or from a -cpuprofile/-memprofile file a test binary wrote.
Package goprof is a trace kind that reads the pprof profiles of the Go processes of a tree at each checkpoint its host marks: over a process's net/http/pprof server or gops agent, or from a -cpuprofile/-memprofile file a test binary wrote.
Package http is the http trace kind: it records the outbound HTTP exchanges commons-db makes for chosen features, one HAR entry per record.
Package http is the http trace kind: it records the outbound HTTP exchanges commons-db makes for chosen features, one HAR entry per record.
Package httpproxy is the http_proxy trace kind: a recording HTTP proxy the processes a capture observes are pointed at through the environment it exports, storing each exchange it relays as an http.Exchange.
Package httpproxy is the http_proxy trace kind: a recording HTTP proxy the processes a capture observes are pointed at through the environment it exports, storing each exchange it relays as an http.Exchange.
jfr
Package jfr is a trace kind that profiles a JVM with a JFR recording, made by the JDK's Flight Recorder or by async-profiler, and stores what each dump of the recording adds as samples aggregated by stack.
Package jfr is a trace kind that profiles a JVM with a JFR recording, made by the JDK's Flight Recorder or by async-profiler, and stores what each dump of the recording adds as samples aggregated by stack.
Package opensearch is the opensearch trace kind: span documents of an opentelemetry connection's index, imported over a window or followed.
Package opensearch is the opensearch trace kind: span documents of an opentelemetry connection's index, imported over a window or followed.
Package pgproxy is the pg_proxy trace kind: a postgres wire proxy that processes under capture are pointed at through the environment the session exports.
Package pgproxy is the pg_proxy trace kind: a postgres wire proxy that processes under capture are pointed at through the environment the session exports.
Package process holds the process trace kinds: process_tree records each process under a root as it starts, changes and exits, and process_samples records the CPU, memory, disk IO and armed facets of every one of them at each tick.
Package process holds the process trace kinds: process_tree records each process under a root as it starts, changes and exits, and process_samples records the CPU, memory, disk IO and armed facets of every one of them at each tick.
sqlserver
deadlocks
Package deadlocks turns SQL Server xml_deadlock_report graphs into decoded, index-resolved and classified Deadlocks.
Package deadlocks turns SQL Server xml_deadlock_report graphs into decoded, index-resolved and classified Deadlocks.
xesession
Package xesession runs live SQL Server Extended Events captures: it creates the XE session, drains its target, and commits every captured event as a row of a sql_xevent record stream, which is where every reader — a result profile, a follower, a step's checkpoint window — reads them back from.
Package xesession runs live SQL Server Extended Events captures: it creates the XE session, drains its target, and commits every captured event as a row of a sql_xevent record stream, which is where every reader — a result profile, a follower, a step's checkpoint window — reads them back from.
xetrace
Package xetrace manages short-lived SQL Server Extended Events sessions backed by a ring_buffer or event_file target, and attaches to the built-in system_health session.
Package xetrace manages short-lived SQL Server Extended Events sessions backed by a ring_buffer or event_file target, and attaches to the built-in system_health session.
xevent
Package xevent is the sql_xevent trace kind: a SQL Server Extended Events capture whose events are stored as xesession event rows.
Package xevent is the sql_xevent trace kind: a SQL Server Extended Events capture whose events are stored as xesession event rows.
Package sqlstatements is the sql_statements trace kind: it records the SQL statements commons-db runs on chosen connections, as the SQL statement tap publishes them, and summarizes them as it goes.
Package sqlstatements is the sql_statements trace kind: it records the SQL statements commons-db runs on chosen connections, as the SQL statement tap publishes them, and summarizes them as it goes.
sqltrace module
Package stacks is a trace kind that dumps the stacks of the processes of a tree at each checkpoint its host marks, storing one record per goroutine of a Go dump, or one per dump of a native one.
Package stacks is a trace kind that dumps the stacks of the processes of a tree at each checkpoint its host marks, storing one record per goroutine of a Go dump, or one per dump of a native one.
Package terminal is the terminal trace kind: it records a PTY session its host feeds it, and exports it as an asciinema v2 cast.
Package terminal is the terminal trace kind: it records a PTY session its host feeds it, and exports it as an asciinema v2 cast.
traces module
Package tracingtest runs trace plugins in specs: a runtime over a real sqlite results store and session registry, and helpers that read a session's rows.
Package tracingtest runs trace plugins in specs: a runtime over a real sqlite results store and session registry, and helpers that read a session's rows.

Jump to

Keyboard shortcuts

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