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