Skip to main content

codetether_agent/telemetry/
globals.rs

1//! # Global telemetry singletons
2//!
3//! Process-wide counters that every part of the agent writes to. Isolated in
4//! their own file so the static definitions don't bloat any type module.
5//!
6//! ## Why globals?
7//!
8//! Telemetry must be cheap and lock-free at the call site — wrapping every
9//! provider/tool call in dependency-injected collectors was measured to add
10//! noticeable overhead in the hot path. The three singletons here use
11//! [`AtomicU64`](std::sync::atomic::AtomicU64) internally (for the counters)
12//! or a [`tokio::sync::Mutex`] guarded `Vec` (for provider history).
13//!
14//! ## Examples
15//!
16//! ```rust
17//! use codetether_agent::telemetry::{TOKEN_USAGE, TOOL_EXECUTIONS};
18//!
19//! TOKEN_USAGE.record(100, 50);
20//! TOOL_EXECUTIONS.record(true);
21//!
22//! let (prompt, completion, total) = TOKEN_USAGE.get();
23//! assert!(total >= prompt + completion);
24//! ```
25
26use once_cell::sync::Lazy;
27use std::sync::Arc;
28
29use super::provider::ProviderMetrics;
30use super::tokens::AtomicTokenCounter;
31use super::tools::AtomicToolCounter;
32
33/// Process-wide cumulative token usage across every provider request.
34pub static TOKEN_USAGE: Lazy<Arc<AtomicTokenCounter>> =
35    Lazy::new(|| Arc::new(AtomicTokenCounter::new()));
36
37/// Process-wide cumulative tool execution counter (success + failure).
38pub static TOOL_EXECUTIONS: Lazy<Arc<AtomicToolCounter>> =
39    Lazy::new(|| Arc::new(AtomicToolCounter::new()));
40
41/// Process-wide rolling buffer of the last N provider requests (N = 1000).
42///
43/// Used to derive averages, p50, and p95 latency / throughput per provider.
44pub static PROVIDER_METRICS: Lazy<Arc<ProviderMetrics>> =
45    Lazy::new(|| Arc::new(ProviderMetrics::new()));