syslog-rs 0.2.1

A native Rust implementation of the glibc/libc syslog.
Documentation

syslog-rs

This crate is still under development. v 0.2.1

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

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.

All 3 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.

Usage:

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

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)
  • Remi a 3rd party developer

Example

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

use std::sync::Arc;
use std::thread;
use std::time::{Instant, Duration};

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


lazy_static! {
    static ref SYSLOG: Arc<Syslog> = 
        Arc::new(
            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)*))
    )
}



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 use_sync_queue use_async
main: 102.373µs t1: 6.681µs main: 798.062µs
t1: 57.026µs t2: 14.692µs t2: 66.082µs
t2: 111.32µs t1: 728ns t1: 38.786µs
t1: 108.239µs main: 1.967µs t1: 58.564µs
t2: 101.264µs t1: 2.222µs t2: 38.279µs
t1: 269.168µs t2: 758ns t2: 70.505µs
t2: 95.979µs t1: 632ns t1: 38.5µs
t1: 38.424µs t2: 1.097µs t1: 67.678µs
t1: 28.495µs t1: 487ns t2: 42.12µs
t2: 62.484µs t2: 1.381µs t2: 48.587µs
t2: 46.874µs t2: 2.317µs t1: 37.847µs
------ ------- ---------
main: 80.361µs t2: 9.708µs main: 90.833µs
t1: 71.085µs main: 2.987µs t2: 105.825µs
t1: 41.886µs t1: 36.827µs t1: 39.842µs
t1: 26.027µs t2: 7.537µs t1: 214.533µs
t1: 38.499µs t1: 1.313µs t2: 38.205µs
t1: 25.682µs t2: 801ns t2: 55.495µs
t2: 51.021µs t1: 499ns t1: 81.401µs
t2: 51.115µs t1: 7.228µs t1: 65.377µs
t2: 37.879µs t2: 1.194µs t2: 55.771µs
t2: 27.949µs t1: 935ns t2: 41.615µs
t2: 50.807µs t2: 628ns t1: 38.411µs