microsandbox_metrics_collector/lib.rs
1//! Metrics collector orchestrator. Polls the microsandbox shared-memory
2//! metrics registry, buffers per-exporter, and fans batches out to
3//! registered exporters.
4//!
5//! See `docs/observability/msb-metrics.mdx` for the user-facing overview and
6//! the `msb-metrics` binary that ships in this crate's `bin/main.rs`.
7//!
8//! # Lifecycle
9//!
10//! Encoded in types — calling [`MetricsCollector::start`] consumes the
11//! collector and returns a [`RunningCollector`]; calling
12//! [`RunningCollector::shutdown`] consumes the handle. Both are compile-time
13//! errors to call twice.
14//!
15//! ```text
16//! [Builder] ─build()?─► [MetricsCollector] ─start().await?─► [RunningCollector]
17//! │
18//! flush() (fire-and-forget)
19//! shutdown(self).await
20//! ```
21//!
22//! # Architecture
23//!
24//! ```text
25//! handle.flush() / handle.shutdown(self).await
26//! │
27//! ▼ mpsc<CollectorCmd>
28//! ┌─ run loop ─────────────────────────────────────────────┐
29//! │ collect_ticker → collect_fn → broadcast::send(data) │
30//! │ cmd Flush → broadcast::send(()) (flush signal) │
31//! │ cmd Shutdown → drop senders → drain JoinSet │
32//! └────┬───────────────────────────────────────┬───────────┘
33//! │ │
34//! ▼ broadcast<Arc<MetricsCollection>> ▼ broadcast<()>
35//! (drop-oldest; lag = drop count) (cap 1)
36//! │ │
37//! ▼ ▼
38//! ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
39//! │ worker 1 │ │ worker 2 │…│ worker N │
40//! │ VecDeque │ │ VecDeque │ │ VecDeque │
41//! │ + flush │ │ + flush │ │ + flush │
42//! │ ticker │ │ ticker │ │ ticker │
43//! │ → export() │ │ → export() │ │ → export() │
44//! └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
45//! │ │ │
46//! └─── JoinSet (results aggregated by run loop) ──┘
47//! ```
48//!
49//! Two broadcast channels carry two different reliability contracts:
50//!
51//! - **Data** is intentionally **lossy**. When a worker can't keep up, the
52//! ring rotates and that worker sees `RecvError::Lagged(n)` — the count
53//! flows into its next [`MetricsExportBatch::dropped_collection_count`].
54//! - **Flush signal** is a single-slot broadcast — explicit
55//! [`RunningCollector::flush`] just bumps it; coalesced flushes are fine.
56//!
57//! Shutdown is structural: dropping the broadcast Senders signals every
58//! worker via `RecvError::Closed`. Each worker runs a final flush, calls
59//! `exporter.shutdown()`, and returns the result. The collector's run loop
60//! collects every result from its `JoinSet` and aggregates the first error.
61
62#![warn(missing_docs)]
63
64pub mod core;
65mod error;
66pub mod exporters;
67
68//--------------------------------------------------------------------------------------------------
69// Re-Exports
70//--------------------------------------------------------------------------------------------------
71
72pub use core::{
73 CatalogLabelSource, DEFAULT_COLLECT_INTERVAL, DEFAULT_EXPORT_TIMEOUT, DEFAULT_FLUSH_INTERVAL,
74 DEFAULT_MAX_BUFFERED_COLLECTIONS, LabelSource, MetricsCollection, MetricsCollector,
75 MetricsCollectorBuilder, MetricsErrorPolicy, MetricsExportBatch, MetricsExporter,
76 MetricsExporterConfig, RunningCollector, SandboxLabels, SandboxMetricSnapshot,
77};
78pub use error::{MetricsCollectorError, MetricsCollectorResult};
79pub use microsandbox_metrics::SandboxMetrics;