libobs_wrapper\logger/
mod.rs1mod console;
5mod file;
6pub use console::ConsoleLogger;
7pub use file::FileLogger;
8
9use std::{fmt::Debug, os::raw::c_void, sync::Mutex};
10
11use lazy_static::lazy_static;
12use num_traits::FromPrimitive;
13use vsprintf::vsprintf;
14
15use crate::enums::ObsLogLevel;
16
17lazy_static! {
18 pub(crate) static ref LOGGER: Mutex<Box<dyn ObsLogger>> = Mutex::new(Box::new(ConsoleLogger::new()));
20}
21
22pub(crate) unsafe extern "C" fn extern_log_callback<V>(
25 log_level: i32,
26 msg: *const i8,
27 args: *mut V,
28 _params: *mut c_void,
29) {
30 let Some(level) = ObsLogLevel::from_i32(log_level) else {
31 eprintln!("Couldn't find log level {}", log_level);
32 return;
33 };
34
35 let Ok(formatted) = vsprintf(msg, args) else {
36 eprintln!("Failed to format log message");
37 return;
38 };
39
40 let mut logger = LOGGER
41 .lock()
42 .unwrap_or_else(|poisoned| poisoned.into_inner());
43 logger.log(level, formatted);
44}
45
46pub trait ObsLogger
47where
48 Self: Send + Debug,
49{
50 fn log(&mut self, level: ObsLogLevel, msg: String);
51}
52
53pub(crate) fn internal_log_global(level: ObsLogLevel, msg: String) {
54 let mut logger = LOGGER
55 .lock()
56 .unwrap_or_else(|poisoned| poisoned.into_inner());
57 logger.log(level, msg);
58}