feat(shadowsocks-rust): logging support syslog (#2044)

This commit is contained in:
zonyitoo
2025-11-17 01:30:11 +08:00
parent 1cba24debf
commit 1db36a1c73
5 changed files with 119 additions and 17 deletions
Generated
+20 -8
View File
@@ -976,7 +976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -1541,7 +1541,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.5.10",
"socket2 0.6.1",
"system-configuration",
"tokio",
"tower-service",
@@ -2592,7 +2592,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls",
"socket2 0.5.10",
"socket2 0.6.1",
"thiserror 2.0.17",
"tokio",
"tracing",
@@ -2629,9 +2629,9 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.5.10",
"socket2 0.6.1",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -2904,7 +2904,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -3273,6 +3273,7 @@ dependencies = [
"shadowsocks-service",
"snmalloc-rs",
"sysexits",
"syslog-tracing",
"tcmalloc",
"thiserror 2.0.17",
"time",
@@ -3545,6 +3546,17 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf9154bb31a0b747e214520c60cb9a842df871bf6a5fea5be4352b59d6c432ab"
[[package]]
name = "syslog-tracing"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d349bc2df408b4bf656709a29643641cef7f1795d708f88b105c626a8f64f6e4"
dependencies = [
"libc",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "system-configuration"
version = "0.6.1"
@@ -3603,7 +3615,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -4274,7 +4286,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.61.2",
]
[[package]]
+1
View File
@@ -249,6 +249,7 @@ windows-service = { version = "0.8", optional = true }
[target.'cfg(unix)'.dependencies]
xdg = "3.0"
syslog-tracing = "0.3"
[target.'cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"))'.dependencies]
reqwest = { version = "0.12", features = [
+11
View File
@@ -913,6 +913,17 @@ Example configuration:
// Optional. If set, keeps the last N log files
"max_files": 5
}
},
{
// Configure a syslog writer, only supported on *nix system
"syslog": {
// `level` and `format` can also be set here, if not set, it will use the default values
// Optional. Set the "identity" when calling openlog(). Use current service name by default.
"identity": "identity_name",
// Optional. Set the "facility" when calling openlog(). 1 (user-level messages) by default. See RFC5424.
"facility": 1
}
}
]
},
+21
View File
@@ -198,6 +198,8 @@ pub struct LogFormatConfig {
pub enum LogWriterConfig {
Console(LogConsoleWriterConfig),
File(LogFileWriterConfig),
#[cfg(unix)]
Syslog(LogSyslogWriterConfig),
}
/// Console appender configuration for logging
@@ -269,6 +271,25 @@ impl From<LogRotation> for tracing_appender::rolling::Rotation {
}
}
/// File appender configuration for logging
#[cfg(all(feature = "logging", unix))]
#[derive(Deserialize, Debug, Clone)]
pub struct LogSyslogWriterConfig {
/// Level override
#[serde(default)]
pub level: Option<u32>,
/// Format override
#[serde(default)]
pub format: LogFormatConfigOverride,
/// syslog identity, process name by default
#[serde(default)]
pub identity: Option<String>,
/// Facility, 1 (USER) by default
#[serde(default)]
pub facility: Option<i32>,
}
/// Runtime mode (Tokio)
#[derive(Deserialize, Debug, Clone, Copy, Default, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
+66 -9
View File
@@ -1,18 +1,21 @@
//! Logging facilities with tracing
use std::io;
use std::io::IsTerminal;
use std::io::{self, IsTerminal};
use time::UtcOffset;
use time::format_description::well_known::Rfc3339;
#[cfg(unix)]
use syslog_tracing::Syslog;
use time::{UtcOffset, format_description::well_known::Rfc3339};
use tracing::level_filters::LevelFilter;
use tracing_appender::rolling::{InitError, RollingFileAppender};
use tracing_subscriber::fmt::MakeWriter;
use tracing_subscriber::fmt::time::OffsetTime;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{EnvFilter, Layer, Registry, fmt};
use tracing_subscriber::{
fmt::{MakeWriter, time::OffsetTime},
layer::SubscriberExt,
util::SubscriberInitExt,
{EnvFilter, Layer, Registry, fmt},
};
#[cfg(unix)]
use crate::config::LogSyslogWriterConfig;
use crate::config::{
LogConfig, LogConsoleWriterConfig, LogFileWriterConfig, LogFormatConfig, LogFormatConfigOverride, LogWriterConfig,
};
@@ -38,6 +41,8 @@ impl MakeLayer for LogWriterConfig {
match self {
LogWriterConfig::Console(console_config) => console_config.make_layer(bin_name, global),
LogWriterConfig::File(file_config) => file_config.make_layer(bin_name, global),
#[cfg(unix)]
LogWriterConfig::Syslog(syslog_config) => syslog_config.make_layer(bin_name, global),
}
}
}
@@ -63,6 +68,17 @@ impl MakeLayer for LogFileWriterConfig {
}
}
#[cfg(unix)]
impl MakeLayer for LogSyslogWriterConfig {
fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {
let level = self.level.unwrap_or(global.level);
let format = apply_override(&global.format, &self.format);
let syslog_writer = make_syslog_writer(bin_name, self);
make_fmt_layer(bin_name, level, &format, false, syslog_writer)
}
}
/// Boilerplate for configuring a `fmt::Layer` with `level` and `format` for different writers.
fn make_fmt_layer<W>(bin_name: &str, level: u32, format: &LogFormatConfig, ansi: bool, writer: W) -> BoxedLayer
where
@@ -162,3 +178,44 @@ fn apply_override(global: &LogFormatConfig, override_config: &LogFormatConfigOve
without_time: override_config.without_time.unwrap_or(global.without_time),
}
}
#[cfg(unix)]
fn make_syslog_writer(bin_name: &str, config: &LogSyslogWriterConfig) -> Syslog {
use std::ffi::CString;
use syslog_tracing::{Facility, Options};
let identity = config.identity.as_deref().unwrap_or(bin_name);
let facility = match config.facility {
None => Facility::default(),
Some(f) => match f {
1 => Facility::User,
2 => Facility::Mail,
3 => Facility::Daemon,
4 => Facility::Auth,
6 => Facility::Lpr,
7 => Facility::News,
8 => Facility::Uucp,
9 => Facility::Cron,
10 => Facility::AuthPriv,
16 => Facility::Local0,
17 => Facility::Local1,
18 => Facility::Local2,
19 => Facility::Local3,
20 => Facility::Local4,
21 => Facility::Local5,
22 => Facility::Local6,
23 => Facility::Local7,
_ => panic!("unsupported syslog facility: {}", f),
},
};
let options = Options::default();
let identity = CString::new(identity).expect("syslog identity contains null-byte ('\\0')");
let syslogger = match Syslog::new(identity, options, facility) {
Some(l) => l,
None => panic!("syslog is already initialized"),
};
syslogger
}