runtimebudget

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 8 Imported by: 0

README

runtimebudget

runtimebudget is a Go 1.23, standard-library-only package for reading and comparing runtime/metrics snapshots.

const name = "/gc/cycles/total:gc-cycles"

before := runtimebudget.Read(name)
// ... work ...
after := runtimebudget.Read(name)

delta, err := runtimebudget.Delta(before, after, name)
if err != nil {
	return err
}
count, ok := delta.Uint64()
_ = count
_ = ok

rate, err := runtimebudget.Rate(before, after, name)

Read() and ReadAll() read all metrics; passing names reads only those metrics. A name unknown to the current Go runtime is retained as KindBad. Snapshot.Get also distinguishes a missing name from a present KindBad value. Value.Uint64, Value.Float64, and Value.Histogram return (value, false) instead of panicking for the wrong kind.

Delta and Rate only accept cumulative scalar metrics, as declared by runtime/metrics.Description.Cumulative. A counter decrease is reported as ErrCounterReset. Histograms are never converted to a scalar: use HistogramDelta for per-bucket count differences. Divide those counts by current.At().Sub(previous.At()).Seconds() when a bucket rate is needed.

For non-cumulative scalar metrics, check maximum budgets:

snapshot := runtimebudget.Read("/sched/goroutines:goroutines")
report := runtimebudget.Check(snapshot, map[string]float64{
	"/sched/goroutines:goroutines": 1000,
})
if err := report.Err(); err != nil {
	// errors.Is(err, runtimebudget.ErrBudgetExceeded) identifies violations.
	// report.Violations contains their values and limits; report.Issues contains
	// unknown, missing, KindBad, histogram, and other unevaluable metrics.
	return err
}

Choose the metric and budget operation together. Limits in examples are illustrative, not recommended production thresholds:

Metric Operation Budget unit
/sched/goroutines:goroutines Check current goroutine count
/gc/heap/allocs:bytes CheckDelta bytes allocated between snapshots
/gc/heap/allocs:bytes CheckRate allocated bytes per second of the actual snapshot interval

/gc/heap/goal:bytes is the GC heap target, not process RSS. /cpu/classes/total:cpu-seconds measures available Go CPU time (including idle capacity), not actual process CPU usage. Consult the runtime description before interpreting a metric as a resource budget.

Check rejects cumulative metrics with ErrCumulativeMetric and directs callers to CheckDelta/CheckRate for scalars or HistogramDelta for histograms. This corrects its former, misleading ErrNotCumulative classification. Delta, Rate, CheckDelta, and CheckRate still use ErrNotCumulative when given a non-cumulative metric.

For cumulative budgets, compare two snapshots directly or per second:

report := runtimebudget.CheckDelta(before, after, map[string]float64{
	"/gc/cycles/total:gc-cycles": 100,
})
// CheckRate(before, after, budgets) uses the same budgets as values/second.
if err := report.Err(); err != nil {
	return err
}

To keep checking a cumulative budget without managing snapshots yourself:

err := runtimebudget.WatchRate(ctx, time.Second, map[string]float64{
	"/gc/cycles/total:gc-cycles": 100,
}, func(report runtimebudget.Report) {
		if err := report.Err(); err != nil {
			// Handle a violation or an unevaluable metric.
		}
})
// err is ctx.Err() after cancellation.

WatchRate takes a baseline immediately; the first report follows the next sample. Its callback runs synchronously; pass a non-nil context, callback, and positive interval. A slow callback delays sampling and may cause ticker events to be dropped. Rates divide by the actual time between snapshots, not the requested interval. Cancellation cannot interrupt the callback: it must return before WatchRate exits.

The runtime metrics API is implementation-defined and evolves with Go. This package consults runtime/metrics.All() at runtime rather than maintaining its own metric list.

API reference: runtime/metrics package, Go source.

Documentation

Overview

