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/// // Write to the log buffer 128 times
81/// for i in 0..128 {
82/// logger.error(&format!("Error number {}", i));
83/// }
84///
85/// // Get a reference to the log buffer
86/// let buffer = logger.output.buffer_output.get_log_buffer();
87/// ```
88///
89/// Enabling file logging:
90/// ```
91/// # use prettylogger::{
92/// # Logger,
93/// # output::Toggleable,
94/// # format::LogFormatter,
95/// # config::LogStruct,
96/// # };
97/// # let mut path = std::env::temp_dir();
98/// # path.push("libprettylogger-tests/readme-logger-saving.json");
99/// # let path = &path.to_str().unwrap().to_string();
100/// // Create a `Logger` instance with default configuration
101/// let mut logger = Logger::default();
102///
103/// // Required by `FileStream` for parsing logs
104/// let mut formatter = LogFormatter::default();
105///
106/// // Set the log file path **first**
107/// logger.output.file_output.set_log_file_path(&path)
108/// .expect("Failed to set the log file path!");
109///
110/// // Enable the output
111/// logger.output.file_output.enable().
112/// expect("Failed to enable the output!");
113///
114/// // Write to the log file buffer
115/// logger.output.file_output.out(&LogStruct::debug("Hello from file!"),
116/// &mut formatter).expect("Failed to write to the buffer!");
117///
118/// // Flush the logs from the buffer to the log file
119/// logger.output.file_output.flush();
120/// ```
121#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize,
122 Deserialize)]
123pub struct Logger {
124 pub formatter: LogFormatter,
125 pub output: LogOutput,
126
127 pub(crate) verbosity: Verbosity,
128 pub(crate) filtering_enabled: bool,
129}
130
131impl Logger {
132 /// Returns true if log should be filtered and false otherwise.
133 pub(crate) fn filter_log(&self, log_type: LogType) -> bool {
134 if self.filtering_enabled {
135 return (log_type as i32) < self.verbosity as i32;
136 }
137 return false;
138 }
139
140 /// Prints a **debug message**.
141 pub fn debug(&mut self, message: &str) {
142 if self.filter_log(LogType::Debug) {
143 return;
144 }
145 let log = LogStruct::debug(message);
146 self.output.out(&log, &mut self.formatter);
147 }
148
149 /// Prints an **informational message**.
150 pub fn info(&mut self, message: &str) {
151 if self.filter_log(LogType::Info) {
152 return;
153 }
154 let log = LogStruct::info(message);
155 self.output.out(&log, &mut self.formatter);
156 }
157
158 /// Prints a **warning**.
159 pub fn warning(&mut self, message: &str) {
160 if self.filter_log(LogType::Warning) {
161 return;
162 }
163 let log = LogStruct::warning(message);
164 self.output.out(&log, &mut self.formatter);
165 }
166
167 /// Prints an **error**.
168 pub fn error(&mut self, message: &str) {
169 let log = LogStruct::error(message);
170 self.output.out(&log, &mut self.formatter);
171 }
172
173 /// Prints a **fatal error**.
174 pub fn fatal(&mut self, message: &str) {
175 let log = LogStruct::fatal_error(message);
176 self.output.out(&log, &mut self.formatter);
177 }
178
179 /// Sets `Logger` verbosity.
180 ///
181 /// # Examples
182 ///
183 /// Setting `Logger` verbosity:
184 /// ```
185 /// # use prettylogger::{Logger, config::Verbosity};
186 /// # let mut logger = Logger::default();
187 /// logger.set_verbosity(Verbosity::Quiet);
188 /// ```
189 pub fn set_verbosity<I: Into<Verbosity>>(&mut self, verbosity: I) {
190 self.verbosity = verbosity.into();
191 }
192
193 /// Enables log filtering.
194 pub fn enable_log_filtering(&mut self) {
195 self.filtering_enabled = true;
196 }
197
198 /// Disables log filtering.
199 pub fn disable_log_filtering(&mut self) {
200 self.filtering_enabled = false;
201 }
202}
203
204impl Default for Logger {
205 fn default() -> Self {
206 Logger {
207 output: LogOutput::default(),
208
209 verbosity: Verbosity::default(),
210 filtering_enabled: true,
211
212 formatter: LogFormatter::default(),
213 }
214 }
215}
216
217impl Drop for Logger {
218 fn drop(&mut self) {
219 self.output.file_output.drop_flush();
220 }
221}
222
223/// Represents errors thrown by the `prettylogger` crate.
224#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
225pub struct Error {
226 pub message: String,
227}
228
229impl Error {
230 pub fn new(msg: &str) -> Self {
231 Error {
232 message: msg.to_string(),
233 }
234 }
235}
236
237impl std::fmt::Display for Error {
238 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
239 return write!(f, "{}", self.message)
240 }
241}
242
243impl std::error::Error for Error { }