syslog-rs 0.4.2

A native Rust implementation of the glibc/libc syslog.
Documentation
syslog-rs-0.4.2 has been yanked.

syslog-rs

This crate is still under development. v 0.4

An implementation of the syslog from glibc/libc like it was designed in in both system libraries. The API is almost compatible with what is in libc/glibc.

Available features:

  • feature = "use_async" for asynchronious code
  • feature = "use_sync" for synchronious code
  • feature = "use_sync_queue" for synchronious with async processing
  • feature = "use_atomic_block" an alternative mutex to std::sync::mutex

The use_sync is acting like the libc's/glibc's functions syslog(), openlog()...

The use_sync_queue has the same API as libc/glibc but is different in some ways. Also, it spawns a worker thread which sends messages from the queue to syslog.

The use_async is async realization of the use_sync. Untested, probably requires further dev.

The use_atomic_block is a mutex which uses atomics and crossbeam::utils::Backoff instead of std::sync::Mutex

All 4 features can be used simpltaniously.

!!! use_async is using tokio mutex to achieve the synchronization. On the large async queues, when many tasks are spawned, the syslog becomes a performace bottleneck because syslog server may be busy, and syslog() is slow, and calling syslog() will lock other tasks until the lock will be released. Maybe it is good idea to have for example for each tokio thread a sibgle instance of the syslog.

!!! use_atomic_block is appliciable only for use_sync. The rest features: use_sync_queue, use_async uses either build in synchronization or Tokio mutex.

Usage:

syslog-rs = {version = "0.4", default-features = false, features = ["use_sync", "use_atomic_block"]}

Supports

  • GNU/Linux RFC3164 (UTF-8 by default)
  • *BSD and OSX RFC5424 (BOM UTF-8 by default)

Contributors

Ordered by Relkom s.r.o (c) 2021

  • Aleksandr Morozov (Relkom s.r.o developer)

Example

#[macro_use] extern crate lazy_static;
#[macro_use] extern crate syslog_rs;

use std::thread;
use std::time::Duration;
use syslog_rs::sy_sync::{Syslog, SyslogStd};
use syslog_rs::{LogStat, LogFacility, Priority};


lazy_static! {
    static ref SYNC_SYSLOG: UnsafeReadOnlyCell<Syslog> = 
        unsafe { UnsafeReadOnlyCell::new_uninitialized("syslog_sync") };
}

macro_rules! logdebug 
{
    ($($arg:tt)*) => (
        SYSLOG.syslog(Priority::LOG_DEBUG, format!($($arg)*))
    )
}



fn main()
{
    let syslog = 
        Syslog::openlog(
            Some("example"), 
            LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
            LogFacility::LOG_DAEMON
        ).unwrap();

    unsafe { SYNC_SYSLOG.init(syslog) };
    
    logdebug!("test message!");

    thread::sleep(Duration::from_micros(10));

    return;
}
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate syslog_rs;

use std::thread;
use std::time::Duration;

#[cfg(feature = "use_sync")]
use syslog_rs::sy_sync::{Syslog, SyslogStd};

use syslog_rs::{LogStat, LogFacility, Priority};

lazy_static! {
    static ref SYSLOG: Syslog = 
        Syslog::openlog(
            Some("example"), 
            LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
            LogFacility::LOG_DAEMON
        ).unwrap();
}

macro_rules! logdebug 
{
    ($($arg:tt)*) => (
        SYSLOG.syslog(Priority::LOG_DEBUG, format!($($arg)*))
    )
}

pub fn main()
{
    logdebug!("test message!");

    thread::sleep(Duration::from_micros(10));

    return;
}

Benchmarking

The test spawns 2 threads and one main thread. All 3 threads are sending messages to syslog. The time measurment in the tables are approximations.

Results of the tests in syslog_*.rs files in Debug mode:

use_sync (sys mutex) use_sync (atomic_block) use_sync_queue use_async
main: 122.101µs main: 88.165µs t2: 4.022µs main: 90.126µs
t2: 35.282µs t2: 28.569µs t2: 8.743µs t2: 67.398µs
t2: 31.308µs t2: 29.397µs t2: 1.238µs t1: 35.32µs
t2: 20.717µs t2: 20.491µs t2: 10.026µs t1: 58.247µs
t2: 37.338µs t2: 19.135µs t2: 1.584µs t2: 39.547µs
t2: 21.684µs t2: 18.612µs t1: 10.609µs t2: 56.621µs
t1: 918.718µs t1: 124.709µs t1: 8.966µs t1: 34.358µs
t1: 40.362µs t1: 104.634µs t1: 981ns t1: 38.329µs
t1: 25.754µs t1: 31.749µs t1: 893ns t2: 36.973µs
t1: 26.845µs t1: 32.285µs t1: 10.45µs t2: 59.271µs
t1: 24.335µs t1: 24.602µs main: 4.301µs t1: 35.053µs