Package runtimebudget reads runtime/metrics snapshots and compares them.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnknownMetric means the metric name is not in runtime/metrics.All.
	ErrUnknownMetric = errors.New("runtimebudget: unknown metric")
	// ErrMetricMissing means a snapshot does not contain the requested metric.
	ErrMetricMissing = errors.New("runtimebudget: metric missing from snapshot")
	// ErrMetricUnavailable means runtime/metrics returned KindBad.
	ErrMetricUnavailable = errors.New("runtimebudget: metric unavailable")
	// ErrKindMismatch means a value's kind differs from its runtime description.
	ErrKindMismatch = errors.New("runtimebudget: metric kind mismatch")
	// ErrUnsupportedKind means a newer or otherwise unsupported metric kind was seen.
	ErrUnsupportedKind = errors.New("runtimebudget: unsupported metric kind")
	// ErrNotCumulative means an operation requiring a cumulative metric was requested.
	ErrNotCumulative = errors.New("runtimebudget: metric is not cumulative")
	// ErrCumulativeMetric means Check received a cumulative metric.
	ErrCumulativeMetric = errors.New("runtimebudget: metric is cumulative; use CheckDelta or CheckRate for scalars, HistogramDelta for histograms")
	// ErrHistogramScalarDelta means a histogram was passed to scalar Delta or Rate.
	ErrHistogramScalarDelta = errors.New("runtimebudget: histogram needs bucket handling")
	// ErrHistogramRequired means HistogramDelta was passed a non-histogram metric.
	ErrHistogramRequired = errors.New("runtimebudget: metric is not a histogram")
	// ErrHistogramLayout means two histogram snapshots have different bucket boundaries.
	ErrHistogramLayout = errors.New("runtimebudget: histogram bucket layout mismatch")
	// ErrCounterReset means a cumulative value decreased between snapshots.
	ErrCounterReset = errors.New("runtimebudget: cumulative metric decreased")
	// ErrInvalidInterval means the current snapshot is not after the previous one.
	ErrInvalidInterval = errors.New("runtimebudget: snapshot interval must be positive")
	// ErrInvalidBudget means a budget limit is NaN or infinite.
	ErrInvalidBudget = errors.New("runtimebudget: budget limit must be finite")
	// ErrHistogramBudget means a histogram cannot be checked as one scalar value.
	ErrHistogramBudget = errors.New("runtimebudget: histogram budget needs bucket handling")
	// ErrBudgetExceeded means at least one budget was exceeded.
	ErrBudgetExceeded = errors.New("runtimebudget: budget exceeded")
	// ErrNilContext means WatchRate received a nil context.
	ErrNilContext = errors.New("runtimebudget: nil context")
	// ErrNilCallback means WatchRate received a nil report callback.
	ErrNilCallback = errors.New("runtimebudget: nil callback")
	// ErrInvalidWatchInterval means WatchRate received a non-positive interval.
	ErrInvalidWatchInterval = errors.New("runtimebudget: watch interval must be positive")
)

Functions

func Rate

func Rate(previous, current Snapshot, name string) (float64, error)

Rate returns the scalar cumulative increase per second, using the timestamps captured in the two snapshots. Histograms are intentionally rejected.

func WatchRate added in v0.3.0

func WatchRate(ctx context.Context, interval time.Duration, budgets map[string]float64, onReport func(Report)) error

WatchRate samples selected cumulative metrics immediately and then at each interval, reporting the rate between consecutive samples. It blocks until ctx is canceled and then returns ctx.Err(). Reports are delivered synchronously in the caller's goroutine. Slow callbacks delay sampling and may cause ticker events to be dropped. Rates use actual snapshot timestamps, not the requested interval. Cancellation does not interrupt a callback; it must return before WatchRate can exit.

Types

type Histogram

type Histogram struct {
	Counts  []uint64
	Buckets []float64
}

