use rollblock::metrics::HealthState;
use rollblock::types::{Operation, StoreKey as Key, Value};
use rollblock::{SimpleStoreFacade, StoreConfig, StoreFacade};
fn key_from_u8(i: u8) -> Key {
Key::from_prefix([i, 0, 0, 0, 0, 0, 0, 0])
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.with_target(false)
.with_thread_ids(true)
.with_file(true)
.with_line_number(true)
.init();
println!("ð Rollblock Observability Example\n");
println!("This example demonstrates metrics collection and tracing.");
println!("Set RUST_LOG=debug for detailed traces.\n");
let config = StoreConfig::new(
"./data/observability_example",
4, 1000, 1, false, )?
.without_remote_server();
let store = SimpleStoreFacade::new(config)?;
println!("ð Initial Health Check");
if let Some(health) = store.health() {
print_health(&health);
}
println!();
println!("âïļ Performing operations...");
let mut operations = Vec::new();
for i in 0..10 {
operations.push(Operation {
key: key_from_u8(i),
value: (i as u64 * 100).into(),
});
}
store.set(1, operations)?;
println!("â Block 1: Set 10 keys");
let mut operations = Vec::new();
for i in 0..5 {
operations.push(Operation {
key: key_from_u8(i),
value: (i as u64 * 200).into(),
});
}
store.set(2, operations)?;
println!("â Block 2: Updated 5 keys");
let mut operations = Vec::new();
for i in 0..3 {
operations.push(Operation {
key: key_from_u8(i),
value: Value::empty(),
});
}
store.set(3, operations)?;
println!("â Block 3: Deleted 3 keys");
println!("\nð Performing lookups...");
for i in 0..10 {
let key = key_from_u8(i);
let _ = store.get(key)?;
}
println!("â Performed 10 lookups");
println!("\n⊠Rolling back to block 1...");
store.rollback(1)?;
println!("â Rollback complete");
println!("\nð Metrics Report");
println!("âââââââââââââââââââââââââââââââââââââââââââââââââââ");
if let Some(metrics) = store.metrics() {
let snapshot = metrics.snapshot();
println!("Operations:");
println!(
" âĒ Total operations applied: {}",
snapshot.operations_applied
);
println!(
" âĒ Sets: {} ({} empty-value deletes)",
snapshot.set_operations_applied, snapshot.zero_value_deletes_applied
);
println!(" âĒ Blocks committed: {}", snapshot.blocks_committed);
println!(" âĒ Rollbacks executed: {}", snapshot.rollbacks_executed);
println!(" âĒ Lookups performed: {}", snapshot.lookups_performed);
println!("\nPerformance (Averages):");
println!(" âĒ Apply time: {} Ξs", snapshot.avg_apply_time_us);
println!(" âĒ Rollback time: {} Ξs", snapshot.avg_rollback_time_us);
println!(" âĒ Lookup time: {} Ξs", snapshot.avg_lookup_time_us);
println!("\nPerformance (Percentiles):");
println!(" âĒ Apply P50: {} Ξs", snapshot.apply_p50_us);
println!(" âĒ Apply P95: {} Ξs", snapshot.apply_p95_us);
println!(" âĒ Apply P99: {} Ξs", snapshot.apply_p99_us);
println!(" âĒ Rollback P50: {} Ξs", snapshot.rollback_p50_us);
println!(" âĒ Rollback P95: {} Ξs", snapshot.rollback_p95_us);
println!(" âĒ Rollback P99: {} Ξs", snapshot.rollback_p99_us);
println!("\nState:");
println!(" âĒ Current block: {}", snapshot.current_block_height);
println!(" âĒ Total keys stored: {}", snapshot.total_keys_stored);
println!("\nErrors:");
println!(" âĒ Failed operations: {}", snapshot.failed_operations);
println!(" âĒ Checksum errors: {}", snapshot.checksum_errors);
if let Some(secs) = snapshot.last_operation_secs {
println!("\nActivity:");
println!(" âĒ Last operation: {} seconds ago", secs);
}
}
println!("\nðĨ Final Health Check");
println!("âââââââââââââââââââââââââââââââââââââââââââââââââââ");
if let Some(health) = store.health() {
print_health(&health);
}
if let Some(metrics) = store.metrics() {
let snapshot = metrics.snapshot();
let json = serde_json::to_string_pretty(&snapshot)?;
println!("\nð Metrics JSON:");
println!("{}", json);
}
println!("\nâ
Example completed successfully!");
println!("\nTip: Run with RUST_LOG=debug to see detailed tracing information.");
Ok(())
}
fn print_health(health: &rollblock::metrics::HealthStatus) {
let status_emoji = match health.state {
HealthState::Healthy => "â
",
HealthState::Idle => "ðĪ",
HealthState::Degraded => "â ïļ",
HealthState::Unhealthy => "â",
};
println!(" {} Status: {}", status_emoji, health.state);
println!(" âĒ Applied block: {}", health.current_block);
println!(" âĒ Durable block: {}", health.durable_block);
println!(" âĒ Total operations: {}", health.total_operations);
println!(" âĒ Failed operations: {}", health.failed_operations);
println!(" âĒ Checksum errors: {}", health.checksum_errors);
if let Some(secs) = health.last_operation_secs {
println!(" âĒ Last operation: {} seconds ago", secs);
} else {
println!(" âĒ Last operation: never");
}
}