nmbrs_metrics/lib.rs
1// Copyright 2024-2026 Jonathan Shook
2// SPDX-License-Identifier: Apache-2.0
3
4//! # nmbrs-metrics
5//!
6//! Contract & axioms: [SRD 39](../../docs/SRD/39_metrics_contract.md).
7//!
8//! Metrics collection and reporting for nmbrs. The design centers
9//! on a **component tree** — a hierarchical, label-keyed structure
10//! where every node owns its own instruments, controls, and child
11//! components. Workload state, phase progress, latency histograms,
12//! and dynamic-control values are all reified as components and
13//! their attached instruments, queryable via [`selector::Selector`]
14//! or directly via parent / child traversal.
15//!
16//! ## Pieces
17//!
18//! - **Components** ([`component::Component`]) hold dimensional
19//! labels (`session=…`, `phase=…`, `activity=…`), per-component
20//! props, an instrument set, and a control registry. Each
21//! component's effective labels are the union of its own labels
22//! and its parent chain.
23//! - **Instruments** ([`instruments`]) are counters, gauges,
24//! histograms, timers — owned by a component and accessed by
25//! name. Histograms are HDR-backed; reads return delta windows
26//! so downstream reporters get *what changed since last read*,
27//! not cumulative state.
28//! - **Snapshots** ([`snapshot::MetricSet`]) are OpenMetrics-shaped
29//! captures of one moment in time across the tree. The
30//! [`cadence_reporter::CadenceReporter`] coalesces snapshots
31//! into declared windows (1s, 10s, 30s, 1m, 5m, …) and fans
32//! them out to async subscribers (SQLite, VictoriaMetrics push,
33//! TUI).
34//! - **Controls** ([`controls`]) live next to instruments — same
35//! tree, same label addressing — but carry mutable typed values
36//! that Polydat Kernels read at cycle time and the runtime applies
37//! via `ControlApplier`s. See SRD 23 for the full surface.
38//! - **MetricsQuery** ([`metrics_query::MetricsQuery`]) is the
39//! read-side handle that consumers (TUI, web, summary reports)
40//! use to pull cadence-window snapshots without touching the
41//! shared store directly.
42//!
43//! ## Quick tour
44//!
45//! Build a root component, then walk it:
46//!
47//! ```
48//! use std::collections::HashMap;
49//! use nmbrs_metrics::component::{self, Component};
50//! use nmbrs_metrics::labels::Labels;
51//! use nmbrs_metrics::selector::Selector;
52//!
53//! let root = Component::root(
54//! Labels::of("session", "demo"),
55//! HashMap::new(),
56//! );
57//!
58//! // Effective labels include the chain back to the root.
59//! let guard = root.read().unwrap();
60//! assert_eq!(guard.effective_labels().get("session"), Some("demo"));
61//! drop(guard);
62//!
63//! // Empty selector matches the root only on a fresh tree.
64//! let hits = component::find(&root, &Selector::new());
65//! assert_eq!(hits.len(), 1);
66//! ```
67//!
68//! ## Design briefs
69//!
70//! See the SRD for the full rationale:
71//!
72//! - SRD 19 — component tree
73//! - SRD 23 — dynamic controls
74//! - SRD 24 — selector lookup semantics
75//! - SRD 40 / 42 — metrics capture, cadence reporter,
76//! subscription dispatch
77
78pub mod cadence;
79pub mod cadence_reporter;
80pub mod cells;
81pub mod component;
82pub mod controls;
83pub mod diag;
84pub mod instruments;
85pub mod labels;
86pub mod metrics_query;
87pub mod reporters;
88pub mod scheduler;
89pub mod selector;
90pub mod snapshot;
91pub mod summaries;
92pub mod thread_pools;
93pub mod validation;
94// Polydat metric-reading nodes — registered into polydat's
95// node catalog via the `inventory` channel. Lives here (not in
96// polydat) so polydat stays free of a reverse dep and can publish
97// standalone. See `polydat_nodes::set_global_query` for the runner
98// hookup.
99pub mod polydat_nodes;
100// The metrics query API — the data-access *service* boundary (SRD-86
101// §"The metric-reader surface"): the `Vector`/`Series` result shapes,
102// the `MetricAccess` service trait, and runtime service location. The
103// MetricsQL engine locates a service here and layers aggregation over
104// it; nmbrs-metrics owns no query language, only the access surface.
105pub mod queryapi;