Histogram is an explicit bucketed metric value. Counts[i] covers [Buckets[i], Buckets[i+1]).

func HistogramDelta

func HistogramDelta(previous, current Snapshot, name string) (Histogram, error)

HistogramDelta returns per-bucket increases for a cumulative histogram. Buckets are copied from the current snapshot.

type Issue

type Issue struct {
	Name string
	Err  error
}

Issue describes a budget that could not be evaluated.

func (Issue) Error

func (i Issue) Error() string

type Report

type Report struct {
	Violations []Violation
	Issues     []Issue
}

Report contains budget violations and metrics that could not be checked.

func Check

func Check(snapshot Snapshot, budgets map[string]float64) Report

Check evaluates maximum numeric budgets for non-cumulative scalar metrics. The returned report is deterministic by metric name. Use report.Err() when the caller wants violations and evaluation issues as an error. Cumulative metrics produce ErrCumulativeMetric; use CheckDelta or CheckRate for scalars and HistogramDelta for histograms.

func CheckDelta added in v0.2.0

func CheckDelta(previous, current Snapshot, budgets map[string]float64) Report

CheckDelta evaluates maximum budgets against cumulative metric increases. The returned report is deterministic by metric name.

func CheckRate added in v0.2.0

func CheckRate(previous, current Snapshot, budgets map[string]float64) Report

CheckRate evaluates maximum budgets against cumulative metric increases per second. The returned report is deterministic by metric name.

func (Report) Err

func (r Report) Err() error

Err converts a non-OK report into a clear, inspectable error.

func (Report) OK

func (r Report) OK() bool

OK reports whether every budget was evaluated and satisfied.

type ReportError

type ReportError struct {
	Report Report
}

ReportError is returned by Report.Err when a check has violations or issues.

func (*ReportError) Error

func (e *ReportError) Error() string

func (*ReportError) Unwrap

func (e *ReportError) Unwrap() []error

Unwrap makes errors.Is useful for both violations and evaluation issues.

type Snapshot

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

Snapshot is an immutable copy of selected runtime metrics at one point in time. The snapshot's histogram slices are copied, so a later runtime/metrics.Read does not change this snapshot.

func Read

func Read(names ...string) Snapshot

Read reads the named metrics. With no names, it reads every metric currently returned by runtime/metrics.All. Unknown names are retained with KindBad.

func ReadAll

func ReadAll() Snapshot

ReadAll reads every metric currently returned by runtime/metrics.All.

func (Snapshot) At

func (s Snapshot) At() time.Time

At reports when the snapshot was captured.

func (Snapshot) Get

func (s Snapshot) Get(name string) (Value, bool)

Get returns a metric value and whether the snapshot contains that name. A present but unsupported or unknown runtime metric has KindBad and still returns true.

func (Snapshot) Names

func (s Snapshot) Names() []string

Names returns the metric names in the snapshot in sorted order.

type Value

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

Value is a kind-tagged runtime metric value.

func Delta

func Delta(previous, current Snapshot, name string) (Value, error)

Delta returns the scalar increase of a cumulative metric. Histograms are intentionally rejected; use HistogramDelta for their bucket counts.

func (Value) Float64

func (v Value) Float64() (float64, bool)

Float64 returns the value when its kind is KindFloat64.

func (Value) Histogram

func (v Value) Histogram() (Histogram, bool)

Histogram returns a copy when its kind is KindFloat64Histogram.

func (Value) Kind

func (v Value) Kind() metrics.ValueKind

Kind reports the runtime/metrics kind of the value.

func (Value) Uint64

func (v Value) Uint64() (uint64, bool)

Uint64 returns the value when its kind is KindUint64.

type Violation

type Violation struct {
	Name  string
	Value float64
	Limit float64
	Kind  metrics.ValueKind
}

Violation describes one numeric value above its configured maximum.

func (Violation) Error

func (v Violation) Error() string

Jump to

Keyboard shortcuts

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