libobs_wrapper\logger/
mod.rs

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