142 lines
5.1 KiB
Rust
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(())
|
|
} |