Geal / rust-syslog

Send syslog messages from Rust
MIT License
109 stars 55 forks source link

UDP syslog example #76

Open khumps opened 1 year ago

khumps commented 1 year ago

I am currently trying to use the syslog crate to send messages to a remote syslog server over UDP.

My current instantiation is: syslog::udp(Formatter3164::default(), UnixStream::connect("/dev/log")?, (syslog_ip,514 as u16)); but this is failing because apparently local and server need to be the same type?

Is there any example code that could be provided on how one uses this to connect to a remote syslog server?

khumps commented 1 year ago

after more testing, I arrived at:

let mut logger = syslog::udp(formatter, "127.0.0.1:1234", "10.0.0.10:514").expect("failed to initialize syslog");
logger.alert("zpe-fixer logging initializing").expect("failed to send syslog message");

However this panics with:

thread 'main' panicked at 'failed to send syslog message: Error(Format, State { next_error: Some(Os { code: 22, kind: InvalidInput, message: "Invalid argument" }), backtrace: InternalBacktrace })', src/main.rs:48:56
xenago commented 1 year ago

When using 0.0.0.0:0 or :::0 as the local socket address, UDP syslogs seem to be sent successfully.


Initially I stumbled upon this SO post, it seemed like Ipv4Addr::UNSPECIFIED with the automatic port 0 would help:

It's not obvious, but if you bind the socket to (UNSPECIFIED, 0), then when you connect to a remote address the local address is set to the appropriate interface address. (Port 0 means to auto-allocate a port, just like an unbound socket in C.)

Turns out that 0.0.0.0 is equivalent to UNSPECIFIED in std::net::ToSocketAddrs

An IPv4 address representing an unspecified address: 0.0.0.0

So I tried connecting to a localhost and LAN UDP syslog server with that format, it worked both times:

let syslog_udp_config = fern::Dispatch::new().chain(formatter, "0.0.0.0:0", "127.0.0.1:514").expect("Unable to initialize syslog"));

(...)

let syslog_udp_config = fern::Dispatch::new().chain(formatter, "0.0.0.0:0", "192.168.1.234:514").expect("Unable to initialize syslog"));

It also worked with the IPv6 equivalent, :::0 which is probably an even better choice for future compatibility.