footprint

package
v0.9.2 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: 17 Imported by: 0

Documentation

Overview

Package footprint bounds and measures the control plane's idle cost: a default memory limit, a registry of background loops, and process stats.

Index

Constants

View Source
const (
	EnvTolRSSPct     = "IDLE_TOL_RSS_PCT"
	EnvTolGoroutines = "IDLE_TOL_GOROUTINES"
	EnvTolFDs        = "IDLE_TOL_FDS"
	EnvTolCPUPoints  = "IDLE_TOL_CPU_POINTS"
	EnvCPUWindowSecs = "APP_FOOTPRINT_CPU_WINDOW_SECONDS"
)

Environment variables shared with scripts/idle-footprint, which has no defaults on purpose.

View Source
const (
	StatusWithin       = "within_tolerance"
	StatusOver         = "over_tolerance"
	StatusNoBaseline   = "no_baseline"
	StatusToleranceOff = "tolerance_unset"
)

Assessment statuses.

View Source
const (
	EnvMemLimit        = "GOMEMLIMIT"
	EnvMemLimitPercent = "APP_GOMEMLIMIT_PERCENT"
	DefaultPercent     = 80
)

Env vars read by ApplyMemoryLimit.

View Source
const (
	EnvGCPercent      = "APP_GC_PERCENT"
	EnvTrimInterval   = "APP_MEM_TRIM_INTERVAL"
	EnvTrimMinIdleMB  = "APP_MEM_TRIM_MIN_IDLE_MB"
	EnvTrimBootDelay  = "APP_MEM_TRIM_BOOT_DELAY"
	DefaultTrimBoot   = 12 * time.Second
	DefaultGCPercent  = 50
	DefaultTrimEvery  = 2 * time.Minute
	DefaultTrimIdleMB = 24
)

Env vars read by ApplyGCPercent and RunTrim.

Variables

This section is empty.

Functions

func ApplyGCPercent

func ApplyGCPercent(getenv func(string) string) int

ApplyGCPercent returns the percent it set, or 0 when GOGC already decides. It lowers the GC target below Go's 100 default unless GOGC or APP_GC_PERCENT is set; the live heap is small, so the extra GC cost is negligible.

func CPUWindowFromEnv

func CPUWindowFromEnv(get func(string) string) time.Duration

CPUWindowFromEnv returns the CPU averaging window, matching the baseline run's 60 seconds when unset.

func Every

func Every(ctx context.Context, name string, interval time.Duration, logger *slog.Logger, tick func(context.Context) error) error

Every runs tick on interval until ctx ends. The first tick is delayed by a random jitter of up to a tenth of the interval so loops do not wake together, and each tick is recorded.

func LimitFor

func LimitFor(total int64, percent int) int64

LimitFor returns percent of total bytes, or 0 when the result would be too small to be safe.

func Percent

func Percent(getenv func(string) string) int

Percent reads APP_GOMEMLIMIT_PERCENT; 0 disables the default limit.

func RunTrim

func RunTrim(ctx context.Context, logger *slog.Logger, getenv func(string) string)

RunTrim returns heap the runtime is holding but not using to the OS. Boot allocates transient hundreds of MB (catalog parse, password hashing) and the scavenger gives it back slowly, so RSS stays high for no reason.

func WindowCPU

func WindowCPU(window time.Duration, now time.Time, cpuSeconds float64) (percent, covered float64)

WindowCPU is the average CPU percent over the last window, or since process start until a full window exists. Each call adds a sample, so a polling caller keeps the window populated.

Types

type Assessment

type Assessment struct {
	Status    string        `json:"status"`
	Detail    string        `json:"detail,omitempty"`
	Platform  string        `json:"platform"`
	Current   Reading       `json:"current"`
	Baseline  *BaselineRow  `json:"baseline,omitempty"`
	Tolerance *Tolerance    `json:"tolerance,omitempty"`
	Checks    []MetricCheck `json:"checks"`
}

Assessment is the live footprint judged against the committed idle baseline.

func Assess

func Assess(cur Reading, rows []BaselineRow, goos, goarch string, tol Tolerance, tolErr error) Assessment

Assess compares a reading with the baseline row for this platform. The baseline records a peak RSS, so live RSS is held to the peak limit.

type BaselineRow

type BaselineRow struct {
	OS            string  `json:"os"`
	Arch          string  `json:"arch"`
	Apps          int     `json:"apps"`
	AppMode       string  `json:"app_mode"`
	WindowSeconds int     `json:"window_seconds"`
	RSSMB         float64 `json:"rss_mb"`
	PeakRSSMB     float64 `json:"peak_rss_mb"`
	CPUPercent    float64 `json:"cpu_percent"`
	Goroutines    int     `json:"goroutines"`
	OpenFDs       int     `json:"open_fds"`
	Threads       int     `json:"threads"`
	Loops         int     `json:"loops"`
}

