Creating a logger in a Rust library to be used on C++ side

I know loggers aren't recommended to be done this way ... in a library. But got this weird request from my CTO. He wants to use a Rust logger on C++ side.

I've tried a number of ways, mostly using a static Lazy<...>, but can't get this working. Tried the tracing crate and slog crate, also env_logger.

Rust C wrapper functions would be created to call info!, error!, etc ... from the C++ side.

If anyone has any helpful suggestions.

Can you show some code and/or be more specific with the problems you are facing?

1 Like

Code I sort of got working using in a simple C++ program. Although it only works with a Rust debug build.

 use once_cell::sync::OnceCell;
 use slog::{debug, error, info, o, warn, Drain, Logger};
 use slog_async;
 use slog_term;
 use std::ffi::CStr;
 use std::fs::OpenOptions;
 use std::os::raw::c_char;

 static LOGGER: OnceCell<Logger> = OnceCell::new();

 #[no_mangle]
 pub extern "C" fn log_init() {
     let _: &Logger = LOGGER.get_or_init(|| {
         let log_path = "/home/user/something.log";
         let file = OpenOptions::new()
             .create(true)
             .write(true)
             .truncate(true)
             .open(log_path)
             .unwrap();

         let decorator = slog_term::PlainDecorator::new(file);
         let drain = slog_term::FullFormat::new(decorator).build().fuse();
         let drain = slog_async::Async::new(drain).build().fuse();
         slog::Logger::root(drain, o!())
     });
 }

 #[no_mangle]
 pub extern "C" fn log_error(message: *const c_char) {
     unsafe {
         let raw = CStr::from_ptr(message);

         if let Ok(msg) = raw.to_str() {
             error!(LOGGER.get().unwrap(), "{}", msg);
         }
    }
}

Please be more specific about what you need help with. Are you asking why it doesn't work in release mode? Or something else?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.