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?