use std::env;
use tracing::{debug, error, info, trace, warn};
use tracing_better_stack::{BetterStackConfig, BetterStackLayer};
use tracing_subscriber::prelude::*;
use tracing_subscriber::{EnvFilter, filter::LevelFilter};
#[tokio::main]
async fn main() {
let ingesting_host = env::var("BETTER_STACK_INGESTING_HOST")
.expect("BETTER_STACK_INGESTING_HOST environment variable must be set");
let source_token = env::var("BETTER_STACK_SOURCE_TOKEN")
.expect("BETTER_STACK_SOURCE_TOKEN environment variable must be set");
let better_stack_layer =
BetterStackLayer::new(BetterStackConfig::builder(ingesting_host, source_token).build());
let _env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
let custom_filter = EnvFilter::new("")
.add_directive("with_filters=trace".parse().unwrap())
.add_directive("hyper=warn".parse().unwrap())
.add_directive("reqwest=info".parse().unwrap())
.add_directive(LevelFilter::INFO.into());
tracing_subscriber::registry()
.with(better_stack_layer.with_filter(LevelFilter::INFO))
.with(
tracing_subscriber::fmt::layer()
.with_target(true)
.compact()
.with_filter(custom_filter),
)
.init();
trace!("This trace message will only appear in console if RUST_LOG includes trace");
debug!("This debug message will only appear in console if RUST_LOG includes debug");
info!("This info message appears in both console and Better Stack");
warn!("This warning appears in both console and Better Stack");
error!("This error appears in both console and Better Stack");
module_a::do_work();
module_b::do_work();
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
info!("Application completed");
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
mod module_a {
use tracing::{debug, info};
pub fn do_work() {
info!("Module A: Starting work");
debug!("Module A: Debug information");
info!("Module A: Work completed");
}
}
mod module_b {
use tracing::{debug, error, info};
pub fn do_work() {
info!("Module B: Starting work");
debug!("Module B: Processing data");
if should_fail() {
error!("Module B: Operation failed!");
} else {
info!("Module B: Work completed successfully");
}
}
fn should_fail() -> bool {
false
}
}