resourceadvisor

package
v0.8.5 Latest Latest
Warning

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

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

Documentation

Overview

Package resourceadvisor turns telemetry, limits and specs into read-only resource findings. It is pure: no I/O, no clock, never applies anything.

Index

Constants

View Source
const (
	UnitBytes    = "bytes"
	UnitNanoCPUs = "nano_cpus"
	UnitRequests = "requests"
)

Evidence units.

View Source
const EnvPrefix = "APP_RESOURCE_ADVISOR_"

EnvPrefix starts every threshold env var.

Variables

This section is empty.

Functions

func Sort

func Sort(fs []Finding)

Sort orders findings by severity, then estimated memory saving, then id.

Types

type Action

type Action struct {
	Type ActionType `json:"type"`
	// Value is bytes, nano-CPUs or idle minutes, by Type. Current is the
	// value it replaces, 0 when none is set.
	Value        int64             `json:"value,omitempty"`
	Current      int64             `json:"current,omitempty"`
	Settings     map[string]string `json:"settings,omitempty"`
	Instructions string            `json:"instructions,omitempty"`
}

Action is a concrete next step.

func (Action) Appliable

func (a Action) Appliable() bool

Appliable reports whether the advisor can apply this action itself.

type ActionType

type ActionType string

ActionType is what applying a finding would do.

const (
	ActionSetMemoryLimit ActionType = "set_memory_limit"
	ActionSetCPULimit    ActionType = "set_cpu_limit"
	ActionEnableSleep    ActionType = "enable_sleep"
	ActionPruneDocker    ActionType = "prune_docker"
	ActionManual         ActionType = "manual"
)

Action types. Only the first three can be applied through the advisor.

type Evidence

type Evidence struct {
	Window        string             `json:"window"`
	WindowSeconds int64              `json:"window_seconds"`
	Samples       int                `json:"samples"`
	Unit          string             `json:"unit,omitempty"`
	P50           float64            `json:"p50,omitempty"`
	P95           float64            `json:"p95,omitempty"`
	P99           float64            `json:"p99,omitempty"`
	Max           float64            `json:"max,omitempty"`
	Limit         float64            `json:"limit,omitempty"`
	Numbers       map[string]float64 `json:"numbers,omitempty"`
	Series        []Point            `json:"series,omitempty"`
}

Evidence is the data behind a finding.

type Finding

type Finding struct {
	ID       string            `json:"id"`
	Kind     Kind              `json:"kind"`
	Severity Severity          `json:"severity"`
	Resource Ref               `json:"resource"`
	Title    string            `json:"title"`
	Why      string            `json:"why"`
	Evidence Evidence          `json:"evidence"`
	Impact   Impact            `json:"impact"`
	Action   *Action           `json:"action,omitempty"`
	Params   map[string]string `json:"params,omitempty"`
}

Finding is one piece of advice.

func Analyze

func Analyze(in Input) []Finding

Analyze runs every rule. The same Input always yields the same findings, ordered by severity, then saving, then id.

type Impact

type Impact struct {
	SavingMemoryBytes int64      `json:"saving_memory_bytes,omitempty"`
	SavingNanoCPUs    int64      `json:"saving_nano_cpus,omitempty"`
	SavingDiskBytes   int64      `json:"saving_disk_bytes,omitempty"`
	ExhaustionAt      *time.Time `json:"exhaustion_at,omitempty"`
	Risk              string     `json:"risk,omitempty"`
}

Impact is the estimated saving or risk.

type Input

type Input struct {
	Now        time.Time
	Resources  []Resource
	Nodes      []Node
	Thresholds Thresholds
}

Input is everything Analyze reads.

type Kind

type Kind string

Kind names a rule.

const (
	KindMemoryLimitMissing    Kind = "memory_limit_missing"
	KindCPULimitMissing       Kind = "cpu_limit_missing"
	KindMemoryLimitTight      Kind = "memory_limit_tight"
	KindCPULimitTight         Kind = "cpu_limit_tight"
	KindMemoryOverProvisioned Kind = "memory_over_provisioned"
	KindCPUOverProvisioned    Kind = "cpu_over_provisioned"
	KindMemoryGrowth          Kind = "memory_growth"
	KindIdleApp               Kind = "idle_app"
	KindIdleDatabase          Kind = "idle_database"
	KindEngineTuning          Kind = "engine_tuning"
	KindConsolidate           Kind = "consolidate_databases"
	KindDiskForecast          Kind = "disk_forecast"
	KindReclaimableDisk       Kind = "reclaimable_disk"
	KindHostMemoryPressure    Kind = "host_memory_pressure"
	KindSwapInUse             Kind = "swap_in_use"
	KindTopConsumers          Kind = "top_consumers"
	KindCapacityUnknown       Kind = "capacity_unknown"
	KindNotEnoughData         Kind = "not_enough_data"
)

