Looking for some syslog help

I've been trying to write a macro to write a message to syslog that includes the file name, line number and a severity that can be called from anywhere including from different threads. I've tried several different ways but I always end up with a compiler error. This latest attempt says that Logger does not implement the DerefMut trait. Other attempts say it does not implement the Copy trait either. Is there any workaround for this?
I've tried using Once and Arc and here's some code using lazy_static:

use std::{process};
use syslog::{Facility, Formatter3164, Logger, LoggerBackend};
#[macro_use]
extern crate lazy_static;

macro_rules! my_log {
    ($logger: ident, $log_level: expr, $log_msg: expr) => {
        match $logger.warning(format!("{}: {},{}: {}", $log_level.to_string(), file!(), line!(), $log_msg)) {
            Err(error) => panic!("Problem writing syslog: {:?}", error),
            _ => (),
        };
    }
}

macro_rules! my_debug_log {
    ($log_msg: expr) => {
        my_log!(LOGGER, "DEBUG", $log_msg);
    }
}

macro_rules! my_error_log {
    ($log_msg: expr) => {
        my_log!(LOGGER, "ERROR", $log_msg);
    }
}

fn init_logger() -> Logger<LoggerBackend, Formatter3164> {
    let formatter = Formatter3164 {
        facility: Facility::LOG_USER,
        hostname: None,
        process:  "thishost".to_string(),
        pid:      process::id as i32,
    };
    syslog::unix(formatter).expect("could not connect to syslog")
}

lazy_static!(
    static ref LOGGER: Logger<LoggerBackend, Formatter3164> = init_logger();
);

fn main() {
    my_debug_log!("Debug log msg");
    my_error_log!("Error log msg");
}

Use ``` for the code that you're sharing, not the single quotes (').

Note to OP: You can edit your original post by clicking on the pencil icon that appears to the author under any post that they authored. Please do so and correct your formatting as a courtesy to future readers of this thread.

Doesn't seem to make a difference.

You're still using single backticks (`) instead of triple ones (```).

Ah... I read that as a backtick between two single quotes. I need to pay more attention but in my defense I'm doing this from a phone. Anyway, fixed now.

The reason you're running into trouble is that the syslog crate requires mutable access to the logger to use it, and gaining mutable access to globals is not possible without unsafe or a locking mechanism such as a mutex.

Thanks, Alice.
I finally got it! I wrapped the static ref in a Mutex and changed the macros to use LOGGER.lock().unwrap().

macro_rules! my_error_log {
    ($log_msg: expr) => {
        my_log!(LOGGER.lock().unwrap(), "ERROR", $log_msg);
    }   
}

fn init_logger() -> Mutex<Logger<LoggerBackend, Formatter3164>> {
    let formatter = Formatter3164 {
        facility: Facility::LOG_USER,
        hostname: None,
        process:  "thishost".to_string(),
        pid:      process::id as i32,
    };  
    Mutex::new(syslog::unix(formatter).expect("could not connect to syslog"))
}

lazy_static!(
    static ref LOGGER: Mutex<Logger<LoggerBackend, Formatter3164>> = init_logger();
);

I knew that my LOGGER was mutable but I thought that the lazy_static was designed to take of that.

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.