use anyhow::Result;
use kerf::{Match, MatcherSet, Kerf, Config};
use std::fs::OpenOptions;
use std::io::Write;
use tracing::{Level, debug, error, info, span, trace, warn};
#[tokio::main]
async fn main() -> Result<()> {
let log_path = std::env::temp_dir().join("span_matcher_demo.log");
println!("Log file path: {}", log_path.display());
let log_file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&log_path)?;
let log_file = std::sync::Mutex::new(log_file);
let console_matcher = MatcherSet::from_matchers([
Match::info().all_modules(),
Match::trace().exclude().span_pattern("database*"),
Match::trace().exclude().target_pattern("foobar"),
]);
let file_matcher = MatcherSet::from_matchers([
Match::trace().span_pattern("database*"),
Match::trace().target_pattern("fooba*"),
]);
let config =
Config::from_tabs([("console", console_matcher), ("file-only", file_matcher)]);
let tracer = Kerf::init(config)?;
info!("Starting application");
info!("okay here we go");
tracer
.set_callback(move |event, tab_names| {
for &target in tab_names {
match target {
"file-only" => {
let mut file = log_file.lock().unwrap();
writeln!(file, "FILE: {}", event.format_full()).unwrap();
}
"console" => {
println!("{}", event.format());
}
_ => unreachable!(),
}
}
})?
.await??;
info!("okay here we go again");
warn!("This is a general warning");
info!(target:"foobar","THIS IS A SPECIAL TARGET MESSAGE");
{
let db_span = span!(Level::INFO, "database_query");
let _guard = db_span.enter();
trace!("Database connection established");
debug!("Preparing SQL query");
info!("Executing query: SELECT * FROM users");
warn!("Query took longer than expected: 250ms");
error!("Query error: deadlock detected");
}
info!("Continuing with application logic");
{
let app_span = span!(Level::INFO, "application");
let _app_guard = app_span.enter();
info!("This log is in the application span");
{
let db_span = span!(Level::INFO, "database_connection");
let _db_guard = db_span.enter();
info!("This log is in the database span"); debug!("Database connection details"); }
info!("Back to application span"); }
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
println!("\nCapture stats:");
println!("\nCheck the log file at: {}", log_path.display());
println!("Log file contents:");
let file_content = std::fs::read_to_string(&log_path)?;
println!("{file_content}");
Ok(())
}