use config_lib::{audit::*, Config};
use std::fs::File;
use std::io::Write;
fn main() -> config_lib::Result<()> {
println!("=== Comprehensive Audit Logging Demo ===");
let audit_logger = AuditLogger::new()
.add_sink(Box::new(ConsoleSink::new(AuditSeverity::Info)))
.add_sink(Box::new(FileSink::new(
"config_audit.log",
AuditSeverity::Warning,
)));
init_audit_logger(audit_logger);
println!("1. Initialized audit logging (console + file)");
let config_path = "audit_demo.conf";
let mut file = File::create(config_path)?;
writeln!(file, "database_host=localhost")?;
writeln!(file, "database_port=5432")?;
writeln!(file, "debug_enabled=false")?;
file.flush()?;
drop(file);
println!("\n2. Loading configuration...");
let mut config = Config::from_file(config_path)?;
if let Some(logger) = get_audit_logger() {
logger.log_event(
AuditEvent::new(AuditEventType::Load, AuditSeverity::Info)
.with_source(config_path)
.with_user_context("demo_user")
.with_metadata("format", "conf")
.with_metadata("keys_loaded", "3"),
);
}
println!("\n3. Accessing configuration values...");
if let Some(logger) = get_audit_logger() {
logger.log_access("database_host", Some("demo_user"));
}
let host = config.get("database_host").unwrap().as_string().unwrap();
println!(" Database Host: {host}");
if let Some(logger) = get_audit_logger() {
logger.log_access("database_port", Some("demo_user"));
}
let port = config.get("database_port").unwrap().as_integer().unwrap();
println!(" Database Port: {port}");
if let Some(logger) = get_audit_logger() {
logger.log_access("debug_enabled", Some("demo_user"));
}
let debug = config.get("debug_enabled").unwrap().as_bool().unwrap();
println!(" Debug Enabled: {debug}");
println!("\n4. Modifying configuration values...");
let old_port = config.get("database_port").cloned();
config.set("database_port", 5433)?;
if let Some(logger) = get_audit_logger() {
logger.log_modification(
"database_port",
old_port.as_ref(),
&config_lib::Value::Integer(5433),
Some("demo_user"),
);
}
println!(" Changed database port: 5432 -> 5433");
let old_debug = config.get("debug_enabled").cloned();
config.set("debug_enabled", true)?;
if let Some(logger) = get_audit_logger() {
logger.log_modification(
"debug_enabled",
old_debug.as_ref(),
&config_lib::Value::Bool(true),
Some("demo_user"),
);
}
println!(" Changed debug mode: false -> true");
config.set("max_connections", 100)?;
if let Some(logger) = get_audit_logger() {
logger.log_modification(
"max_connections",
None,
&config_lib::Value::Integer(100),
Some("demo_user"),
);
}
println!(" Added new key: max_connections = 100");
println!("\n5. Simulating validation failures...");
if let Some(logger) = get_audit_logger() {
logger.log_validation_failure(
"database_port",
"Port must be between 1024 and 65535",
&config_lib::Value::Integer(99999),
Some("demo_user"),
);
}
println!(" Validation failed: database_port=99999 (out of range)");
if let Some(logger) = get_audit_logger() {
logger.log_validation_failure(
"database_host",
"Invalid hostname format",
&config_lib::Value::String("invalid..host".to_string()),
Some("demo_user"),
);
}
println!(" Validation failed: database_host='invalid..host' (invalid format)");
println!("\n6. Simulating configuration reloads...");
if let Some(logger) = get_audit_logger() {
logger.log_reload(config_path, true, None);
}
println!(" Successful reload from {config_path}");
if let Some(logger) = get_audit_logger() {
logger.log_reload("invalid_config.conf", false, Some("File not found"));
}
println!(" Failed reload from invalid_config.conf");
println!("\n7. Logging custom audit events...");
if let Some(logger) = get_audit_logger() {
logger.log_event(
AuditEvent::new(AuditEventType::Access, AuditSeverity::Critical)
.with_key("admin_password")
.with_user_context("unauthorized_user")
.with_metadata("ip_address", "192.168.1.100")
.with_metadata("attempt_count", "3")
.with_error("Unauthorized access attempt"),
);
logger.log_event(
AuditEvent::new(AuditEventType::Access, AuditSeverity::Warning)
.with_key("large_dataset")
.with_user_context("batch_processor")
.with_metadata("processing_time_ms", "5000")
.with_metadata("memory_usage_mb", "512"),
);
}
println!(" Logged security and performance events");
println!("\n8. Flushing audit logs...");
if let Some(logger) = get_audit_logger() {
logger.flush();
}
println!("\n9. File audit log contents:");
if let Ok(contents) = std::fs::read_to_string("config_audit.log") {
for line in contents.lines() {
println!(" {line}");
}
}
let _ = std::fs::remove_file(config_path);
let _ = std::fs::remove_file("config_audit.log");
println!("\n✅ Audit logging demo completed successfully!");
println!(" - Structured event logging ✓");
println!(" - Multiple severity levels ✓");
println!(" - User context tracking ✓");
println!(" - Before/after value tracking ✓");
println!(" - Multiple output sinks ✓");
println!(" - Performance metadata ✓");
println!(" - Security event detection ✓");
Ok(())
}