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 = "useasync" for asynchronious code - feature = "usesync" for synchronious code - feature = "usesyncqueue" 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 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.

Usage:

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

Supports

Contributors

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

Example

```rust

[macrouse] extern crate lazystatic;

[macrouse] extern crate syslogrs;

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

lazystatic! { static ref SYNCSYSLOG: UnsafeReadOnlyCell = unsafe { UnsafeReadOnlyCell::newuninitialized("syslogsync") }; }

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

fn main() { let syslog = Syslog::openlog( Some("example"), LogStat::LOGCONS | LogStat::LOGNDELAY | LogStat::LOGPID, LogFacility::LOGDAEMON ).unwrap();

unsafe { SYNC_SYSLOG.init(syslog) };

logdebug!("test message!");

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

return;

} ```

```rust

[macrouse] extern crate lazystatic;

[macrouse] extern crate syslogrs;

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

[cfg(feature = "use_sync")]

use syslogrs::sysync::{Syslog, SyslogStd};

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

lazystatic! { static ref SYSLOG: Syslog = Syslog::openlog( Some("example"), LogStat::LOGCONS | LogStat::LOGNDELAY | LogStat::LOGPID, LogFacility::LOG_DAEMON ).unwrap(); }

macrorules! logdebug { ($($arg:tt)*) => ( SYSLOG.syslog(Priority::LOGDEBUG, 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:

| usesync (sys mutex) |usesync (atomicblock) | usesyncqueue | useasync | |---------- |------------------------|----------------|--------------| |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 |