use ri::observability::{RiObservabilityModule, RiObservabilityConfig, RiMetricsRegistry, RiTracer, RiMetricType};
use ri::core::RiResult;
fn main() -> RiResult<()> {
println!("=== Ri Observability Module Example ===\n");
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let config = RiObservabilityConfig::new()
.with_service_name("ri-example")
.with_service_version("1.0.0")
.with_environment("development")
.with_metrics_enabled(true)
.with_tracing_enabled(true)
.with_tracing_sample_rate(1.0)
.build();
println!("1. Creating observability module...");
let observability = RiObservabilityModule::new(config).await?;
let metrics = observability.get_metrics();
let tracer = observability.get_tracer();
println!(" Observability module initialized\n");
println!("2. Creating custom metrics...");
let request_counter = metrics.create_metric(
"http_requests_total",
"Total number of HTTP requests",
RiMetricType::Counter,
vec!["method", "endpoint", "status"],
)?;
println!(" Created counter: http_requests_total\n");
let active_connections = metrics.create_metric(
"active_connections",
"Number of active connections",
RiMetricType::Gauge,
vec!["protocol"],
)?;
println!(" Created gauge: active_connections\n");
let request_duration = metrics.create_metric(
"http_request_duration_seconds",
"HTTP request duration in seconds",
RiMetricType::Histogram,
vec!["method", "endpoint"],
)?;
println!(" Created histogram: http_request_duration_seconds\n");
println!("3. Recording metrics...");
request_counter.increment(vec!["GET", "/api/users", "200"])?;
request_counter.increment(vec!["GET", "/api/users", "200"])?;
request_counter.increment(vec!["POST", "/api/users", "201"])?;
request_counter.increment(vec!["GET", "/api/orders", "500"])?;
println!(" Recorded request metrics\n");
active_connections.set(100, vec!["HTTP"])?;
active_connections.set(25, vec!["WebSocket"])?;
println!(" Updated connection gauges\n");
request_duration.record(0.125, vec!["GET", "/api/users"])?;
request_duration.record(0.250, vec!["GET", "/api/users"])?;
request_duration.record(0.075, vec!["POST", "/api/users"])?;
println!(" Recorded duration metrics\n");
println!("4. Recording custom business metrics...");
let user_registrations = metrics.create_metric(
"user_registrations_total",
"Total number of user registrations",
RiMetricType::Counter,
vec!["source"],
)?;
user_registrations.increment(vec!["web"])?;
user_registrations.increment(vec!["mobile"])?;
user_registrations.increment(vec!["web"])?;
println!(" Recorded user registration metrics\n");
println!("5. Creating distributed trace...");
let _span = tracer.span("process_user_request")
.with_attribute("user_id", "user-123")
.with_attribute("operation", "update_profile")
.start();
{
let child_span = tracer.span("validate_input")
.parent(&_span)
.start();
println!(" Created parent span: process_user_request");
println!(" Created child span: validate_input");
child_span.end();
}
let error_span = tracer.span("database_operation")
.parent(&_span)
.with_attribute("operation", "update")
.with_attribute("table", "users")
.start();
println!(" Created span: database_operation");
error_span.record_error("Connection timeout");
error_span.end();
_span.end();
println!(" All spans ended\n");
println!("6. Getting metrics snapshot...");
let snapshot = metrics.snapshot();
println!(" Metrics snapshot:");
println!(" - Total metric families: {}\n", snapshot.len());
println!("7. Exporting metrics in Prometheus format...");
let prometheus_output = metrics.export_prometheus();
println!(" Prometheus metrics (first 500 chars):");
println!(" {}\n", &prometheus_output[..500.min(prometheus_output.len())]);
println!("8. Setting up health check...");
observability.register_health_check("database", async {
Ok(ri::observability::RiHealthStatus::Healthy)
}).await;
println!(" Registered 'database' health check\n");
println!("9. Running health checks...");
let health_report = observability.run_health_checks().await?;
println!(" Health report:");
println!(" - Overall status: {:?}", health_report.overall_status());
println!(" - Check results:");
for (name, result) in health_report.results() {
println!(" - {}: {:?}", name, result.status());
}
println!();
println!("10. Recording system metrics...");
let cpu_usage = metrics.create_metric(
"system_cpu_usage_percent",
"CPU usage percentage",
RiMetricType::Gauge,
vec!["core"],
)?;
cpu_usage.set(45.5, vec!["core-0"])?;
cpu_usage.set(52.3, vec!["core-1"])?;
let memory_usage = metrics.create_metric(
"system_memory_usage_bytes",
"Memory usage in bytes",
RiMetricType::Gauge,
vec!["type"],
)?;
memory_usage.set(1024 * 1024 * 512, vec!["heap"])?;
memory_usage.set(1024 * 1024 * 128, vec!["stack"])?;
println!(" Recorded system metrics\n");
println!("11. Getting observability statistics...");
let stats = observability.get_statistics().await?;
println!(" Observability statistics:");
println!(" - Metrics recorded: {}", stats.metrics_recorded());
println!(" - Spans created: {}", stats.spans_created());
println!(" - Errors recorded: {}\n", stats.errors_recorded());
println!("=== Observability Example Completed ===");
Ok::<(), RiError>(())
})?
}