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