//! Logging utility to forward logging. use std::{io, sync::Arc};
use tracing::{Level, debug}; use tracing_subscriber::{filter::LevelFilter, fmt::MakeWriter};
/// Log levels used by libthreema. #[derive(Clone, Copy, Debug, uniffi::Enum)] pubenum LogLevel { /// Extremely verbose, often leaking sensitive data. Only use this for specific debugging /// sessions.
Trace, /// Verbose. Should not leak sensitive data and is therefore safe to use in debug builds.
Debug, /// Useful information. Should be used by release builds.
Info, /// Warns about unexpected situations.
Warn, /// Indicates an internal error has been encountered.
Error,
}
impl From<Level> for LogLevel { fn from(level: Level) -> Self { match level {
Level::TRACE => LogLevel::Trace,
Level::DEBUG => LogLevel::Debug,
Level::INFO => LogLevel::Info,
Level::WARN => LogLevel::Warn,
Level::ERROR => LogLevel::Error,
}
}
} /// Dispatches log records from libthreema. #[uniffi::export(with_foreign)] pubtrait LogDispatcher: Send + Sync { /// Handle a log record. /// /// # Errors /// /// This function is considered infallible and should not return an error. If it does however, /// libthreema will discard the error. fn log(&self, level: LogLevel, record: String) -> Result<(), super::InfallibleError>;
}
fn flush(&mutself) -> io::Result<()> { // Nothing to-do here, we instead flush on drop
Ok(())
}
}
impl Drop for DispatchWriter { fn drop(&mutself) { let record = String::from_utf8_lossy(&self.buffer).to_string(); // Ignoring result as there's not much we can do here other than to log... which will likely // fail again let _ = self.dispatcher.log(self.level, record);
}
}
/// Initialise logging with the provided log dispatcher and minimum log level. /// /// IMPORTANT: This may only be called **once**! pub(super) fn init_logging(min_log_level: LogLevel, log_dispatcher: Arc<dyn LogDispatcher>) { // Configure tracing let level_filter: LevelFilter = min_log_level.into(); let subscriber = tracing_subscriber::fmt()
.with_max_level(level_filter)
.with_ansi(false)
.with_target(false)
.with_level(false)
.without_time()
.with_writer(MakeDispatchWriter::new(log_dispatcher))
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("Cannot initialize logging multiple times. Did you call this more than once?");
debug!(?level_filter, "Configured log level filter");
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-22)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.