Expand description
Lock-free event-based analytics for Iron Runtime LLM proxy.
Provides real-time usage tracking, cost analytics, and operational metrics for the Iron Runtime dashboard. Uses atomic operations for lock-free event recording and aggregation.
§Purpose
This crate handles all analytics operations for Iron Runtime:
- Real-time event capture (LLM requests, failures, system events)
- Lock-free statistical aggregation (per-model, per-provider)
- Event storage with deduplication
- Dashboard sync for real-time visualization
- Cost tracking and budget threshold alerts
§Architecture
Analytics follows an event-driven, lock-free design:
- Event Recording: Capture typed events with automatic metadata (timestamp, IDs)
- Storage: Append-only event store with atomic operations
- Aggregation: Compute statistics on-demand from event stream
- Sync: Background thread sends events to dashboard (optional)
All operations use atomic primitives to avoid locks in the critical path of LLM request handling.
§Key Types
AnalyticsEvent- Typed event with metadata (timestamp, event_id, agent_id)EventPayload- Event variants (LlmRequestCompleted, LlmRequestFailed, etc.)EventStore- Lock-free append-only event storage with deduplicationComputedStats- Aggregated statistics snapshot (totals, by-model, by-provider)ModelStats- Per-model usage statistics (requests, tokens, cost)- [
SyncClient] - Background sync to dashboard (feature: sync)
§Public API
§Record Events
ⓘ
use iron_runtime_analytics::{ EventStore, EventPayload, LlmUsageData, LlmModelMeta };
use std::sync::Arc;
let store = EventStore::new();
// Record successful LLM request
let meta = LlmModelMeta {
provider_id: Some(Arc::from("openai")),
provider: Arc::from("openai"),
model: Arc::from("gpt-4"),
};
let usage = LlmUsageData {
meta,
input_tokens: 1000,
output_tokens: 500,
cost_micros: 15_000_000, // $0.015
};
store.record_event(EventPayload::LlmRequestCompleted(usage));§Compute Statistics
ⓘ
use iron_runtime_analytics::EventStore;
let store = EventStore::new();
// ... record events ...
let stats = store.compute_stats();
println!("Total requests: {}", stats.total_requests);
println!("Success rate: {:.1}%", stats.success_rate());
println!("Total cost: ${:.4}", stats.total_cost_usd());
println!("Avg cost/request: ${:.6}", stats.avg_cost_per_request_usd());
// Per-model breakdown
for (model, stats) in &stats.by_model {
println!("{}: {} requests, ${:.4}", model, stats.request_count, stats.cost_usd());
}§Dashboard Sync
ⓘ
use iron_runtime_analytics::{ SyncClient, SyncConfig };
let config = SyncConfig {
dashboard_url: "http://localhost:8080".to_string(),
sync_interval_ms: 5000,
};
let sync_handle = SyncClient::start(config)?;
// Client runs in background, syncing events every 5 seconds
// Stop when done:
sync_handle.stop();§Feature Flags
enabled- Enable analytics collection (disabled for minimal builds)sync- Enable background dashboard sync (requiresenabled)
§Performance
Event recording is lock-free and allocation-minimal:
- Event append: Single atomic operation
- Deduplication: Lock-free concurrent hash map
- Statistics: Computed on-demand from event stream
Typical overhead: <1μs per event in hot path.
Re-exports§
pub use event::AnalyticsEvent;pub use event::EventId;pub use event::EventPayload;pub use event::LlmModelMeta;pub use event::LlmUsageData;pub use event::LlmFailureData;pub use event_storage::EventStore;pub use stats::ComputedStats;pub use stats::ModelStats;pub use provider_utils::Provider;pub use provider_utils::infer_provider;pub use provider_utils::current_time_ms;
Modules§
- event
- Analytics event types and payloads.
- event_
storage - Lock-free event storage with atomic counters.
- provider_
utils - Utility functions and types for analytics.
- recording
- High-level recording API for EventStore.
- stats
- Statistics types for analytics aggregation.