16 个版本

0.6.0 2024 年 2 月 5 日
0.5.1 2023 年 12 月 9 日
0.5.0 2023 年 4 月 2 日
0.4.3 2023 年 2 月 14 日
0.2.1 2021 年 6 月 12 日

#238异步

每月 28 次下载

MPL-2.0 许可证

170KB
3.5K SLoC

syslog-rs

此 crate 仍在开发中。版本 0.6

类似于系统库中设计的 glibc/libc syslog 实现。API 几乎与 libc/glibc 中的 API 兼容。

可用功能

  • feature = "use_async" 用于异步代码
  • feature = "use_sync" 用于同步代码
  • feature = "use_sync_queue" 用于同步和异步处理
  • feature = "build_with_net" 启用 TCP/UDP 和扩展接口

use_sync 的行为类似于 libc/glibc 的函数 syslog(), openlog()...

use_sync_queue 与 libc/glibc 有相同的 API,但在某些方面有所不同。此外,它还会启动一个工作线程,该线程将队列中的消息发送到 syslog。

use_asyncuse_sync 的异步实现。未测试,可能需要进一步开发。

所有 3 个功能都可以简单使用。

可用可调参数

  • feature = "udp_truncate_1024_bytes"
  • feature = "udp_truncate_1440_bytes" 默认

以上是针对 RFC5424 的,它控制通过 UDP 协议转发的 syslog 消息长度。

  • feature = "tcp_truncate_1024_bytes"
  • feature = "tcp_truncate_2048_bytes" 默认
  • feature = "tcp_truncate_4096_bytes"
  • feature = "tcp_truncate_max_bytes"

以上是针对 RFC5424 的,它控制通过 TCP 协议转发的 syslog 消息长度。

  • feature = "dgram_sysctl_failure_panic"

以上是仅针对 *BSD 系统的,它控制 sysctl 错误处理的行为。如果启用,当 sysctl 访问失败时,crate 将引发恐慌。默认未启用。

!!! use_async 使用 tokio mutex 实现同步。在大型异步队列中,当许多任务被启动时,syslog 成为了性能瓶颈,因为 syslog 服务器可能很忙,syslog() 很慢,并且调用 syslog() 将锁定其他任务,直到锁被释放。可能对于每个 tokio 线程有一个单独的 syslog 实例是个好主意。

使用方法

对于定制:syslog-rs = {version = "0.6", default-features = false, features = ["use_sync"]}

支持

  • GNU/Linux RFC3164(默认为 UTF-8)
  • *BSD 和 OSX RFC5424(默认为 BOM UTF-8)

贡献者

按 Relkom s.r.o 排序(© 2021)

开发者:Aleksandr Morozov

示例

#[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;
}

基准测试

测试会启动 2 个线程和 1 个主线程。所有 3 个线程都向 syslog 发送消息。表中的时间测量为近似值。

Debug 模式下 syslog_*.rs 文件中的测试结果(AMD Ryzen 5 7600X 6 核处理器)

use_sync(sys 线程锁) use_sync_queue use_async
主线程:81.101µs 主线程:12.74µs 主线程:67.549µs
t1:91.02µs t2:1.77µs t2:44.779µs
t2:129.919µs t1:4.49µs t1:5.76µs
t1:31.32µs t2:630ns t1:7.74µs
t2:9.09µs t1:320ns t2:4.58µs
t1:10.82µs t2:1.13µs t2:13.77µs
t2:7.23µs t1:280ns t1:5.62µs
t1:11.68µs t1:950ns t1:6.55µs
t2:7.239µs t2:750ns t2:4.47µs
t1:11.57µs t1:720ns t2:7.22µs
t2:6.61µs t2:700ns t1:4.43µs

依赖项

~5–14MB
~164K SLoC