pub mod backends;
pub mod error;
pub mod traits;
pub mod types;
pub use error::AuditError;
pub use traits::{AuditConfig, AuditLogger, AuditStats, CompositeLogger, MemoryLogger, NoOpLogger};
pub use types::{
AuditContext, AuditEvent, AuditEventBuilder, AuditLevel, EventKind, LifecycleAction,
SecurityEventType,
};
pub use backends::{
AsyncLogger, AsyncLoggerBuilder, FileLogger, JsonFileLogger, RotationConfig, RotationPolicy,
};
pub async fn create_production_logger(
path: impl Into<std::path::PathBuf>,
) -> Result<JsonFileLogger, AuditError> {
let rotation = RotationConfig::new(RotationPolicy::Daily).with_max_files(30);
JsonFileLogger::new(path, AuditConfig::production(), rotation).await
}
pub async fn create_dev_logger(
path: impl Into<std::path::PathBuf>,
) -> Result<FileLogger, AuditError> {
FileLogger::new(path, AuditConfig::development()).await
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_memory_logger_integration() {
let logger = MemoryLogger::new();
logger
.log(AuditEvent::tool_call("tool1", serde_json::json!({}), true))
.await
.unwrap();
logger
.log(AuditEvent::llm_request("anthropic", "claude-3", false))
.await
.unwrap();
logger
.log(AuditEvent::error_event(
"RuntimeError",
"Something went wrong",
))
.await
.unwrap();
assert_eq!(logger.count().await, 3);
let events = logger.events().await;
assert!(matches!(events[0].kind, EventKind::ToolCall { .. }));
assert!(matches!(events[1].kind, EventKind::LlmRequest { .. }));
assert!(matches!(events[2].kind, EventKind::Error { .. }));
}
#[test]
fn test_event_builder() {
let event = AuditEventBuilder::new()
.level(AuditLevel::Info)
.kind(EventKind::Custom {
name: "test".to_string(),
payload: serde_json::json!({"key": "value"}),
})
.trace_id("trace-1")
.session_id("session-1")
.agent_id("agent-1")
.build();
assert_eq!(event.level, AuditLevel::Info);
assert_eq!(event.context.trace_id, Some("trace-1".to_string()));
assert_eq!(event.context.session_id, Some("session-1".to_string()));
assert_eq!(event.context.agent_id, Some("agent-1".to_string()));
}
#[test]
fn test_config_presets() {
let dev = AuditConfig::development();
assert_eq!(dev.min_level, AuditLevel::Debug);
assert!(dev.include_debug);
assert!(!dev.redact_sensitive);
let prod = AuditConfig::production();
assert_eq!(prod.min_level, AuditLevel::Info);
assert!(!prod.include_debug);
assert!(prod.redact_sensitive);
}
}