log: Log trait adapter around the GStreamer debug system

Allows usage of normal `log` crate macros, and for other crates
using those macros to have their log messages go to the GStreamer
debug logs.

This implementation is based on the one found in Servo.

Fixes #187
This commit is contained in:
Nick Steel 2024-04-21 00:12:31 +01:00
parent 241338f43c
commit 78d4db1b6c
3 changed files with 61 additions and 6 deletions

View file

@ -23,6 +23,7 @@ num-rational = { version = "0.4", default-features = false, features = [] }
futures-core = "0.3"
futures-channel = "0.3"
futures-util = { version = "0.3", default-features = false }
log = "0.4"
muldiv = "1"
opt-ops = { package = "option-operations", version = "0.5" }
serde = { version = "1.0", optional = true, features = ["derive"] }

View file

@ -50,12 +50,12 @@ mod serde_macros;
#[macro_use]
pub mod log;
pub use crate::log::{
DebugCategory, DebugLogFunction, DebugMessage, LoggedObject, CAT_BUFFER, CAT_BUFFER_LIST,
CAT_BUS, CAT_CALL_TRACE, CAT_CAPS, CAT_CLOCK, CAT_CONTEXT, CAT_DEFAULT, CAT_ELEMENT_PADS,
CAT_ERROR_SYSTEM, CAT_EVENT, CAT_GST_INIT, CAT_LOCKING, CAT_MEMORY, CAT_MESSAGE, CAT_META,
CAT_NEGOTIATION, CAT_PADS, CAT_PARAMS, CAT_PARENTAGE, CAT_PERFORMANCE, CAT_PIPELINE,
CAT_PLUGIN_INFO, CAT_PLUGIN_LOADING, CAT_PROBE, CAT_PROPERTIES, CAT_QOS, CAT_REFCOUNTING,
CAT_REGISTRY, CAT_RUST, CAT_SCHEDULING, CAT_SIGNAL, CAT_STATES,
DebugCategory, DebugCategoryLogger, DebugLogFunction, DebugMessage, LoggedObject, CAT_BUFFER,
CAT_BUFFER_LIST, CAT_BUS, CAT_CALL_TRACE, CAT_CAPS, CAT_CLOCK, CAT_CONTEXT, CAT_DEFAULT,
CAT_ELEMENT_PADS, CAT_ERROR_SYSTEM, CAT_EVENT, CAT_GST_INIT, CAT_LOCKING, CAT_MEMORY,
CAT_MESSAGE, CAT_META, CAT_NEGOTIATION, CAT_PADS, CAT_PARAMS, CAT_PARENTAGE, CAT_PERFORMANCE,
CAT_PIPELINE, CAT_PLUGIN_INFO, CAT_PLUGIN_LOADING, CAT_PROBE, CAT_PROPERTIES, CAT_QOS,
CAT_REFCOUNTING, CAT_REGISTRY, CAT_RUST, CAT_SCHEDULING, CAT_SIGNAL, CAT_STATES,
};
#[cfg(target_os = "macos")]

View file

@ -4,6 +4,7 @@ use std::{borrow::Cow, ffi::CStr, fmt, ptr};
use glib::{ffi::gpointer, prelude::*, translate::*};
use libc::c_char;
use log;
use once_cell::sync::Lazy;
use crate::DebugLevel;
@ -1064,6 +1065,43 @@ macro_rules! log_with_level(
}};
);
#[derive(Debug)]
pub struct DebugCategoryLogger(DebugCategory);
impl DebugCategoryLogger {
pub fn new(cat: DebugCategory) -> Self {
Self(cat)
}
}
impl log::Log for DebugCategoryLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}
fn log(&self, record: &log::Record) {
let lvl = match record.level() {
log::Level::Error => DebugLevel::Error,
log::Level::Warn => DebugLevel::Warning,
log::Level::Info => DebugLevel::Info,
log::Level::Debug => DebugLevel::Debug,
log::Level::Trace => DebugLevel::Trace,
};
let file = record.file().unwrap_or("");
let file = glib::GStr::from_str_until_nul(file).unwrap_or_default();
self.0.log(
None::<&glib::Object>,
lvl,
file,
record.module_path().unwrap_or(""),
record.line().unwrap_or(0),
record.args().clone(),
);
}
fn flush(&self) {}
}
unsafe extern "C" fn log_handler<T>(
category: *mut ffi::GstDebugCategory,
level: ffi::GstDebugLevel,
@ -1308,6 +1346,22 @@ mod tests {
memdump!(cat, obj: obj, "meh");
}
static LOGGER: Lazy<DebugCategoryLogger> = Lazy::new(|| {
DebugCategoryLogger::new(DebugCategory::new(
"Log_trait",
crate::DebugColorFlags::empty(),
Some("Using the Log trait"),
))
});
#[test]
fn log_trait() {
crate::init().unwrap();
log::set_logger(&(*LOGGER)).expect("Failed to set logger");
log::error!("meh");
}
#[test]
fn log_handler() {
crate::init().unwrap();