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 次下载
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_async
是 use_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