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 { }