Finding kinds, one per rule.

type Node

type Node struct {
	ID   string
	Name string
	// MemoryTotal is 0 when the node does not report host memory.
	MemoryTotal     float64
	MemoryAvailable []Sample
	SwapUsed        []Sample
	DiskUsed        []Sample
	DiskTotal       float64
	Reclaimable     *Reclaimable
	// NoIdentity marks a single server without a node record.
	NoIdentity bool
}

Node is one machine.

type OOM

type OOM struct {
	At      time.Time
	Excerpt string
}

OOM is an observed OOM-kill signal.

type Point

type Point struct {
	T time.Time `json:"t"`
	V float64   `json:"v"`
}

Point is one downsampled evidence reading.

type Reclaimable

type Reclaimable struct {
	ImagesBytes     int64
	BuildCacheBytes int64
}

Reclaimable is Docker's own reclaimable disk accounting.

type Ref

type Ref struct {
	Kind ResourceKind `json:"kind"`
	Name string       `json:"name"`
}

Ref names one resource.

func ParseRef

func ParseRef(s string) (Ref, error)

ParseRef parses "app:web", "database:main" or "node:id".

func (Ref) String

func (r Ref) String() string

type Resource

type Resource struct {
	Ref     Ref
	NodeID  string
	Engine  string
	Version string
	Image   string
	// MemoryLimit and NanoCPUs are the configured limits, 0 when unset.
	MemoryLimit int64
	NanoCPUs    int64
	Memory      []Sample
	CPUPercent  []Sample
	Restarts    int
	OOM         *OOM
	// Requests are per-tick request counts; only non-zero ticks are stored,
	// so they mean anything only when ServesTraffic is true.
	Requests      []Sample
	ServesTraffic bool
	SleepEnabled  bool
	Suspended     bool
	// LinkedApps counts apps wired to a database, -1 when unknown.
	LinkedApps int
}

Resource is one app or database and everything known about it.

type ResourceKind

type ResourceKind string

ResourceKind is what a finding is about.

const (
	ResourceApp      ResourceKind = "app"
	ResourceDatabase ResourceKind = "database"
	ResourceNode     ResourceKind = "node"
)

Resource kinds.

type Sample

type Sample struct {
	At    time.Time
	Value float64
}

Sample is one telemetry reading.

type Severity

type Severity string

Severity ranks a finding.

const (
	SeverityInfo    Severity = "info"
	SeveritySuggest Severity = "suggest"
	SeverityWarn    Severity = "warn"
)

Severities, most urgent last.

func (Severity) Rank

func (s Severity) Rank() int

Rank orders severities, warn highest.

type Summary

type Summary struct {
	Total             int            `json:"total"`
	BySeverity        map[string]int `json:"by_severity"`
	ByKind            map[string]int `json:"by_kind"`
	Actionable        int            `json:"actionable"`
	PendingData       int            `json:"pending_data"`
	SavingMemoryBytes int64          `json:"saving_memory_bytes"`
	SavingDiskBytes   int64          `json:"saving_disk_bytes"`
	TopSavings        []Finding      `json:"top_savings"`
}

Summary counts findings for the dashboard tile and the attention feed.

func Summarize

func Summarize(fs []Finding, top int) Summary

Summarize builds a Summary; not-enough-data findings are counted apart.

type Thresholds

type Thresholds struct {
	Window             time.Duration
	MinData            time.Duration
	MemoryHeadroom     float64
	CPUHeadroom        float64
	TightRatio         float64
	OverProvisionRatio float64
	RestartsTight      int
	GrowthMinFraction  float64
	GrowthMinFit       float64
	IdleWindow         time.Duration
	IdleCPUPercent     float64
	SleepIdleMinutes   int64
	TuningMinMemory    int64
	SmallDatabaseBytes int64
	SmallDatabaseCount int
	HostPressure       float64
	SwapWarnBytes      int64
	TopConsumerShare   float64
	DiskHorizon        time.Duration
	ReclaimableMin     int64
	DatabaseCPUFloor   int64
	CacheTTL           time.Duration
}

Thresholds tune every rule. Each field has an APP_RESOURCE_ADVISOR_* env var.

func DefaultThresholds

func DefaultThresholds() Thresholds

DefaultThresholds are the documented defaults (docs/resource-advisor.md).

func ThresholdsFromEnv

func ThresholdsFromEnv(lookup func(string) (string, bool)) (Thresholds, []error)

ThresholdsFromEnv overlays env values on the defaults. A bad value keeps its default and is reported, so a typo never disables the advisor.

Jump to

Keyboard shortcuts

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