Skip to content

Commit

Permalink
Detect failure to install GUI log callback (#1655)
Browse files Browse the repository at this point in the history
* Detect failure to install GUI log callback

* typo

* Fix compilation on wasm
  • Loading branch information
emilk authored Mar 22, 2023
1 parent f5de99e commit dac6286
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 13 deletions.
2 changes: 1 addition & 1 deletion crates/re_log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub use log_once::{debug_once, error_once, info_once, trace_once, warn_once};

pub use {
channel_logger::*,
multi_logger::{add_boxed_logger, add_logger},
multi_logger::{add_boxed_logger, add_logger, MultiLoggerNotSetupError},
setup::*,
};

Expand Down
24 changes: 16 additions & 8 deletions crates/re_log/src/multi_logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,32 @@ static MULTI_LOGGER: MultiLogger = MultiLogger::new();

static HAS_MULTI_LOGGER: AtomicBool = AtomicBool::new(false);

/// Produced when trying to install additional loggers when [`init`] has not been called.
///
/// This can happen for example when users of the `rerun` crate use the `spawn` method,
/// and they aren't using `re_log`.
#[derive(Clone, Copy, Debug)]
pub struct MultiLoggerNotSetupError {}

/// Install the multi-logger as the default logger.
pub fn init() -> Result<(), log::SetLoggerError> {
HAS_MULTI_LOGGER.store(true, SeqCst);
log::set_logger(&MULTI_LOGGER)
}

/// Install an additional global logger.
pub fn add_boxed_logger(logger: Box<dyn log::Log>) {
add_logger(Box::leak(logger));
pub fn add_boxed_logger(logger: Box<dyn log::Log>) -> Result<(), MultiLoggerNotSetupError> {
add_logger(Box::leak(logger))
}

/// Install an additional global logger.
pub fn add_logger(logger: &'static dyn log::Log) {
debug_assert!(
HAS_MULTI_LOGGER.load(SeqCst),
"You forgot to setup multi-logging"
);
MULTI_LOGGER.loggers.write().push(logger);
pub fn add_logger(logger: &'static dyn log::Log) -> Result<(), MultiLoggerNotSetupError> {
if HAS_MULTI_LOGGER.load(SeqCst) {
MULTI_LOGGER.loggers.write().push(logger);
Ok(())
} else {
Err(MultiLoggerNotSetupError {})
}
}

/// Forward log messages to multiple [`log::log`] receivers.
Expand Down
5 changes: 3 additions & 2 deletions crates/re_log/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn setup_native_logging() {

let mut stderr_logger = env_logger::Builder::new();
stderr_logger.parse_filters(&log_filter);
crate::add_boxed_logger(Box::new(stderr_logger.build()));
crate::add_boxed_logger(Box::new(stderr_logger.build())).expect("Failed to install logger");
}

#[cfg(target_arch = "wasm32")]
Expand All @@ -51,5 +51,6 @@ pub fn setup_web_logging() {
log::set_max_level(log::LevelFilter::Debug);
crate::add_boxed_logger(Box::new(crate::web_logger::WebLogger::new(
log::LevelFilter::Debug,
)));
)))
.expect("Failed to install logger");
}
2 changes: 1 addition & 1 deletion crates/re_ui/examples/re_ui_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub struct ExampleApp {
impl ExampleApp {
fn new(re_ui: re_ui::ReUi) -> Self {
let (logger, text_log_rx) = re_log::ChannelLogger::new(re_log::LevelFilter::Info);
re_log::add_boxed_logger(Box::new(logger));
re_log::add_boxed_logger(Box::new(logger)).unwrap();

let tree = egui_dock::Tree::new(vec![1, 2, 3]);

Expand Down
7 changes: 6 additions & 1 deletion crates/re_viewer/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ impl App {
shutdown: std::sync::Arc<std::sync::atomic::AtomicBool>,
) -> Self {
let (logger, text_log_rx) = re_log::ChannelLogger::new(re_log::LevelFilter::Info);
re_log::add_boxed_logger(Box::new(logger));
if re_log::add_boxed_logger(Box::new(logger)).is_err() {
// This can happen when `rerun` crate users call `spawn`. TODO(emilk): make `spawn` spawn a new process.
re_log::debug!(
"re_log not initialized - we won't see any log messages as GUI notifications"
);
}

let state: AppState = storage
.and_then(|storage| eframe::get_value(storage, eframe::APP_KEY))
Expand Down

0 comments on commit dac6286

Please sign in to comment.