emabee / flexi_logger

A flexible logger for rust programs that can write to stderr, stdout, and/or to log files
Apache License 2.0
315 stars 55 forks source link

Custom formatter for syslog not working? #168

Closed krims0n32 closed 2 months ago

krims0n32 commented 3 months ago

Hello, thanks for your work on this library. I have a question about formatting when using a Syslog writer, it seems my formatting method is not being used. Considering the code below, my custom formatter is applied to the console output, but not to the syslog output. The predefined formatters also do not seem to work. Although the syslog entry do contain timestamp, hostname and such, I need the message itself to be more detailed. Am I doing something wrong here?

pub fn my_own_format(
    w: &mut dyn std::io::Write,
    now: &mut DeferredNow,
    record: &Record,
) -> Result<(), std::io::Error> {
    let level = record.level();
    write!(
        w,
        "{} [Thread {}] Severity {}, Message: {}",
        now.format(TS_DASHES_BLANK_COLONS_DOT_BLANK),
        thread::current().name().unwrap_or("<unnamed>"),
        record.level(),
        &record.args()
    )
}

pub fn setup() {
    let syslog_logger = Syslog::try_udp(
        SocketAddr::from(([0, 0, 0, 0], 0)),
        format!(
            "{}:{}",
            env::var("GRAYLOG_SERVICE").expect("GRAYLOG_SERVICE is not set."),
            env::var("GRAYLOG_SYSLOG_PORT").expect("GRAYLOG_SYSLOG_PORT is not set."),
        )
        .to_socket_addrs()
        .expect("Invalid graylog service and/or port specified.")
        .next()
        .expect("Invalid graylog service and/or port specified."),
    )
    .expect("Unable to connect to graylog.");

    let syslog_writer = SyslogWriter::try_new(
        SyslogFacility::LocalUse0,
        None,
        LevelFilter::Debug,
        "proxy".into(),
        syslog_logger,
    )
    .expect("Error setting up syslog writer.");

    Logger::try_with_env_or_str("debug")
        .expect("LogSpecification String has errors")
        // .print_message()
        .log_to_writer(syslog_writer)
        .format_for_writer(my_own_format)
        .duplicate_to_stderr(flexi_logger::Duplicate::All)
        .format_for_stderr(my_own_format)
        .start()
        .unwrap_or_else(|e| panic!("Logger initialization failed with {}", e));
}
emabee commented 3 months ago

SyslogWriter comes with two factory methods: try_new() and try_new_bsd(). Both use different, but hardcoded formats, corresponding to RFC5424 or RFC3164, respectively.

I'm really not an expert for syslog. Do you think it makes sense to allow a free customising of the format?

krims0n32 commented 3 months ago

I have tried both methods, but I think it would be nice to be able to format the log message itself using a formatter. That way you can add things like thread id, target, etc to it, similar to logging to a file or console.

emabee commented 3 months ago

That makes sense, I see...

emabee commented 2 months ago

Realized with 0.29.0

krims0n32 commented 2 months ago

Thanks, works perfectly!