Skip to main content

syslog_rs/
lib.rs

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