profilequery

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package profilequery reads continuous profiles back out of ClickHouse and writes them in formats other tools open.

It is the reusable half of `forge obs profile`: nothing here shells out or touches a terminal. Stacks come from the tables docker-compose.yml's `profiles-schema` job creates (see profiles-schema.sql in a scaffolded project); Stack is the interchange value, and Pprof, Speedscope and Folded write it for `go tool pprof`, speedscope.app (and an embedded speedscope view) and flamegraph.pl respectively.

Index

Constants

View Source
const RangeSQL = `` /* 605-byte string literal not displayed */

RangeSQL is the aggregated-flamegraph statement: stacks of one service and sample type between {from} and {to}, from the per-minute table joined to the stack dictionary. Output columns: frames (root to leaf), unit, value.

View Source
const ServicesSQL = `` /* 212-byte string literal not displayed */

ServicesSQL lists the services that sent profiles in a range, for when the caller did not name one.

View Source
const SnapshotLookback = 24 * time.Hour

SnapshotLookback is how far before a range's end a snapshot read looks for the newest snapshot: the raw tier's retention, and the longest heap interval a workload may declare (forge.Profiling heap_interval, 1m-24h).

View Source
const SnapshotSQL = `` /* 1539-byte string literal not displayed */

SnapshotSQL reads a gauge sample type (IsSnapshot) as each instance's newest snapshot in the range, from the raw tier (one ProfileId per snapshot). An instance is keyed by its environment AND its instance id, so with no Env filter each environment keeps its own newest snapshot. Only instances that sent a snapshot in the range are read; an instance whose newest snapshot predates {from} is not mixed in beside current ones. Only when the range holds no snapshot at all is the window moved back to end at the newest snapshot of the last SnapshotLookback ({since}), so a 1h window against a 2h cadence still answers with the heap as last measured. Output columns match RangeSQL.

View Source
const TraceSQL = `` /* 373-byte string literal not displayed */

TraceSQL reads the raw tier for the samples linked to a trace (and optionally a span). Output columns match RangeSQL.

Variables

This section is empty.

Functions

func IsSnapshot added in v1.1.0

func IsSnapshot(sampleType string) bool

IsSnapshot reports whether a sample type is a point-in-time GAUGE (the live heap, the goroutines), as opposed to a quantity accumulated over time (CPU time, contentions). A gauge is read as each instance's newest snapshot (SnapshotSQL), never summed over a range: two snapshots of one heap are the same bytes counted twice, and a range that holds no snapshot (the default hour, against the default 2h heap cadence) would hold no heap at all.

Types

type Profile

type Profile struct {
	Service    string
	SampleType string // cpu, alloc_space, inuse_space, goroutine, ...
	Unit       string // nanoseconds, bytes, count
	From, To   time.Time
	Stacks     []Stack
}

Profile is an aggregated profile: the stacks of one service and sample type over a time range, or of one trace.

func Parse

func Parse(r io.Reader, q Query) (Profile, error)

Parse reads the JSONEachRow output of RangeSQL or TraceSQL.

func (Profile) Folded

func (p Profile) Folded(w io.Writer) error

Folded writes the collapsed-stack format: "root;child;leaf value" per line. flamegraph.pl, speedscope and d3-flamegraph all read it.

func (Profile) Pprof

func (p Profile) Pprof(w io.Writer) error

Pprof writes a gzip-compressed pprof profile that `go tool pprof` opens. Only function names survive the trip through ClickHouse's stack dictionary, so there are no line numbers or addresses; -top, -tree, -peek and -http flamegraphs all work.

func (Profile) Speedscope

func (p Profile) Speedscope(w io.Writer) error

Speedscope writes speedscope's file format (a single "sampled" profile), the shape an embedded speedscope view loads directly.

func (Profile) Total

func (p Profile) Total() int64

Total is the sum of every stack's value.

type Query

type Query struct {
	Service    string
	SampleType string
	// Env filters on deployment.environment.name when non-empty (range queries only).
	Env      string
	From, To time.Time
	// TraceID, when set, reads the RAW tier for that trace instead of the
	// per-minute aggregate: the samples whose goroutine was serving the trace's
	// spans. Raw rows live 24h; the aggregate 30d.
	TraceID string
	// SpanID narrows a trace query to one span.
	SpanID string
}

Query selects what to read. SQL turns it into a statement with named parameters; callers pass Params to the client, never string-concatenate.

func (Query) SQL

func (q Query) SQL() (string, map[string]string)

SQL returns the statement for q and the parameter values it binds: the trace's samples, a gauge's newest snapshot (IsSnapshot), or a range's sum.

type Stack

type Stack struct {
	Frames []string
	Value  int64
}

Stack is one distinct call stack and the value it accumulated in the queried range. Frames run ROOT to LEAF, the order flamegraph tools expect.

Jump to

Keyboard shortcuts

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