A3S Docs
A3S Lane

Observability

Metrics collection, latency histograms, and configurable alerts

Observability

A3S Lane provides built-in metrics collection and alerting for production monitoring. Track command throughput, latency percentiles, queue depth, and set threshold-based alerts.

Metrics

Enable Metrics

use a3s_lane::QueueMetrics;

let manager = QueueManagerBuilder::new(emitter)
    .with_default_lanes()
    .with_metrics(QueueMetrics::local())
    .build()
    .await?;

QueueMetrics::local() uses an in-memory backend. For production, implement a custom MetricsBackend (e.g., Prometheus, Datadog).

Reading Metrics

let metrics = manager.metrics().unwrap();
let snapshot = metrics.snapshot().await;

// Counters
println!("Submitted: {:?}", snapshot.counters.get("lane.commands.submitted"));
println!("Completed: {:?}", snapshot.counters.get("lane.commands.completed"));
println!("Failed: {:?}", snapshot.counters.get("lane.commands.failed"));

// Gauges
println!("Queue depth: {:?}", snapshot.gauges.get("lane.queue.depth.query"));
println!("Active: {:?}", snapshot.gauges.get("lane.queue.active.query"));

// Histograms
if let Some(latency) = snapshot.histograms.get("lane.command.latency_ms.query") {
    println!("Latency p50: {}ms", latency.percentiles.p50);
    println!("Latency p95: {}ms", latency.percentiles.p95);
    println!("Latency p99: {}ms", latency.percentiles.p99);
}

Available Metrics

Counters (monotonically increasing):

Prop

Type

Gauges (point-in-time values):

Prop

Type

Histograms (distributions):

Prop

Type

Histogram Percentiles

pub struct HistogramStats {
    pub count: u64,
    pub sum: f64,
    pub min: f64,
    pub max: f64,
    pub mean: f64,
    pub percentiles: HistogramPercentiles,
}

pub struct HistogramPercentiles {
    pub p50: f64,
    pub p90: f64,
    pub p95: f64,
    pub p99: f64,
}

Custom Metrics Backend

Implement the MetricsBackend trait to push metrics to your monitoring system:

use a3s_lane::MetricsBackend;

#[async_trait]
impl MetricsBackend for PrometheusBackend {
    async fn increment_counter(&self, name: &str, value: u64) {
        // Push to Prometheus
    }
    async fn set_gauge(&self, name: &str, value: f64) { /* ... */ }
    async fn record_histogram(&self, name: &str, value: f64) { /* ... */ }
    async fn get_counter(&self, name: &str) -> Option<u64> { /* ... */ }
    async fn get_gauge(&self, name: &str) -> Option<f64> { /* ... */ }
    async fn get_histogram_stats(&self, name: &str) -> Option<HistogramStats> { /* ... */ }
    async fn reset(&self) { /* ... */ }
    async fn snapshot(&self) -> MetricsSnapshot { /* ... */ }
}

let metrics = QueueMetrics::new(Arc::new(PrometheusBackend::new()));

Alerts

Enable Alerts

use a3s_lane::AlertManager;

// Queue depth alerts
let alerts = Arc::new(AlertManager::with_queue_depth_alerts(100, 500));

// Latency alerts (in milliseconds)
let alerts = Arc::new(AlertManager::with_latency_alerts(500.0, 2000.0));

let manager = QueueManagerBuilder::new(emitter)
    .with_default_lanes()
    .with_alerts(alerts)
    .build()
    .await?;

Alert Levels

Prop

Type

Alert Callbacks

Register callbacks to handle alerts (send to Slack, PagerDuty, etc.):

let alerts = Arc::new(AlertManager::with_queue_depth_alerts(100, 500));

alerts.add_callback(|alert| {
    println!("[{:?}] Lane '{}': {}",
        alert.level, alert.lane_id, alert.message);
}).await;

Alert Fields

pub struct Alert {
    pub lane_id: String,
    pub level: AlertLevel,      // Warning | Critical
    pub message: String,
    pub timestamp: DateTime<Utc>,
}

Configure Thresholds at Runtime

use a3s_lane::{QueueDepthAlertConfig, LatencyAlertConfig};

let alerts = manager.alerts().unwrap();

alerts.set_queue_depth_config(QueueDepthAlertConfig {
    warning_threshold: 200,
    critical_threshold: 1000,
}).await;

alerts.set_latency_config(LatencyAlertConfig {
    warning_threshold: 1000.0,
    critical_threshold: 5000.0,
}).await;

Monitoring

For continuous health monitoring, use QueueMonitor:

use a3s_lane::{QueueMonitor, MonitorConfig};
use std::time::Duration;

let monitor = QueueMonitor::with_config(
    manager.queue(),
    MonitorConfig {
        interval: Duration::from_secs(5),
        pending_warning_threshold: 50,
        active_warning_threshold: 20,
    },
);

// Start background monitoring
monitor.start().await;

// Check stats on demand
let stats = monitor.stats().await;

On this page