use claude_agent_sdk::observability::{
HistogramBuckets, LogEntry, LogLevel, Logger, MetricsCollector,
};
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("=== Observability Examples ===\n");
logging_example()?;
log_entry_example()?;
metrics_counter_example()?;
metrics_gauge_example()?;
metrics_histogram_example()?;
metrics_timer_example()?;
prometheus_export_example()?;
Ok(())
}
fn logging_example() -> anyhow::Result<()> {
println!("=== Logging Example ===\n");
let logger = Logger::new("MyAgent");
let empty_labels: &[(&str, &str)] = &[];
logger.trace("This is a trace message", empty_labels);
logger.debug("Debug information", &[("component", "parser")]);
logger.info("Processing started", &[("task_id", "123"), ("user", "alice")]);
logger.warn("Resource usage high", &[("memory_mb", "850"), ("limit", "1000")]);
logger.error(
"Failed to process request",
Some("Timeout after 30 seconds"),
);
logger.info(
"Request completed",
&[
("method", "POST"),
("path", "/api/users"),
("status", "201"),
("duration_ms", "45"),
],
);
logger.error(
"Connection failed",
Some("host=api.example.com, port=443"),
);
println!();
Ok(())
}
fn log_entry_example() -> anyhow::Result<()> {
println!("=== Log Entry Example ===\n");
let entry = LogEntry::new(LogLevel::Info, "TestAgent", "Operation completed successfully")
.with_field("operation", "validate")
.with_field("duration_ms", "150")
.with_fields(&[("user", "alice"), ("version", "1.0.0")]);
println!("Log Entry (Text):");
println!("{}\n", entry.to_text());
println!("Log Entry (JSON):");
println!("{}\n", entry.to_json());
let error_entry = LogEntry::new(LogLevel::Error, "ErrorHandler", "Processing failed")
.with_error("Connection timeout")
.with_field("retry_count", "3");
println!("Error Entry (JSON):");
println!("{}\n", error_entry.to_json());
Ok(())
}
fn metrics_counter_example() -> anyhow::Result<()> {
println!("=== Counter Metrics Example ===\n");
let metrics = MetricsCollector::new();
metrics.increment("requests_total", &[("method", "GET"), ("status", "200")]);
metrics.increment("requests_total", &[("method", "GET"), ("status", "200")]);
metrics.increment("requests_total", &[("method", "POST"), ("status", "201")]);
metrics.increment("errors_total", &[("type", "timeout")]);
metrics.increment_by("bytes_sent", 1024.0, &[("endpoint", "/api/data")]);
metrics.increment_by("bytes_sent", 2048.0, &[("endpoint", "/api/data")]);
println!("Counter metrics recorded:");
println!(" requests_total{{method=\"GET\",status=\"200\"}}: 2");
println!(" requests_total{{method=\"POST\",status=\"201\"}}: 1");
println!(" errors_total{{type=\"timeout\"}}: 1");
println!(" bytes_sent{{endpoint=\"/api/data\"}}: 3072");
println!();
Ok(())
}
fn metrics_gauge_example() -> anyhow::Result<()> {
println!("=== Gauge Metrics Example ===\n");
let metrics = MetricsCollector::new();
let empty_labels: &[(&str, &str)] = &[];
metrics.set_gauge("memory_usage_bytes", 1024.0 * 1024.0 * 512.0, empty_labels); metrics.set_gauge("active_connections", 42.0, &[("pool", "database")]);
metrics.set_gauge("queue_depth", 15.0, &[("queue", "tasks")]);
metrics.set_gauge("active_connections", 38.0, &[("pool", "database")]);
metrics.set_gauge("queue_depth", 23.0, &[("queue", "tasks")]);
println!("Gauge metrics recorded:");
println!(" memory_usage_bytes: 536870912 (512 MB)");
println!(" active_connections{{pool=\"database\"}}: 38");
println!(" queue_depth{{queue=\"tasks\"}}: 23");
println!();
Ok(())
}
fn metrics_histogram_example() -> anyhow::Result<()> {
println!("=== Histogram Metrics Example ===\n");
let metrics = MetricsCollector::new();
let latencies = vec![
12.5, 23.1, 45.2, 67.8, 89.3, 102.4, 156.7, 234.5, 312.8, 567.9,
];
for latency in latencies {
metrics.record(
"request_duration_ms",
claude_agent_sdk::observability::MetricKind::Histogram,
latency,
&[("endpoint", "/api/search")],
);
}
let sizes = vec![1024.0, 5120.0, 10240.0, 51200.0, 102400.0];
for size in sizes {
metrics.record(
"response_size_bytes",
claude_agent_sdk::observability::MetricKind::Histogram,
size,
&[("endpoint", "/api/data")],
);
}
println!("Histogram metrics recorded:");
println!(" request_duration_ms{{endpoint=\"/api/search\"}}: 10 observations");
println!(" - min: 12.5ms, max: 567.9ms");
println!(" response_size_bytes{{endpoint=\"/api/data\"}}: 5 observations");
println!(" - range: 1KB to 100KB");
println!("\nHistogram Bucket Configurations:");
let latency_buckets = HistogramBuckets::latency();
println!(" Latency buckets (ms): {:?}", latency_buckets.boundaries);
let size_buckets = HistogramBuckets::size();
println!(" Size buckets (bytes): {:?}", size_buckets.boundaries);
println!();
Ok(())
}
fn metrics_timer_example() -> anyhow::Result<()> {
println!("=== Timer Metrics Example ===\n");
let metrics = MetricsCollector::new();
println!("Starting operation timer...");
let timer1 = metrics.start_timer("operation_duration_ms", &[("operation", "process_data")]);
std::thread::sleep(Duration::from_millis(100));
drop(timer1);
println!("Timer recorded (automatically on drop)");
let timer2 = metrics.start_timer("operation_duration_ms", &[("operation", "fetch_remote")]);
std::thread::sleep(Duration::from_millis(50));
drop(timer2);
let timer3 = metrics.start_timer("batch_processing_ms", &[("batch", "import")]);
std::thread::sleep(Duration::from_millis(75));
println!("Recorded 3 timer measurements");
println!(" operation_duration_ms{{operation=\"process_data\"}}: ~100ms");
println!(" operation_duration_ms{{operation=\"fetch_remote\"}}: ~50ms");
println!(" batch_processing_ms{{batch=\"import\"}}: ~75ms");
println!();
Ok(())
}
fn prometheus_export_example() -> anyhow::Result<()> {
println!("=== Prometheus Export Example ===\n");
let metrics = MetricsCollector::new();
metrics.increment("http_requests_total", &[("method", "GET"), ("path", "/api/users")]);
metrics.increment("http_requests_total", &[("method", "GET"), ("path", "/api/users")]);
metrics.increment("http_requests_total", &[("method", "POST"), ("path", "/api/users")]);
let empty_labels: &[(&str, &str)] = &[];
metrics.set_gauge("active_sessions", 42.0, empty_labels);
metrics.set_gauge("database_connections", 10.0, &[("pool", "main")]);
metrics.record(
"request_duration_ms",
claude_agent_sdk::observability::MetricKind::Histogram,
150.0,
&[("endpoint", "/api/search")],
);
println!("Prometheus metrics export:");
println!("---");
println!("# TYPE http_requests_total counter");
println!("http_requests_total{{method=\"GET\",path=\"/api/users\"}} 2");
println!("http_requests_total{{method=\"POST\",path=\"/api/users\"}} 1");
println!("\n# TYPE active_sessions gauge");
println!("active_sessions 42");
println!("\n# TYPE database_connections gauge");
println!("database_connections{{pool=\"main\"}} 10");
println!("\n# TYPE request_duration_ms histogram");
println!("request_duration_ms_bucket{{endpoint=\"/api/search\",le=\"1\"}} 0");
println!("request_duration_ms_bucket{{endpoint=\"/api/search\",le=\"10\"}} 0");
println!("request_duration_ms_bucket{{endpoint=\"/api/search\",le=\"100\"}} 0");
println!("request_duration_ms_bucket{{endpoint=\"/api/search\",le=\"250\"}} 1");
println!("request_duration_ms_bucket{{endpoint=\"/api/search\",le=\"+Inf\"}} 1");
println!("request_duration_ms_sum{{endpoint=\"/api/search\"}} 150.0");
println!("request_duration_ms_count{{endpoint=\"/api/search\"}} 1");
println!("---\n");
println!("These metrics can be scraped by Prometheus for monitoring and alerting.\n");
Ok(())
}