Skip to main content

media_pp\core/
pp_log.rs

1//! Contextual logging identity and macros used by pipeline elements.
2//!
3//! A [`PpLog`] stores the stable, structured identity for one element. The `pp_*`
4//! macros send records only to [`crate::log`]'s opt-in private file writer,
5//! keeping them isolated from an embedding application's global logger.
6
7use std::sync::Arc;
8
9/// Stable contextual identity attached to a pipeline element's log records.
10#[derive(Debug, Clone)]
11pub struct PpLog {
12    pipeline_id: Option<Arc<str>>,
13    element: Arc<str>,
14    name: Arc<str>,
15}
16
17impl PpLog {
18    /// Creates a logging identity.
19    ///
20    /// `element` is the element type (for example `FileDemuxer`), while
21    /// `name` is the caller-selected instance name (for example `demux`).
22    /// `pipeline_id` is omitted until the element is attached to a pipeline.
23    pub fn new(element: &str, name: &str, pipeline_id: Option<&str>) -> Self {
24        Self {
25            pipeline_id: pipeline_id.map(Arc::from),
26            element: Arc::from(element),
27            name: Arc::from(name),
28        }
29    }
30
31    pub fn pipeline_id(&self) -> Option<&str> {
32        self.pipeline_id.as_deref()
33    }
34
35    pub fn element(&self) -> &str {
36        &self.element
37    }
38
39    pub fn name(&self) -> &str {
40        &self.name
41    }
42}
43
44#[doc(hidden)]
45pub mod __private {
46    pub use crate::log::{Level, emit, enabled};
47}
48
49#[doc(hidden)]
50#[macro_export]
51macro_rules! __pp_log {
52    ($level:expr, pp_log: $pp_log:expr, $($arg:tt)+) => {{
53        let level = $level;
54        if $crate::pp_log::__private::enabled(level) {
55            $crate::pp_log::__private::emit(
56                level,
57                $pp_log,
58                format_args!($($arg)+),
59            );
60        }
61    }};
62    ($level:expr, $self:ident, $($arg:tt)+) => {{
63        let level = $level;
64        if $crate::pp_log::__private::enabled(level) {
65            $crate::pp_log::__private::emit(
66                level,
67                &$self.pp_log,
68                format_args!($($arg)+),
69            );
70        }
71    }};
72}
73
74#[macro_export]
75macro_rules! pp_info {
76    ($($arg:tt)+) => {
77        $crate::__pp_log!($crate::pp_log::__private::Level::Info, $($arg)+)
78    };
79}
80
81#[macro_export]
82macro_rules! pp_debug {
83    ($($arg:tt)+) => {
84        $crate::__pp_log!($crate::pp_log::__private::Level::Debug, $($arg)+)
85    };
86}
87
88#[macro_export]
89macro_rules! pp_warn {
90    ($($arg:tt)+) => {
91        $crate::__pp_log!($crate::pp_log::__private::Level::Warn, $($arg)+)
92    };
93}
94
95#[macro_export]
96macro_rules! pp_error {
97    ($($arg:tt)+) => {
98        $crate::__pp_log!($crate::pp_log::__private::Level::Error, $($arg)+)
99    };
100}
101
102#[macro_export]
103macro_rules! pp_trace {
104    ($($arg:tt)+) => {
105        $crate::__pp_log!($crate::pp_log::__private::Level::Trace, $($arg)+)
106    };
107}
108
109pub use crate::{pp_debug, pp_error, pp_info, pp_trace, pp_warn};
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn keeps_each_identity_field_separate() {
117        let pp_log = PpLog::new("FileDemuxer", "demux", Some("app-sink"));
118        assert_eq!(pp_log.pipeline_id(), Some("app-sink"));
119        assert_eq!(pp_log.element(), "FileDemuxer");
120        assert_eq!(pp_log.name(), "demux");
121    }
122}