Skip to main content

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;