nng_c/
utils.rs

1//! Utilities
2
3use nng_c_sys::nng_log_set_level;
4use nng_c_sys::nng_system_logger;
5use nng_c_sys::nng_null_logger;
6use nng_c_sys::nng_log_set_logger;
7
8#[derive(Copy, Clone)]
9#[repr(i32)]
10///NNG logging level
11pub enum Level {
12    ///NNG Error
13    Error = nng_c_sys::nng_log_level::NNG_LOG_ERR,
14    ///NNG Warnings
15    Warn = nng_c_sys::nng_log_level::NNG_LOG_WARN,
16    ///NNG Notice level
17    Info = nng_c_sys::nng_log_level::NNG_LOG_NOTICE,
18    ///NNG Info level
19    Debug = nng_c_sys::nng_log_level::NNG_LOG_INFO,
20    ///NNG Debug level
21    Trace = nng_c_sys::nng_log_level::NNG_LOG_DEBUG,
22}
23
24impl Level {
25    ///Initializes default logging level
26    ///
27    ///In debug builds it is `Debug` while in release builds it is `Warn`
28    pub const fn new() -> Self {
29        if cfg!(debug_assertions) {
30            Self::Debug
31        } else {
32            Self::Warn
33        }
34    }
35}
36
37impl Default for Level {
38    #[inline(always)]
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44///Disables logging
45pub fn disable_logging() {
46    unsafe {
47        nng_log_set_logger(Some(nng_null_logger));
48    }
49}
50
51///Enables logging using standard facilities of nng.
52///
53///Specifically it will use syslog on POSIX compliant systems while other systems will use stderr
54pub fn enable_logging(level: Level) {
55    unsafe {
56        nng_log_set_level(level as _);
57        nng_log_set_logger(Some(nng_system_logger));
58    }
59}
60
61#[cfg(feature = "log")]
62///Enables logging using [log](https://crates.io/crates/log) crate
63///
64///Requires feature `log`
65///
66///Note that messages are only logged if C strings are valid utf-8
67pub fn enable_log_logging(level: Level) {
68    use core::ffi::CStr;
69
70    unsafe extern "C" fn nng_rust_log_logger(level: nng_c_sys::nng_log_level::Type, _: nng_c_sys::nng_log_facility::Type, msg_id: *const core::ffi::c_char, msg: *const core::ffi::c_char) {
71        const NNG: &str = "NNG";
72
73        if msg.is_null() {
74            return;
75        }
76
77        let level = match level {
78            nng_c_sys::nng_log_level::NNG_LOG_DEBUG => log::Level::Trace,
79            nng_c_sys::nng_log_level::NNG_LOG_INFO => log::Level::Debug,
80            nng_c_sys::nng_log_level::NNG_LOG_NOTICE => log::Level::Info,
81            nng_c_sys::nng_log_level::NNG_LOG_WARN => log::Level::Warn,
82            nng_c_sys::nng_log_level::NNG_LOG_ERR => log::Level::Error,
83            _ => return,
84        };
85
86        let msg = match CStr::from_ptr(msg).to_str() {
87            Ok(msg) => msg,
88            Err(_) => return,
89        };
90
91        let nng_tag = if msg_id.is_null() {
92            NNG
93        } else {
94            match CStr::from_ptr(msg_id).to_str() {
95                Ok(msg) => msg,
96                Err(_) => NNG,
97            }
98        };
99
100        log::log!(level, "{}: {}", nng_tag, msg);
101    }
102
103    unsafe {
104        nng_log_set_level(level as _);
105        nng_log_set_logger(Some(nng_rust_log_logger));
106    }
107}
108
109#[cfg(feature = "tracing")]
110///Enables logging using [tracing](https://crates.io/crates/tracing) crate
111///
112///Requires feature `tracing`
113///
114///Note that messages are only logged if C strings are valid utf-8
115pub fn enable_tracing(level: Level) {
116    use core::ffi::CStr;
117
118    unsafe extern "C" fn nng_rust_tracing_logger(level: nng_c_sys::nng_log_level::Type, _: nng_c_sys::nng_log_facility::Type, msg_id: *const core::ffi::c_char, msg: *const core::ffi::c_char) {
119        const NNG: &str = "NNG";
120
121        if msg.is_null() {
122            return;
123        }
124
125        let msg = match CStr::from_ptr(msg).to_str() {
126            Ok(msg) => msg,
127            Err(_) => return,
128        };
129
130        let target = if msg_id.is_null() {
131            NNG
132        } else {
133            match CStr::from_ptr(msg_id).to_str() {
134                Ok(msg) => msg,
135                Err(_) => NNG,
136            }
137        };
138
139        match level {
140            nng_c_sys::nng_log_level::NNG_LOG_DEBUG => tracing::trace!(target, "{}", msg),
141            nng_c_sys::nng_log_level::NNG_LOG_INFO => tracing::debug!(target, "{}", msg),
142            nng_c_sys::nng_log_level::NNG_LOG_NOTICE => tracing::info!(target, "{}", msg),
143            nng_c_sys::nng_log_level::NNG_LOG_WARN => tracing::warn!(target, "{}", msg),
144            nng_c_sys::nng_log_level::NNG_LOG_ERR => tracing::error!(target, "{}", msg),
145            _ => (),
146        };
147    }
148
149    unsafe {
150        nng_log_set_level(level as _);
151        nng_log_set_logger(Some(nng_rust_tracing_logger));
152    }
153}