//! 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> { 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::(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> { 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::, _>>()?; 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(()) }