syslog_rs/
lib.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * The syslog-rs crate can be redistributed and/or modified
7 * under the terms of either of the following licenses:
8 *
9 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
10 *
11 *   2. The MIT License (MIT)
12 *                     
13 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
14 */
15
16//! syslog-rs
17//! 
18//!  <img src="https://cdn.4neko.org/syslog_logo.webp" width="280"/> <img src="https://cdn.4neko.org/source_avail.webp" width="280"/> <img src="https://cdn.4neko.org/mit_mpl_eupl_2.webp" width="280"/>
19//! 
20//! An implementation of the syslog from glibc/libc like it was designed in
21//! in both system libraries. The API is almost compatible with what is in
22//! libc/glibc.
23//! 
24//! Also supports windows Event Log and/or remote syslog server.
25//! 
26//! ## Supports
27//! 
28//! * GNU/Linux RFC3164 (UTF-8 by default)
29//! * *BSD and OSX RFC5424 (BOM UTF-8 by default) (including msgid and parametes).
30//! * Windows Event Log via `WindowsEvent` provider and `RFC3164`/`RFC5424` via network or file.
31//! * Tokio async
32//! * Smol async
33//! * TLS over TCP syslog server connection
34//! * TCP/UDP syslog server connection
35//! * Local file writer
36//! 
37//! Directories:
38//! * a_sync - all async code
39//! * formatters - syslog message formatter.
40//! * sync - all sync code
41//! * src - all common code for both sync and async.
42//! 
43//! Features: 
44//! * feature = `build_with_thread_local` enables the lockless syslog client for single threaded or `thread_local` instances.
45//! * feature = "build_sync"  a base feature which enables all SYNC code. Just enabling the `use_sync`
46//!      would enable only basic SharedSyslog.
47//! * feature = "build_async_tokio" a Tokio based async IO. Includes the tokio and tokio-rustls deps.
48//! * feature = "build_async_smol" for synchronious with async processing (use syslog_rs::sy_async_queue::{Syslog};)
49//! * feature = "build_async_interface" for asynchronious interface only without any realisations.
50//! * feature = "build_with_queue" a Smol based async IO. Includes the smol and futures-rustls dep.
51//!     moves the syslog client to separate thread and by default uses 
52//!     crossbeam-channel to receive messages.
53//!     Depending on which async procvider is selected, the channel realization 
54//!     will be switched suring compilation. In this case, an async code can be 
55//!     attached to the sync queue which allows to write to the same syslog
56//!     connection with the same setup.
57//! * feature = "build_ext_net" adds the networking support! (TCP, UDP)
58//! * feature = "build_ext_tls" adds the TLS support over network (TCP).
59//! * feature = "build_ext_file" writing directly to file.
60//! 
61//! --
62//! * feature = "udp_truncate_1024_bytes" - Forces truncation of the (whole) syslog message to 1024
63//! * feature = udp_truncate_1440_bytes - Forces truncation of the (whole) syslog message to 1440
64//! * feature = tcp_truncate_1024_bytes - Forces truncation of the (whole) syslog message to 1024
65//! * feature = tcp_truncate_2048_bytes - Forces truncation of the (whole) syslog message to 2048 
66//! * feature = tcp_truncate_4096_bytes - Forces truncation of the (whole) syslog message to 4096
67//! * feature = tcp_truncate_max_bytes - Forces truncation of the (whole) syslog message to 8192 (max)
68//! * feature = dgram_sysctl_failure_panic - BSD only! By default, if crate fails to obtain a sysctl net.local.dgram.maxdgram, 
69//!     it returns a default value 2048. If this feature is enabled, then it will panic.
70//! 
71//! `build_async_tokio` and `build_async_smol` cannot be used together.
72//! 
73//! `build_with_queue` behaves differently if enabled ine of the async providers.
74//! 
75//! **For mor info, please see README.md!**
76//! 
77//! # Usage Example
78//! 
79//! syslog-rs = {version = "6.4", default-features = false, features = ["build_sync", "build_ext_net", "udp_truncate_1440_bytes"]}
80//! 
81//! By default, the following features are enabled: `build_sync`, `truncate_default`
82//! 
83//! ```ignore
84//! use std::{sync::LazyLock, thread};
85//! use std::time::Duration;
86//! 
87//! use syslog_rs::formatters::DefaultSyslogFormatter;
88//! use syslog_rs::{SyslogApi, SyncSyslog};
89//! use syslog_rs::{LogFacility, LogStat, Priority, SyslogLocal};
90//! 
91//! pub static SYSLOG: LazyLock<SyncSyslog> = LazyLock::new(|| 
92//!     {
93//!         SyncSyslog::openlog(
94//!             Some("example"), 
95//!             LogStat::LOG_CONS | LogStat::LOG_PID, 
96//!             LogFacility::LOG_DAEMON, SyslogLocal::new()
97//!         )
98//!         .unwrap()
99//!     }
100//! );
101//! 
102//! pub static SYSLOG2: LazyLock<SyncSyslog<DefaultSyslogFormatter, SyslogLocal>> = LazyLock::new(|| 
103//!     {
104//!         SyncSyslog
105//!             ::<_, _>
106//!             ::openlog_with(
107//!             None, 
108//!             LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
109//!             LogFacility::LOG_DAEMON, SyslogLocal::new()
110//!         )
111//!         .unwrap()
112//!     }
113//! );
114//! 
115//! pub static SYSLOG3: LazyLock<SyncSyslog<DefaultSyslogFormatter, SyslogLocal>> = LazyLock::new(|| 
116//!     {
117//!         SyncSyslog
118//!             ::<_, _>
119//!             ::openlog_with(
120//!                 None, 
121//!                 LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
122//!                 LogFacility::LOG_DAEMON, SyslogLocal::new()
123//!             )
124//!             .unwrap()
125//!     }
126//! );
127//! 
128//! macro_rules! logdebug 
129//! {
130//!     ($($arg:tt)*) => (
131//!         SYSLOG.syslog(Priority::LOG_DEBUG, format!($($arg)*).into())
132//!     )
133//! }
134//! 
135//! macro_rules! logdebug2 
136//! {
137//!     ($($arg:tt)*) => (
138//!         SYSLOG2.syslog(Priority::LOG_DEBUG, format!($($arg)*).into())
139//!     )
140//! }
141//! 
142//! pub fn main()
143//! {
144//!     logdebug2!("test program name!");
145//! 
146//! 
147//!     logdebug!("test message1!");
148//! 
149//!     SYSLOG.change_identity(Some("example2")).unwrap();
150//! 
151//!     logdebug!("test message from new ident");
152//! 
153//!     let new_syslog = 
154//!         SyncSyslog
155//!             ::<DefaultSyslogFormatter, SyslogLocal>
156//!             ::openlog_with(
157//!                 None, 
158//!                 LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
159//!                 LogFacility::LOG_DAEMON, SyslogLocal::new()
160//!             )
161//!             .unwrap();
162//! 
163//!     let c_new_syslog = new_syslog.clone();
164//!     let thread_hndl = 
165//!         std::thread::spawn(move || 
166//!             {
167//!                 logdebug!("message from thread 1");
168//!                 std::thread::sleep(Duration::from_nanos(1000));
169//!                 logdebug!("message from thread 2");
170//!                 std::thread::sleep(Duration::from_nanos(1000));
171//!                 logdebug!("message from thread 3");
172//!                 std::thread::sleep(Duration::from_nanos(1000));
173//!                 logdebug!("message from thread 4");
174//! 
175//!                 c_new_syslog.syslog(Priority::LOG_DEBUG, "test".into());
176//!             }
177//!         );
178//! 
179//!     let _ = thread_hndl.join();
180//! 
181//!     logdebug!("joined");
182//!     thread::sleep(Duration::from_micros(10));
183//! 
184//!     return;
185//! }
186//! ```
187//! 
188//! ```ignore
189//! use syslog_rs::sy_async::AsyncSyslog;
190//! use tokio::sync::OnceCell;
191//! use tokio::time::{Duration, sleep};
192//! 
193//! use syslog_rs::{LogFacility, LogStat, Priority, SyslogLocal};
194//! 
195//! 
196//! pub static SYSLOG: OnceCell<AsyncSyslog> = OnceCell::const_new();
197//! 
198//! 
199//! 
200//! 
201//! macro_rules! logdebug 
202//! {
203//!     ($($arg:tt)*) => (
204//!         SYSLOG.get().unwrap().syslog(Priority::LOG_DEBUG, format!($($arg)*)).await
205//!     )
206//! }
207//! 
208//! #[tokio::main]
209//! async fn main()
210//! {
211//!     let syslog =
212//!         AsyncSyslog::openlog(
213//!                 Some("example"), 
214//!                 LogStat::LOG_CONS | LogStat::LOG_NDELAY | LogStat::LOG_PID, 
215//!                 LogFacility::LOG_DAEMON,
216//!                 SyslogLocal::new()
217//!             )
218//!             .await
219//!             .unwrap();
220//! 
221//! 
222//!     SYSLOG.get_or_init(|| async { syslog }).await;
223//! 
224//! 
225//!     logdebug!("test message async start!");
226//!     
227//!     SYSLOG.get().unwrap().vsyslog(Priority::LOG_DEBUG, "test 2").await;
228//! 
229//!     sleep(Duration::from_micros(10)).await;
230//! 
231//!     SYSLOG.get().unwrap().change_identity("new_identity").await.unwrap();
232//! 
233//!     logdebug!("test message new identity!");
234//! 
235//!     sleep(Duration::from_micros(10)).await;
236//! 
237//!     logdebug!("test 123!");
238//!     logdebug!("test 123123! end ");
239//!     return;
240//! }
241//! 
242//! ```
243
244// make sure that the smol and tokio are not used together.
245#[cfg(all(feature = "build_async_tokio", feature = "build_async_smol"))]
246compile_error!("use_async_tokio and use_async_smol can not be used at the same time");
247
248// make sure that the build_async_interface and either async_embedded are not used together.
249#[cfg(all(feature = "build_async_interface", feature = "async_embedded"))]
250compile_error!("build_async_interface and either tokio/smol can not be used at the same time");
251
252//-- REEXPORT --
253#[macro_use] 
254extern crate bitflags;
255pub extern crate chrono;
256extern crate socket2;
257
258extern crate instance_copy_on_write;
259
260#[cfg(target_family = "unix")]
261pub extern crate nix;
262
263/// winDAws crp...
264#[cfg(target_family = "windows")]
265pub extern crate windows;
266
267
268// -- TLS --
269
270#[cfg(all(feature = "build_sync", feature = "build_ext_tls"))]
271extern crate rustls;
272
273#[cfg(all(feature = "build_async_tokio", feature = "build_ext_tls"))]
274extern crate tokio_rustls;
275
276#[cfg(all(feature = "build_async_smol", feature = "build_ext_tls"))]
277extern crate futures_rustls;
278
279// -- ASYNC --
280
281#[cfg(feature = "build_async_tokio")]
282extern crate tokio;
283
284#[cfg(feature = "build_async_smol")]
285extern crate smol;
286
287// -- SYNC --
288#[cfg(feature = "build_with_queue")]
289extern crate crossbeam_channel;
290
291#[cfg(feature = "build_sync")]
292extern crate crossbeam_utils;
293
294/// A sync syslog realization including shared and queued syslog client.
295#[cfg(feature = "build_sync")]
296pub mod sync;
297
298/// An async interface and/or realisations. The main async syslog struct is located there.
299#[cfg(feature = "async_enabled")]
300pub mod a_sync;
301
302/// A message formatters i.e RFC5424 and other. Also a message formatter interface.
303pub mod formatters;
304
305pub mod syslog_provider;
306
307/// A syslog destnation. i.e local, remote, remote TLS, local file. Needed to initialize the 
308/// (both sync and async) instances.
309pub use syslog_provider::*;
310
311/// A common things for the sockets managment.
312pub mod socket;
313
314/// A common code which holds all flags and macroses.
315#[macro_use] 
316pub mod common;
317
318/// Unified error interface.
319#[macro_use] 
320pub mod error;
321
322
323//-- NON EXPORT
324/// A portable code which is different for different OSes.
325mod portable;
326
327/// Public use of the type of the tap.
328pub use socket::TapType;
329
330/// A (prev SyslogShared) single shared (between threads) a sync type of the syslog client.
331#[cfg(feature = "build_sync")]
332pub use sync::syslog_sync_shared::SyncSyslog;
333
334#[cfg(feature = "build_sync")]
335pub use sync::syslog_trait::SyslogApi;
336
337/// A streamable sync instance (both).
338#[cfg(feature = "build_sync")]
339pub use sync::SyStreamApi;
340
341
342/// A `sy_async` is a shortcut to the file `syslog_async.rs` in dir `a_sync`.
343#[cfg(feature = "async_enabled")]
344pub use a_sync::syslog_async as sy_async;
345
346/// A main async syslog instance.
347#[cfg(feature = "async_enabled")]
348pub use sy_async::AsyncSyslog;
349
350/// A shortcut for the internals of the `async_syslog` and IO for user implementation.
351#[cfg(feature = "build_async_interface")]
352pub use a_sync::syslog_async_internal::{AsyncSyslogInternal, AsyncSyslogInternalIO};
353
354/// A shortcut to the trait `AsyncMutex` which unifies the mutex realiztion of different 
355/// exec environments.
356#[cfg(feature = "build_async_interface")]
357pub use a_sync::syslog_async_internal::AsyncMutex;
358
359/// Use this trait to access queue interface for async code.
360#[cfg(all(feature = "async_enabled", feature = "build_with_queue"))]
361pub use a_sync::syslog_trait::AsyncSyslogQueueApi;
362
363
364/// A shortcut to the file `syslog_sync_queue.rs` in dir `sync`.
365#[cfg(feature = "build_with_queue")]
366pub use sync::syslog_sync_queue as sy_sync_queue;
367
368/// A (previosuly SyslogQueue) queued sync type of the syslog client. Also async queue.
369#[cfg(feature = "build_with_queue")]
370pub use sync::syslog_sync_queue::QueuedSyslog;
371
372#[cfg(feature = "build_with_thread_local")]
373pub use sync::syslog_threadlocal::SingleSyslog;
374
375/// A shortcut use of all in the `common.rs`.
376pub use common::*;