prettylogger/setters.rs
1use crate::{
2 Logger,
3 Error,
4 colors::Color,
5 fileio::{ensure_writable_file_exists, expand_env_vars, expand_tilde, overwrite_file},
6 config::{Verbosity, OnDropPolicy},
7};
8
9impl Logger {
10 /// Sets logger `verbosity`.
11 ///
12 /// # Example
13 /// ```
14 /// # use prettylogger::{Logger, config::Verbosity};
15 /// # let mut logger = Logger::default();
16 /// logger.set_verbosity(Verbosity::Quiet);
17 /// ```
18 pub fn set_verbosity<I: Into<Verbosity>>(&mut self, verbosity: I) {
19 self.verbosity = verbosity.into();
20 }
21
22 /// Toggles log filtering.
23 /// * **true**: logs will get filtered based on verbosity
24 /// * **false**: log filtering will be disabled globally
25 pub fn toggle_log_filtering<I: Into<bool>>(&mut self, enabled: I) {
26 self.filtering_enabled = enabled.into();
27 }
28
29 /// Toggles colored log headers.
30 /// * `true`: Log headers will have colors
31 /// * `false`: No colors :(
32 pub fn toggle_log_header_color<I: Into<bool>>(&mut self, enabled: I) {
33 self.log_header_color_enabled = enabled.into();
34 }
35
36 /// Sets **debug log header** color.
37 pub fn set_debug_color<I: Into<Color>>(&mut self, color: I) {
38 self.debug_color = color.into();
39 }
40
41 /// Sets **info log header** color.
42 pub fn set_info_color<I: Into<Color>>(&mut self, color: I) {
43 self.info_color = color.into();
44 }
45
46 /// Sets **warning header** color.
47 pub fn set_warning_color<I: Into<Color>>(&mut self, color: I) {
48 self. warning_color = color.into();
49 }
50
51 /// Sets **error header** color.
52 pub fn set_error_color<I: Into<Color>>(&mut self, color: I) {
53 self.error_color = color.into();
54 }
55
56 /// Sets **fatal error header** color.
57 pub fn set_fatal_color<I: Into<Color>>(&mut self, color: I) {
58 self.fatal_color = color.into();
59 }
60
61 /// Sets **debug log header** format.
62 pub fn set_debug_header(&mut self, header: &str) {
63 self.debug_header = header.to_string();
64 }
65
66 /// Sets **info log header** format.
67 pub fn set_info_header(&mut self, header: &str) {
68 self.info_header = header.to_string();
69 }
70
71 /// Sets **warning header** format.
72 pub fn set_warning_header(&mut self, header: &str) {
73 self.warning_header = header.to_string();
74 }
75
76 /// Sets **error header** format.
77 pub fn set_error_header(&mut self, header: &str) {
78 self.error_header = header.to_string();
79 }
80
81 /// Sets **fatal error header** format.
82 pub fn set_fatal_header(&mut self, header: &str) {
83 self.fatal_header = header.to_string();
84 }
85
86 /// Sets datetime format.
87 pub fn set_datetime_format(&mut self, format: &str) {
88 self.datetime_format = String::from(format);
89 }
90
91 /// Sets the log format.
92 ///
93 /// There are several placeholders in a log format string:
94 /// * `%c`: Ascending log count starting at 1.
95 /// * `%d`: The timestamp.
96 /// * `%h`: The header indicating the log type (e.g., debug, error, etc.)
97 /// * `%m`: The log message (this placeholder is mandatory, you will
98 /// get an error if you don't include this in your log format).
99 ///
100 /// You can have multiple placeholders of the same type in a format string.
101 ///
102 /// # Example
103 /// ```
104 /// # use prettylogger::Logger;
105 /// # let mut l = Logger::default();
106 /// l.set_log_format("<l> <h>%h</h> <m>%m</m> </l>");
107 /// l.error("lorem ipsum");
108 /// ```
109 ///
110 /// Returns an error when the `%m` placeholder is missing.
111 pub fn set_log_format(&mut self, format: &str) -> Result<(), Error> {
112 if format.contains("%m") {
113 self.log_format = String::from(format);
114 self.show_datetime = format.contains("%d");
115 Ok(())
116 }
117 else {
118 Err(Error::new(&"Expected a message placeholder!"))
119 }
120 }
121
122 /// Sets log file path.
123 ///
124 /// Returns an error if the path is inaccessible.
125 ///
126 /// Check out the [File logging documentation](https://github.com/tpaau-17DB/libprettylogger?tab=readme-ov-file#file-logging).
127 ///
128 /// # Example
129 /// ```
130 /// # use prettylogger::Logger;
131 /// # let mut logger = Logger::default();
132 /// # let mut path = std::env::temp_dir();
133 /// # path.push("libprettylogger-tests/set_log_file_path.log");
134 /// # let path = &path.to_str().unwrap().to_string();
135 /// # logger.set_log_file_path(path);
136 /// // Set the log file path first:
137 /// logger.set_log_file_path(path);
138 /// // Then enable file logging:
139 /// logger.toggle_file_logging(true);
140 /// ```
141 pub fn set_log_file_path(&mut self, path: &str) -> Result<(), Error> {
142 let path: &str = &expand_env_vars(&expand_tilde(path));
143 if ensure_writable_file_exists(path) {
144 self.log_file_path = path.to_string();
145 match overwrite_file(path, "") {
146 Ok(_) => { Ok(()) },
147 Err(e) => {
148 self.error(&format!("Failed to open file '{}' for writing. {}",
149 path, e.to_string()));
150 return Err(Error::new(&e.to_string()))
151 }
152 }
153 }
154 else {
155 self.error(&format!("Failed to open file '{}' for writing. File not writeable", path));
156 return Err(Error::new(&"File is not writable!"))
157 }
158 }
159
160 /// Toggles file logging.
161 ///
162 /// Before enabling file logging, ensure that the log file path is set.
163 /// This is because this method checks if the log file is writable. If
164 /// the log file path is not set, or the file is not writable, enabling
165 /// file logging will result in an error.
166 ///
167 /// # Example
168 /// ```
169 /// # use prettylogger::Logger;
170 /// # let mut logger = Logger::default();
171 /// # let mut path = std::env::temp_dir();
172 /// # path.push("libprettylogger-tests/toggle_file_logging.log");
173 /// # let path = &path.to_str().unwrap().to_string();
174 /// # logger.set_log_file_path(path);
175 /// // Set the log file path first:
176 /// logger.set_log_file_path(path);
177 /// // Then enable file logging:
178 /// logger.toggle_file_logging(true);
179 /// ```
180 pub fn toggle_file_logging<I: Into<bool>>(&mut self, enabled: I)
181 -> Result<(), std::io::Error> {
182 if !enabled.into() {
183 self.file_logging_enabled = false;
184 Ok(())
185 }
186 else if ensure_writable_file_exists(&self.log_file_path) {
187 self.file_logging_enabled = true;
188 Ok(())
189 }
190 else {
191 self.error(&format!("Failed to open file '{}' for writing!",
192 self.log_file_path));
193 Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied,
194 "File is not writable!"))
195 }
196 }
197
198 /// Sets the maximum allowed size for the log buffer.
199 ///
200 /// When the buffer exceeds its max size, it gets flushed
201 /// automatically to the log file. When set to `0`, automatic flushing is
202 /// disabled and the buffer can only be flushed manually.
203 ///
204 /// If a log file lock is active, the log buffer will not be flushed
205 /// automatically, regardless of the size limit.
206 ///
207 /// # Example
208 /// ```
209 /// # use prettylogger::Logger;
210 /// # let mut path = std::env::temp_dir();
211 /// # path.push("libprettylogger-tests/set_max_log_buffer_size.log");
212 /// # let path = &path.to_str().unwrap().to_string();
213 /// let mut logger = Logger::default();
214 /// logger.set_log_file_path(path);
215 /// logger.toggle_file_logging(true);
216 ///
217 /// // Make `Logger` flush the log buffer every 16 logs:
218 /// logger.set_max_log_buffer_size(16 as u32);
219 ///
220 /// let mut i = 0;
221 /// loop {
222 /// logger.info("Yay!");
223 /// i += 1;
224 /// if i >= 16 {
225 /// break;
226 /// }
227 /// }
228 /// // Here the buffer gets flushed, after sixteenth iteration.
229 /// ```
230 pub fn set_max_log_buffer_size<I: Into<u32>>(&mut self, size: I) {
231 self.file_log_buffer_max_size = size.into();
232 }
233
234 /// Log file lock can be used to prevent race conditions when there are
235 /// multiple threads accessing the log file at the same time.
236 ///
237 /// # WARNING: leaving this option on for a long period of time will
238 /// cause high memory usage!
239 ///
240 /// * `true`: When log file lock is enabled, logger won't flush into the
241 /// log file. Instead, it will wait until the lock is disabled. You
242 /// will not loose any logs, they will be stored in the log buffer
243 /// even when it exceeds its size limit.
244 /// * `false`: Logger will write to the log file normally.
245 pub fn toggle_log_file_lock<I: Into<bool>>(&mut self, enabled: I) {
246 self.log_file_lock = enabled.into();
247 }
248
249 /// Sets `Logger`'s on drop log file policy.
250 ///
251 /// # Example
252 /// ```
253 /// # use prettylogger::{Logger, config::OnDropPolicy};
254 /// # let mut logger = Logger::default();
255 /// logger.set_on_drop_file_policy(OnDropPolicy::IgnoreLogFileLock);
256 /// ```
257 pub fn set_on_drop_file_policy<I: Into<OnDropPolicy>>(&mut self, policy: I) {
258 self.on_drop_policy = policy.into();
259 }
260
261 /// Toggles printing logs to `stdout`.
262 /// * `true`: Logs will be printed in your terminal's `stdout`.
263 /// * `false`: No log output in your terminal.
264 pub fn toggle_console_output<I: Into<bool>>(&mut self, enabled: I) {
265 self.console_out_enabled = enabled.into();
266 }
267
268 /// Toggles the usage of a custom log buffer.
269 /// * `true`: Logs will be stored in a buffer inside `Logger` and can
270 /// be cloned using the `clone_log_buffer()` method. Be aware that
271 /// this will lead to high memory usage if turned on for a log
272 /// period of time.
273 /// * `false`: Logs will not be stored in a log buffer.
274 pub fn toggle_custom_log_buffer<I: Into<bool>>(&mut self, enabled: I) {
275 self.use_custom_log_buffer = enabled.into();
276 }
277
278 /// Clears the custom log buffer.
279 pub fn clear_log_buffer(&mut self) {
280 self.custom_log_buffer = Vec::new();
281 }
282}