BaselineRow is one committed idle measurement from scripts/idle-footprint-baseline.json.

func Baseline

func Baseline() []BaselineRow

Baseline returns the committed idle measurements compiled into the binary.

func SelectBaseline

func SelectBaseline(rows []BaselineRow, goos, goarch string, apps int) (BaselineRow, bool)

SelectBaseline picks the stopped-app row for this platform closest to the live app count.

type Loop

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

Loop records the runs of one background loop.

func Track

func Track(name string, interval time.Duration) *Loop

Track returns the registry entry for name, creating it on first use.

func (*Loop) Active

func (l *Loop) Active() func()

Active marks the loop running and returns the func that marks it stopped.

func (*Loop) Observe

func (l *Loop) Observe(start time.Time, err error)

Observe records one finished run that began at start.

type LoopInfo

type LoopInfo struct {
	Name         string    `json:"name"`
	IntervalSecs float64   `json:"interval_seconds"`
	Runs         int64     `json:"runs"`
	Errors       int64     `json:"errors"`
	LastRunAt    time.Time `json:"last_run_at"`
	LastDuration float64   `json:"last_duration_ms"`
	BusyMS       float64   `json:"busy_ms_total"`
	CostPercent  float64   `json:"cost_percent"`
	Running      bool      `json:"running"`
	LastError    string    `json:"last_error,omitempty"`
	// contains filtered or unexported fields
}

LoopInfo is the observable state of one background loop.

func Loops

func Loops() []LoopInfo

Loops returns every registered loop, busiest first.

type MemoryLimit

type MemoryLimit struct {
	LimitBytes int64  `json:"limit_bytes"`
	Source     string `json:"source"`
	Percent    int    `json:"percent"`
}

MemoryLimit describes what ApplyMemoryLimit decided.

func ApplyMemoryLimit

func ApplyMemoryLimit(getenv func(string) string, logger *slog.Logger) MemoryLimit

ApplyMemoryLimit sets a soft Go memory limit from the container or host memory unless GOMEMLIMIT is already set.

func CurrentMemoryLimit

func CurrentMemoryLimit() MemoryLimit

CurrentMemoryLimit returns what the last ApplyMemoryLimit call decided.

type MetricCheck

type MetricCheck struct {
	Name     string  `json:"name"`
	Unit     string  `json:"unit"`
	Current  float64 `json:"current"`
	Baseline float64 `json:"baseline"`
	Limit    float64 `json:"limit"`
	OK       bool    `json:"ok"`
}

MetricCheck is one live value next to its baseline and the limit the tolerance allows.

type Proc

type Proc struct {
	RSSBytes   uint64  `json:"rss_bytes"`
	HeapBytes  uint64  `json:"heap_bytes"`
	Goroutines int     `json:"goroutines"`
	Threads    int     `json:"threads"`
	OpenFDs    int     `json:"open_fds"`
	CPUSeconds float64 `json:"cpu_seconds"`
	CPUPercent float64 `json:"cpu_percent"`
}

Proc is a point in time reading of the process footprint.

func ReadProc

func ReadProc() Proc

ReadProc samples the process. CPUPercent is relative to the previous call (or process start for the first).

type Reading

type Reading struct {
	RSSBytes         uint64  `json:"rss_bytes"`
	CPUPercent       float64 `json:"cpu_percent"`
	CPUWindowSeconds float64 `json:"cpu_window_seconds"`
	Goroutines       int     `json:"goroutines"`
	OpenFDs          int     `json:"open_fds"`
	Threads          int     `json:"threads"`
	Apps             int     `json:"apps"`
}

Reading is the live control plane footprint compared against a baseline.

func Snapshot

func Snapshot(window time.Duration, apps int) Reading

Snapshot reads the process and its window CPU in one call.

type Tolerance

type Tolerance struct {
	RSSPercent float64 `json:"rss_percent"`
	Goroutines int     `json:"goroutines"`
	FDs        int     `json:"open_fds"`
	CPUPoints  float64 `json:"cpu_points"`
}

Tolerance is how far a reading may rise above its baseline row.

func ToleranceFromEnv

func ToleranceFromEnv(get func(string) string) (Tolerance, error)

ToleranceFromEnv fails when any variable is unset or invalid: a guard with silent limits is a guard nobody tuned.

Jump to

Keyboard shortcuts

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