#[cfg(feature = "setup")]
mod channel_logger;
mod debug_assert;
#[cfg(feature = "setup")]
mod event_visitor;
mod result_extensions;
#[cfg(feature = "setup")]
mod setup;
#[cfg(feature = "setup")]
pub use channel_logger::{LogMsg, Receiver, Sender, add_log_msg_receiver};
#[cfg(feature = "setup")]
pub use event_visitor::FieldValue;
pub use tracing::Level;
#[cfg(feature = "setup")]
pub use tracing_subscriber::filter::LevelFilter;
pub use log_once::{debug_once, error_once, info_once, trace_once, warn_once};
pub use result_extensions::ResultExt;
#[cfg(all(feature = "setup", not(target_arch = "wasm32")))]
pub use setup::PanicOnWarnScope;
#[cfg(feature = "setup")]
pub use setup::{setup_logging, setup_logging_with_filter};
pub use tracing::{debug, error, info, trace, warn};
#[macro_export]
macro_rules! log_once {
($level:expr, $($arg:tt)+) => {
match $level {
$crate::Level::ERROR => $crate::error_once!($($arg)+),
$crate::Level::WARN => $crate::warn_once!($($arg)+),
$crate::Level::INFO => $crate::info_once!($($arg)+),
$crate::Level::DEBUG => $crate::debug_once!($($arg)+),
$crate::Level::TRACE => $crate::trace_once!($($arg)+),
}
};
}
#[cfg(debug_assertions)]
#[macro_export]
macro_rules! debug_warn {
($($arg:tt)+) => {
$crate::warn!("DEBUG: {}", format_args!($($arg)+))
};
}
#[cfg(not(debug_assertions))]
#[macro_export]
macro_rules! debug_warn {
($($arg:tt)+) => {
$crate::debug!($($arg)+)
};
}
#[cfg(debug_assertions)]
#[macro_export]
macro_rules! debug_warn_once {
($($arg:tt)+) => {
$crate::warn_once!("DEBUG: {}", format_args!($($arg)+))
};
}
#[cfg(not(debug_assertions))]
#[macro_export]
macro_rules! debug_warn_once {
($($arg:tt)+) => {
$crate::debug_once!($($arg)+)
};
}
pub mod external {
pub use log;
}
const CRATES_AT_ERROR_LEVEL: &[&str] = &[
#[cfg(not(debug_assertions))]
"rustls",
];
const CRATES_AT_WARN_LEVEL: &[&str] = &[
"naga",
"tracing",
"wgpu_core",
"wgpu_hal",
"zbus",
];
const CRATES_AT_INFO_LEVEL: &[&str] = &[
"datafusion_optimizer",
"datafusion",
"h2",
"hyper",
"opentelemetry", "prost_build",
"reqwest", "sqlparser",
"tonic_web",
"tower",
"ureq",
#[cfg(debug_assertions)]
"rustls",
"walkers",
"winit",
];
#[cfg(not(target_arch = "wasm32"))]
pub fn default_log_filter() -> String {
let base_log_filter = if cfg!(debug_assertions) {
"debug"
} else {
"info"
};
log_filter_from_env_or_default(base_log_filter)
}
#[cfg(target_arch = "wasm32")]
pub fn default_log_filter() -> String {
"debug".to_owned()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn log_filter_from_env_or_default(default_base_log_filter: &str) -> String {
let rust_log = std::env::var("RUST_LOG").unwrap_or_else(|_| default_base_log_filter.to_owned());
add_builtin_log_filter(&rust_log)
}
#[cfg(not(target_arch = "wasm32"))]
fn add_builtin_log_filter(base_log_filter: &str) -> String {
use std::fmt::Write as _;
let mut rust_log = base_log_filter.to_lowercase();
if base_log_filter != "off" {
for crate_name in crate::CRATES_AT_ERROR_LEVEL {
if !rust_log.contains(&format!("{crate_name}=")) {
write!(rust_log, ",{crate_name}=error").ok();
}
}
if base_log_filter != "error" {
for crate_name in crate::CRATES_AT_WARN_LEVEL {
if !rust_log.contains(&format!("{crate_name}=")) {
write!(rust_log, ",{crate_name}=warn").ok();
}
}
if base_log_filter != "warn" {
for crate_name in crate::CRATES_AT_INFO_LEVEL {
if !rust_log.contains(&format!("{crate_name}=")) {
write!(rust_log, ",{crate_name}=info").ok();
}
}
}
}
}
rust_log += ",walkers::download=off";
rust_log
}
#[cfg(feature = "setup")]
fn is_log_enabled(
filter: tracing_subscriber::filter::LevelFilter,
metadata: &tracing::Metadata<'_>,
) -> bool {
if CRATES_AT_ERROR_LEVEL
.iter()
.any(|crate_name| metadata.target().starts_with(crate_name))
{
*metadata.level() <= tracing_subscriber::filter::LevelFilter::ERROR
} else if CRATES_AT_WARN_LEVEL
.iter()
.any(|crate_name| metadata.target().starts_with(crate_name))
{
*metadata.level() <= tracing_subscriber::filter::LevelFilter::WARN
} else if CRATES_AT_INFO_LEVEL
.iter()
.any(|crate_name| metadata.target().starts_with(crate_name))
{
*metadata.level() <= tracing_subscriber::filter::LevelFilter::INFO
} else {
*metadata.level() <= filter
}
}
pub fn env_var_flag(var_name: &str) -> Option<bool> {
match std::env::var(var_name)
.ok()?
.trim()
.to_ascii_lowercase()
.as_str()
{
"" => None,
"0" | "false" | "no" | "off" => Some(false),
"1" | "true" | "yes" | "on" => Some(true),
value => {
crate::warn_once!(
"Ignoring unrecognized value {value:?} for environment variable {var_name:?} \
(expected one of: 1/true/yes/on, 0/false/no/off); falling back to the default."
);
None
}
}
}
pub fn env_var_is_truthy(var_name: &str) -> bool {
env_var_flag(var_name).unwrap_or(false)
}
pub fn is_rerun_very_strict() -> bool {
static VERY_STRICT: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
*VERY_STRICT.get_or_init(|| env_var_is_truthy("RERUN_VERY_STRICT"))
}
#[allow(clippy::allow_attributes, dead_code)] fn shorten_file_path(file_path: &str) -> &str {
if let Some(i) = file_path.rfind("/src/") {
if let Some(prev_slash) = file_path[..i].rfind('/') {
&file_path[prev_slash + 1..]
} else {
file_path
}
} else {
file_path
}
}
#[test]
fn test_shorten_file_path() {
for (before, after) in [
(
"/Users/emilk/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.24.1/src/runtime/runtime.rs",
"tokio-1.24.1/src/runtime/runtime.rs",
),
("crates/rerun/src/main.rs", "rerun/src/main.rs"),
(
"/rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/ops/function.rs",
"core/src/ops/function.rs",
),
("/weird/path/file.rs", "/weird/path/file.rs"),
] {
assert_eq!(shorten_file_path(before), after);
}
}