libobs_wrapper\logger/
mod.rs

1mod console;
2mod file;
3pub use console::ConsoleLogger;
4pub use file::FileLogger;
5
6use std::{fmt::Debug, os::raw::c_void, sync::Mutex};
7
8use lazy_static::lazy_static;
9use num_traits::FromPrimitive;
10use vsprintf::vsprintf;
11
12use crate::enums::ObsLogLevel;
13
14lazy_static! {
15    /// We are using this as global variable because there can only be one obs context
16    pub static ref LOGGER: Mutex<Box<dyn ObsLogger>> = Mutex::new(Box::new(ConsoleLogger::new()));
17}
18
19pub(crate) unsafe extern "C" fn extern_log_callback<V>(
20    log_level: i32,
21    msg: *const i8,
22    args: *mut V,
23    _params: *mut c_void,
24) {
25    let level = ObsLogLevel::from_i32(log_level);
26    if level.is_none() {
27        eprintln!("Couldn't find log level {}", log_level);
28        return;
29    }
30
31    let level = level.unwrap();
32
33    let formatted = vsprintf(msg, args);
34    if formatted.is_err() {
35        eprintln!("Failed to format log message");
36        return;
37    }
38
39    let mut logger = LOGGER.lock().unwrap();
40
41    logger.log(level, formatted.unwrap());
42}
43
44pub trait ObsLogger
45where
46    Self: Send + Debug,
47{
48    fn log(&mut self, level: ObsLogLevel, msg: String);
49}
50
51pub(crate) fn internal_log_global(level: ObsLogLevel, msg: String) {
52    let mut logger = LOGGER.lock().unwrap();
53    logger.log(level, msg);
54}