libcamera/
logging.rs

1use std::{
2    ffi::{CStr, CString},
3    io,
4};
5
6use libcamera_sys::*;
7
8use crate::utils::handle_result;
9
10/// Log destination type.
11#[derive(Copy, Clone, Debug)]
12pub enum LoggingTarget {
13    None,
14    Syslog,
15    File,
16    Stream,
17}
18
19impl From<LoggingTarget> for libcamera_logging_target_t {
20    fn from(value: LoggingTarget) -> Self {
21        match value {
22            LoggingTarget::None => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_NONE,
23            LoggingTarget::Syslog => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_SYSLOG,
24            LoggingTarget::File => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_FILE,
25            LoggingTarget::Stream => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_STREAM,
26        }
27    }
28}
29
30#[derive(Copy, Clone, Debug)]
31pub enum LoggingLevel {
32    Debug,
33    Info,
34    Warn,
35    Error,
36    Fatal,
37}
38
39impl From<LoggingLevel> for &'static CStr {
40    fn from(value: LoggingLevel) -> Self {
41        match value {
42            LoggingLevel::Debug => c"DEBUG",
43            LoggingLevel::Info => c"INFO",
44            LoggingLevel::Warn => c"WARN",
45            LoggingLevel::Error => c"ERROR",
46            LoggingLevel::Fatal => c"FATAL",
47        }
48    }
49}
50
51#[derive(Copy, Clone, Debug)]
52pub enum LoggingStream {
53    StdOut,
54    StdErr,
55    Custom(*mut core::ffi::c_void),
56}
57
58impl From<LoggingStream> for libcamera_logging_stream_t {
59    fn from(value: LoggingStream) -> Self {
60        match value {
61            LoggingStream::StdOut => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_STDOUT,
62            LoggingStream::StdErr => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_STDERR,
63            LoggingStream::Custom(_) => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_CUSTOM,
64        }
65    }
66}
67
68/// Direct logging to a file.
69pub fn log_set_file(file: &str, color: bool) -> io::Result<()> {
70    let file = CString::new(file).expect("file contains null byte");
71    let ret = unsafe { libcamera_log_set_file(file.as_ptr(), color) };
72    handle_result(ret)
73}
74
75/// Direct logging to a stream.
76pub fn log_set_stream(stream: LoggingStream, color: bool) -> io::Result<()> {
77    let ret = unsafe {
78        match stream {
79            LoggingStream::Custom(ptr) => libcamera_log_set_custom_stream(ptr, color),
80            _ => libcamera_log_set_stream(stream.into(), color),
81        }
82    };
83    handle_result(ret)
84}
85
86/// Set the logging target.
87pub fn log_set_target(target: LoggingTarget) -> io::Result<()> {
88    let ret = unsafe { libcamera_log_set_target(target.into()) };
89    handle_result(ret)
90}
91
92/// Convenience: direct logging to stderr and set a default level for the "Camera" category.
93pub fn configure_stderr(category: &str, level: LoggingLevel, color: bool) -> io::Result<()> {
94    log_set_stream(LoggingStream::StdErr, color)?;
95    let cm = crate::camera_manager::CameraManager::new()?;
96    cm.log_set_level(category, level);
97    Ok(())
98}
99
100/// Convenience: configure logging target and stream without creating a CameraManager.
101pub fn configure_logging(target: LoggingTarget, stream: Option<LoggingStream>, color: bool) -> io::Result<()> {
102    if let Some(s) = stream {
103        log_set_stream(s, color)?;
104        log_set_target(LoggingTarget::Stream)?;
105    } else {
106        log_set_target(target)?;
107    }
108    Ok(())
109}
110
111/// Convenience: direct logging to stdout and set a default level for the given category.
112pub fn configure_stdout(category: &str, level: LoggingLevel, color: bool) -> io::Result<()> {
113    log_set_stream(LoggingStream::StdOut, color)?;
114    set_category_level(category, level);
115    Ok(())
116}
117
118/// Set the log level for a category without constructing a CameraManager.
119pub fn set_category_level(category: &str, level: LoggingLevel) {
120    let category = CString::new(category).expect("category contains null byte");
121    let level: &CStr = level.into();
122    unsafe { libcamera_log_set_level(category.as_ptr(), level.as_ptr()) };
123}