prettylogger/
lib.rs

1//! Fancy logger library.
2
3/// Fancy logger library.
4#[cfg(test)]
5mod tests;
6
7#[doc = include_str!("../README.md")]
8mod fileio;
9mod json;
10
11pub mod colors;
12pub mod config;
13pub mod format;
14pub mod output;
15
16use format::LogFormatter;
17use serde::{Serialize, Deserialize};
18use config::{Verbosity, LogStruct, LogType};
19use output::LogOutput;
20
21/// `Logger` capable of filtering logs, formatting them and distributing them
22/// to various streams.
23///
24/// The `Logger` struct is modular and itself only filters the logs, relying
25/// on `LogFormatter` and `LogOutput` for log formatting and outputting.
26///
27/// Additionally, `Logger` includes a template system with built-in methods and
28/// constructors for easy JSON serialization and deserialization.
29///
30/// # Examples
31///
32/// Creating a `Logger` struct and printing out some logs:
33/// ```
34/// # use prettylogger::Logger;
35/// // Create a `Logger` instance with default configuration
36/// let mut logger = Logger::default();
37///
38/// // Print log messages
39/// logger.debug("debug message");
40/// logger.info("info message");
41/// logger.warning("warning message");
42/// logger.error("error message");
43/// logger.fatal("fatal error message");
44/// ```
45///
46/// Configuring the formatter of a `Logger`:
47/// ```
48/// # use prettylogger::{
49/// #     Logger,
50/// #     colors::Color,
51/// # };
52/// // Create a `Logger` instance with default configuration
53/// let mut logger = Logger::default();
54///
55/// // Set a simple log format
56/// logger.formatter.set_log_format("[ %d ] %m");
57///
58/// // Change debug log header color
59/// logger.formatter.set_debug_color(Color::Red);
60///
61/// // Set a fatal log header
62/// logger.formatter.set_fatal_header("--FATAL--");
63///
64/// // Configure datetime format
65/// logger.formatter.set_datetime_format("%H:%M");
66/// ```
67///
68/// Enabling log buffering:
69/// ```
70/// # use prettylogger::{
71/// #     Logger,
72/// #     output::Toggleable,
73/// # };
74/// // Create a `Logger` instance with default configuration
75/// let mut logger = Logger::default();
76///
77/// // Enable log buffering
78/// logger.output.buffer_output.enable();
79///
80/// for i in 0..128 {
81///     logger.error(&format!("Error number {}", i));
82/// }
83///
84/// // Get a reference to the log buffer
85/// let buffer = logger.output.buffer_output.get_log_buffer();
86/// ```
87///
88/// Enabling file logging:
89/// ```
90/// # use prettylogger::{
91/// #     Logger,
92/// #     output::Toggleable,
93/// #     format::LogFormatter,
94/// #     config::LogStruct,
95/// # };
96/// # let mut path = std::env::temp_dir();
97/// # path.push("libprettylogger-tests/readme-logger-saving.json");
98/// # let path = &path.to_str().unwrap().to_string();
99/// // Create a `Logger` instance with default configuration
100/// let mut logger = Logger::default();
101///
102/// // Required by `FileStream` for parsing logs
103/// let mut formatter = LogFormatter::default();
104///
105/// // Set the log file path **first**
106/// logger.output.file_output.set_log_file_path(&path)
107///     .expect("Failed to set the log file path!");
108///
109/// // Enable the output
110/// logger.output.file_output.enable().
111///     expect("Failed to enable the output!");
112///
113/// // Write to the log file buffer
114/// logger.output.file_output.out(&LogStruct::debug("Hello from file!"),
115///     &mut formatter).expect("Failed to write to the buffer!");
116///
117/// // Flush the logs from the buffer to the log file
118/// logger.output.file_output.flush();
119/// ```
120#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize,
121    Deserialize)]
122pub struct Logger {
123    pub formatter: LogFormatter,
124    pub output: LogOutput,
125
126    pub(crate) verbosity: Verbosity,
127    pub(crate) filtering_enabled: bool,
128}
129
130impl Logger {
131    /// Returns true if log should be filtered and false otherwise.
132    pub(crate) fn filter_log(&self, log_type: LogType) -> bool {
133        if self.filtering_enabled {
134            return (log_type as i32) < self.verbosity as i32;
135        }
136        return false;
137    }
138
139    /// Prints a **debug message**.
140    pub fn debug(&mut self, message: &str) {
141        if self.filter_log(LogType::Debug) {
142            return;
143        }
144        let log = LogStruct::debug(message);
145        self.output.out(&log, &mut self.formatter);
146    }
147
148    /// Prints an **informational message**.
149    pub fn info(&mut self, message: &str) {
150        if self.filter_log(LogType::Info) {
151            return;
152        }
153        let log = LogStruct::info(message);
154        self.output.out(&log, &mut self.formatter);
155    }
156
157    /// Prints a **warning**.
158    pub fn warning(&mut self, message: &str) {
159        if self.filter_log(LogType::Warning) {
160            return;
161        }
162        let log = LogStruct::warning(message);
163        self.output.out(&log, &mut self.formatter);
164    }
165
166    /// Prints an **error**.
167    pub fn error(&mut self, message: &str) {
168        let log = LogStruct::error(message);
169        self.output.out(&log, &mut self.formatter);
170    }
171
172    /// Prints a **fatal error**.
173    pub fn fatal(&mut self, message: &str) {
174        let log = LogStruct::fatal_error(message);
175        self.output.out(&log, &mut self.formatter);
176    }
177
178    /// Sets `Logger` verbosity.
179    ///
180    /// # Examples
181    ///
182    /// Setting `Logger` verbosity:
183    /// ```
184    /// # use prettylogger::{Logger, config::Verbosity};
185    /// # let mut logger = Logger::default();
186    /// logger.set_verbosity(Verbosity::Quiet);
187    /// ```
188    pub fn set_verbosity<I: Into<Verbosity>>(&mut self, verbosity: I) {
189        self.verbosity = verbosity.into();
190    }
191
192    /// Enables log filtering.
193    pub fn enable_log_filtering(&mut self) {
194        self.filtering_enabled = true;
195    }
196
197    /// Disables log filtering.
198    pub fn disable_log_filtering(&mut self) {
199        self.filtering_enabled = false;
200    }
201}
202
203impl Default for Logger {
204    fn default() -> Self {
205        Logger {
206            output: LogOutput::default(),
207
208            verbosity: Verbosity::default(),
209            filtering_enabled: true,
210
211            formatter: LogFormatter::default(),
212        }
213    }
214}
215
216impl Drop for Logger {
217    fn drop(&mut self) {
218        self.output.file_output.drop_flush();
219    }
220}
221
222/// Represents errors thrown by the `prettylogger` crate.
223#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
224pub struct Error {
225    pub message: String,
226}
227
228impl Error {
229    pub fn new(msg: &str) -> Self {
230        Error {
231            message: msg.to_string(),
232        }
233    }
234}
235
236impl std::fmt::Display for Error {
237    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
238        return write!(f, "{}", self.message)
239    }
240}
241
242impl std::error::Error for Error { }