Documentation
¶
Index ¶
- Variables
- func CollectHWSpecs() []collector.Metric
- func FilterStatic(metrics []collector.Metric) []collector.Metric
- func WriteAtomic(path string, s *Snapshot) error
- func WriteJSONAtomic(path string, v any) error
- type CollectorInfo
- type CompSnapshot
- type GlobalSnapshot
- type GlobalWriter
- type History
- type MetricSource
- type PerCompWriter
- type Snapshot
Constants ¶
This section is empty.
Variables ¶
var StaticMetricNames = map[string]bool{ "model_info": true, "numa_node_num": true, "core_num": true, "numa_core_num": true, "cpu_num": true, "min_freq": true, "max_freq": true, "l1d_cache_size": true, "l1i_cache_size": true, "l2_cache_size": true, "l3_cache_size": true, "module_info": true, "module_size": true, "module_num": true, }
StaticMetricNames is the set of metric names the collectors emit once at startup then suppress via flags (see cpu/memory collectors). FilterStatic extracts these so they can be stashed for the Specs snapshot field. The cross-component identity metrics (device_model/gpu_info/npu_info/disk_info/ net_info) are NOT here — they are collected once by hwinfo.go at startup, not via the periodic collectors.
var TrackedSeries = []seriesSpec{ {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, {/* contains filtered or unexported fields */}, }
TrackedSeries is the single place to extend which metrics get trend history.
Functions ¶
func CollectHWSpecs ¶
CollectHWSpecs gathers one-shot hardware identity specs (server model, GPU, NPU, disk, NIC) ONCE at web startup. It is deliberately NOT a registered periodic collector: these values are static identity, not time-series, so running them every collection cycle (and relying on a stash to keep them alive) was a layering mistake. The result is stored on the DataCollector and surfaced in every snapshot's Specs field.
cpu/memory statics (model_info, module_info, ...) are still emitted by their existing periodic collectors and stashed separately — only the cross-component identity specs that nothing else emits live here.
func FilterStatic ¶
FilterStatic returns the subset of metrics whose names are in StaticMetricNames. These are the one-shot device specs that must be stashed.
func WriteAtomic ¶
WriteAtomic writes the snapshot to disk atomically: write to a temp file in the same directory, then rename. Readers never see a half-written file.
func WriteJSONAtomic ¶
WriteJSONAtomic marshals v to JSON and writes it to disk atomically: write to a temp file in the same directory, then rename. Readers never see a half-written file. Used by both the per-component and global snapshot writers.
Types ¶
type CollectorInfo ¶
type CollectorInfo struct {
Name string `json:"name"`
Component string `json:"component"`
Priority string `json:"priority"`
Interval string `json:"interval"`
Enabled bool `json:"enabled"`
}
CollectorInfo is a registered collector's metadata, written into the global snapshot so the web frontend can build its nav without importing collectors.
type CompSnapshot ¶
type CompSnapshot struct {
Component string `json:"component"`
Timestamp time.Time `json:"timestamp"`
Metrics []collector.Metric `json:"metrics"`
History map[string][]float64 `json:"history"`
Specs []collector.Metric `json:"specs,omitempty"`
}
CompSnapshot is the per-component view written to <dir>/snapshot_<component>.json right after each collector's collection cycle. It carries only that component's latest metrics, that component's history ring, and that component's specs (stashed cpu/memory statics + startup hardware identity like gpu_info/npu_info/disk_info/net_info). Health and cross-component data live in the global snapshot.
func ReadComp ¶
func ReadComp(path string) (*CompSnapshot, error)
ReadComp loads a per-component snapshot (metrics/history/specs) written by the daemon's PerCompWriter.
type GlobalSnapshot ¶
type GlobalSnapshot struct {
SessionID string `json:"session_id"`
Timestamp time.Time `json:"timestamp"`
RefreshInterval int `json:"refresh_interval_ms"`
Intervals map[string]int `json:"intervals_ms,omitempty"`
Health health.HealthScore `json:"health"`
Collectors []CollectorInfo `json:"collectors"`
SystemSpecs []collector.Metric `json:"system_specs,omitempty"`
}
GlobalSnapshot is the cross-component view written to <dir>/snapshot.json at the global cadence (C_global). It carries health (overall + per-component subscores, evaluated on the full union so auto scheme detection is correct), the per-component collection intervals, collector metadata, and the cross-component system specs (device_model / os_info). Per-component metrics + history live in the per-component files, NOT here.
func ReadGlobal ¶
func ReadGlobal(path string) (*GlobalSnapshot, error)
ReadGlobal loads the global snapshot (health/collectors/intervals/system specs) written by the daemon's GlobalWriter.
type GlobalWriter ¶
type GlobalWriter struct {
// contains filtered or unexported fields
}
GlobalWriter periodically reads a MetricSource, evaluates health on the full union, and atomically writes the global snapshot. It is the only writer of <dir>/snapshot.json. Health, collectors, intervals and system specs are set by the daemon (startup hardware specs, registry metadata, derived cadence).
func NewGlobalWriter ¶
func NewGlobalWriter(source MetricSource, dir string, interval time.Duration, logger *slog.Logger) *GlobalWriter
NewGlobalWriter creates a GlobalWriter that writes <dir>/snapshot.json at the given global cadence. interval <= 0 defaults to 5s.
func (*GlobalWriter) Run ¶
func (w *GlobalWriter) Run(ctx context.Context)
Run blocks until ctx is canceled, writing a global snapshot immediately and then on every interval tick.
func (*GlobalWriter) SetCollectors ¶
func (w *GlobalWriter) SetCollectors(c []CollectorInfo)
SetCollectors sets the collector metadata written into every global snapshot.
func (*GlobalWriter) SetIntervals ¶
func (w *GlobalWriter) SetIntervals(m map[string]int)
SetIntervals sets the per-component collection cadence (ms) written into the global snapshot so consumers can align their polling.
func (*GlobalWriter) SetSystemSpecs ¶
func (w *GlobalWriter) SetSystemSpecs(s []collector.Metric)
SetSystemSpecs sets the cross-component static identity specs (device_model / os_info) collected once at daemon startup.
type History ¶
type History struct {
// contains filtered or unexported fields
}
History is the per-component trend ring buffer: one point per tracked series (max across devices where configured) into a ring, returned as a copy.
func NewHistory ¶
NewHistory creates a History with the given ring capacity (defaults to 60 when <= 0).
type MetricSource ¶
MetricSource is the read-only union cache the global writer snapshots. It is implemented by exporter.CachingStorage (AllMetrics/Ready).
type PerCompWriter ¶
type PerCompWriter struct {
// contains filtered or unexported fields
}
PerCompWriter is a collector.Storage decorator: it delegates each per-batch Write to the inner storage (JSONL / cache / faultsub / stragglerout) and then atomically writes a per-component snapshot file for that batch's component. Collection cadence == per-component snapshot refresh cadence (the file is written right after each collect). One instance handles all components, keeping independent per-component history rings + spec stashes.
func NewPerCompWriter ¶
func NewPerCompWriter(inner collector.Storage, dir string, historyCap int, logger *slog.Logger) *PerCompWriter
NewPerCompWriter wraps inner so every per-collector batch also produces a snapshot_<comp>.json file in dir. historyCap sets the ring depth (0 => 60).
func (*PerCompWriter) SetCompSpecs ¶
func (w *PerCompWriter) SetCompSpecs(comp string, specs []collector.Metric)
SetCompSpecs pre-loads a component's startup hardware-identity specs (gpu_info -> gpu, npu_info -> npu, disk_info -> disk, net_info -> network). Called by the daemon once at startup after CollectHWSpecs.
type Snapshot ¶
type Snapshot struct {
SessionID string `json:"session_id"`
Timestamp time.Time `json:"timestamp"`
RefreshInterval int `json:"refresh_interval_ms"`
HistoryPoints int `json:"history_points"`
Health health.HealthScore `json:"health"`
Metrics []collector.Metric `json:"metrics"`
History map[string][]float64 `json:"history"`
// Specs holds stashed static device specs (CPU model, frequency, cache,
// topology, memory modules). Collectors emit these once at startup then
// suppress them via flags; without this stash the snapshot would lose all
// device specs after the first cycle. Populated by collectOnce from the
// first cycle that yields any static metric, then re-injected every cycle.
Specs []collector.Metric `json:"specs,omitempty"`
}
Snapshot is the single cached view written by the collector goroutine and read by the HTTP layer. It is the decoupling boundary: the web side never calls collectors directly, it only reads this file.