rustls_ffi/
log.rs

1use libc::c_void;
2use log::Level;
3
4#[cfg(not(feature = "no_log_capture"))]
5use crate::userdata::log_callback_get;
6
7use crate::rslice::rustls_str;
8
9#[cfg(not(feature = "no_log_capture"))]
10struct Logger {}
11
12#[cfg(not(feature = "no_log_capture"))]
13impl log::Log for Logger {
14    fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
15        true
16    }
17    fn log(&self, record: &log::Record<'_>) {
18        if let Ok((Some(cb), userdata)) = log_callback_get() {
19            let message = format!("{} {}", record.target(), record.args());
20            if let Ok(message) = message.as_str().try_into() {
21                unsafe {
22                    cb(
23                        userdata,
24                        &rustls_log_params {
25                            level: record.level() as rustls_log_level,
26                            message,
27                        },
28                    );
29                }
30            }
31        }
32    }
33    fn flush(&self) {}
34}
35
36#[cfg(feature = "no_log_capture")]
37pub(crate) fn ensure_log_registered() {}
38
39#[cfg(not(feature = "no_log_capture"))]
40pub(crate) fn ensure_log_registered() {
41    log::set_logger(&Logger {}).ok();
42    log::set_max_level(log::LevelFilter::Debug)
43}
44
45/// Numeric representation of a log level.
46///
47/// Passed as a field of the `rustls_log_params` passed to a log callback.
48/// Use with `rustls_log_level_str` to convert to a string label.
49pub type rustls_log_level = usize;
50
51/// Return a rustls_str containing the stringified version of a log level.
52#[no_mangle]
53pub extern "C" fn rustls_log_level_str(level: rustls_log_level) -> rustls_str<'static> {
54    let s = match level {
55        1 => Level::Error.as_str(),
56        2 => Level::Warn.as_str(),
57        3 => Level::Info.as_str(),
58        4 => Level::Debug.as_str(),
59        5 => Level::Trace.as_str(),
60        _ => "INVALID",
61    };
62    rustls_str::from_str_unchecked(s)
63}
64
65/// Parameter structure passed to a `rustls_log_callback`.
66#[repr(C)]
67pub struct rustls_log_params<'a> {
68    /// The log level the message was logged at.
69    pub level: rustls_log_level,
70    /// The message that was logged.
71    pub message: rustls_str<'a>,
72}
73
74/// A callback that is invoked for messages logged by rustls.
75#[allow(non_camel_case_types)]
76pub type rustls_log_callback =
77    Option<unsafe extern "C" fn(userdata: *mut c_void, params: *const rustls_log_params)>;