baobab/core/logger/examples/logging_demo.rs
Maxime Van Hees 9c4fa1a78b logger
2025-08-06 14:34:56 +02:00

142 lines
5.1 KiB
Rust

//! Logging System Demo
//!
//! This example demonstrates the Hero logging system functionality including:
//! - System logger initialization
//! - Per-job logger creation
//! - Rhai script integration with logging
//! - Directory structure creation
use hero_logger::{
init_system_logger, create_job_logger, rhai_integration::configure_rhai_logging,
};
use tracing::{info, debug, warn, error};
use tracing::subscriber::with_default;
use rhai::Engine;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🚀 Hero Logging System Demo");
println!("============================");
// 1. Initialize the system logger
println!("\n📋 Step 1: Initializing system logger...");
let components = vec![
"supervisor".to_string(),
"osis_actor".to_string(),
"sal_actor".to_string(),
];
let _guards = init_system_logger("demo_logs", &components)?;
println!("✅ System logger initialized with {} components", components.len());
// 2. Test system-level logging
println!("\n📝 Step 2: Testing system-level logging...");
info!(target: "supervisor", "Supervisor started successfully");
info!(target: "osis_actor", "OSIS actor is ready");
info!(target: "sal_actor", "SAL actor is ready");
warn!(target: "supervisor", "This is a warning message");
error!(target: "supervisor", "This is an error message for testing");
// Give time for async logging
sleep(Duration::from_millis(100)).await;
println!("✅ System logs written to demo_logs/supervisor/ and demo_logs/actor/*/");
// 3. Test per-job logging
println!("\n🔄 Step 3: Testing per-job logging...");
// Create job loggers for different jobs
let job1_logger = create_job_logger("demo_logs", "osis", "demo-job-001")?;
let job2_logger = create_job_logger("demo_logs", "sal", "demo-job-002")?;
// Execute logging within job contexts
with_default(job1_logger, || {
info!(target: "osis_actor", "Job demo-job-001 started");
debug!(target: "osis_actor", "Processing OSIS data");
info!(target: "osis_actor", "Job demo-job-001 completed successfully");
});
with_default(job2_logger, || {
info!(target: "sal_actor", "Job demo-job-002 started");
debug!(target: "sal_actor", "Processing SAL data");
warn!(target: "sal_actor", "Minor issue detected but continuing");
info!(target: "sal_actor", "Job demo-job-002 completed successfully");
});
sleep(Duration::from_millis(100)).await;
println!("✅ Per-job logs written to demo_logs/actor/*/job-*/");
// 4. Test Rhai integration
println!("\n🔧 Step 4: Testing Rhai script logging integration...");
let job3_logger = create_job_logger("demo_logs", "osis", "rhai-demo-003")?;
with_default(job3_logger, || {
let mut engine = Engine::new();
configure_rhai_logging(&mut engine, "osis_actor");
info!(target: "osis_actor", "Starting Rhai script execution");
// Execute a Rhai script that uses print and debug
let script = r#"
print("Hello from Rhai script!");
debug("This is a debug message from Rhai");
let result = 42 + 8;
print("Calculation result: " + result);
result
"#;
match engine.eval::<i64>(script) {
Ok(result) => {
info!(target: "osis_actor", "Rhai script completed with result: {}", result);
}
Err(e) => {
error!(target: "osis_actor", "Rhai script failed: {:?}", e);
}
}
});
sleep(Duration::from_millis(100)).await;
println!("✅ Rhai script logs captured in per-job logger");
// 5. Display directory structure
println!("\n📁 Step 5: Generated directory structure:");
display_directory_structure("demo_logs", 0)?;
println!("\n🎉 Demo completed successfully!");
println!("Check the 'demo_logs' directory to see the generated log files.");
println!("Each component and job has its own isolated log files with hourly rotation.");
Ok(())
}
/// Recursively display directory structure
fn display_directory_structure(path: &str, depth: usize) -> Result<(), Box<dyn std::error::Error>> {
let path = std::path::Path::new(path);
if !path.exists() {
return Ok(());
}
let indent = " ".repeat(depth);
if path.is_dir() {
println!("{}📁 {}/", indent, path.file_name().unwrap_or_default().to_string_lossy());
let mut entries: Vec<_> = std::fs::read_dir(path)?.collect::<Result<Vec<_>, _>>()?;
entries.sort_by_key(|entry| entry.file_name());
for entry in entries {
let entry_path = entry.path();
if entry_path.is_dir() {
display_directory_structure(&entry_path.to_string_lossy(), depth + 1)?;
} else {
println!("{}📄 {}", " ".repeat(depth + 1), entry.file_name().to_string_lossy());
}
}
}
Ok(())
}