prettylogger/setters.rs
1use crate::{
2 colors::*, fileio::*, filtering::*, logging::*
3};
4use std::io::{Error, ErrorKind};
5
6impl Logger {
7 /// Sets logger `verbosity`.
8 /// * `All` -> Don't filter any logs
9 /// * `Standard` -> Just filter debug logs
10 /// * `Quiet` -> Only let warnings and errors to be displayed
11 /// * `ErrorsOnly` -> I'm not gonna explain this one
12 pub fn set_verbosity<I: Into<Verbosity>>(&mut self, verbosity: I) {
13 self.verbosity = verbosity.into();
14 }
15
16
17 /// Toggles log filtering.
18 /// * **true** -> logs will get filtered based on verbosity
19 /// * **false** -> log filtering will be disabled globally
20 pub fn toggle_log_filtering<I: Into<bool>>(&mut self, enabled: I) {
21 self.filtering_enabled = enabled.into();
22 }
23
24 /// Toggles colored log headers.
25 /// * `true` -> Log headers will have colors
26 /// * `false` -> No colors :(
27 pub fn toggle_log_header_color<I: Into<bool>>(&mut self, enabled: I) {
28 self.log_header_color_enabled = enabled.into();
29 }
30
31 /// Sets **debug log header** color.
32 pub fn set_debug_color<I: Into<Color>>(&mut self, color: I) {
33 self.debug_color = color.into();
34 }
35
36 /// Sets **info log header** color.
37 pub fn set_info_color<I: Into<Color>>(&mut self, color: I) {
38 self.info_color = color.into();
39 }
40
41 /// Sets **warning header** color.
42 pub fn set_warning_color<I: Into<Color>>(&mut self, color: I) {
43 self. warning_color = color.into();
44 }
45
46 /// Sets **error header** color.
47 pub fn set_error_color<I: Into<Color>>(&mut self, color: I) {
48 self.error_color = color.into();
49 }
50
51 /// Sets **fatal error header** color.
52 pub fn set_fatal_color<I: Into<Color>>(&mut self, color: I) {
53 self.fatal_color = color.into();
54 }
55
56 /// Sets **debug log header** format.
57 pub fn set_debug_header(&mut self, header: &str) {
58 self.debug_header = header.to_string();
59 }
60
61 /// Sets **info log header** format.
62 pub fn set_info_header(&mut self, header: &str) {
63 self.info_header = header.to_string();
64 }
65
66 /// Sets **warning header** format.
67 pub fn set_warning_header(&mut self, header: &str) {
68 self.warning_header = header.to_string();
69 }
70
71 /// Sets **error header** format.
72 pub fn set_error_header(&mut self, header: &str) {
73 self.error_header = header.to_string();
74 }
75
76 /// Sets **fatal error header** format.
77 pub fn set_fatal_header(&mut self, header: &str) {
78 self.fatal_header = header.to_string();
79 }
80
81 /// Sets datetime format.
82 pub fn set_datetime_format(&mut self, format: &str) {
83 self.datetime_format = String::from(format);
84 }
85
86 /// Sets the log format.
87 ///
88 /// There are three placeholders in a log format string (you can place
89 /// multiple placeholders of the same type in a format string):
90 /// * `%m` -> The log message (this placeholder is mandatory, you format
91 /// will get rejected if it doesn't contain this placeholder)
92 /// * `%h` -> The log type header (debug, error, etc.)
93 /// * `%d` -> The datetime
94 ///
95 /// # Set an XML-like log format;
96 /// ```
97 /// # use prettylogger::logging::Logger;
98 /// # let mut l = Logger::default();
99 /// l.set_log_format("<l> <h>%h</h> <m>%m</m> </l>");
100 /// l.error("A nice debug log!");
101 /// ```
102 ///
103 /// Returns an error when the `%m` placeholder is missing.
104 pub fn set_log_format(&mut self, format: &str) -> Result<(), &'static str> {
105 if format.contains("%m") {
106 self.log_format = String::from(format);
107 self.show_datetime = format.contains("%d");
108 Ok(())
109 }
110 else {
111 Err("Expected a message placeholder ('%m')!")
112 }
113 }
114
115 /// Sets log file path.
116 ///
117 /// Returns an error if the path is inaccessible.
118 ///
119 /// # Make sure to actually enable file logging:
120 /// ```ignore
121 /// # use prettylogger::logging::Logger;
122 /// # let mut logger = Logger::default();
123 /// // Set the log file path first:
124 /// logger.set_log_file_path("/path/to/file.log");
125 /// // Then enable file logging:
126 /// logger.toggle_file_logging(true);
127 /// ```
128 pub fn set_log_file_path(&mut self, path: &str) -> Result<(), Error> {
129 if is_file_writable(path) {
130 self.log_file_path = path.to_string();
131 overwrite_file(path, "")
132 .map_err(|e| {
133 self.error(&format!("Failed to open file '{}' for writing!",
134 self.log_file_path));
135 Error::new(ErrorKind::Other,
136 format!("Failed to overwrite file: {}", e))
137 })?;
138 Ok(())
139 }
140 else {
141 self.error(&format!("Failed to open file '{}' for writing!",
142 self.log_file_path));
143 Err(Error::new(ErrorKind::PermissionDenied,
144 "File is not writable!"))
145 }
146 }
147
148 /// Toggles file logging.
149 ///
150 /// Before enabling file logging, ensure that the log file path is set.
151 /// This is because the method checks if the log file is writable. If the
152 /// log file path is not set, or the file is not writable, enabling file
153 /// logging will result in an error.
154 ///
155 /// # Enabling file logging:
156 /// ```ignore
157 /// # use prettylogger::logging::Logger;
158 /// # let mut logger = Logger::default();
159 /// // Set the log file path first:
160 /// logger.set_log_file_path("/path/to/file.log");
161 /// // Then enable file logging:
162 /// logger.toggle_file_logging(true);
163 /// ```
164 pub fn toggle_file_logging<I: Into<bool>>(&mut self, enabled: I)
165 -> Result<(), Error> {
166 if !enabled.into() {
167 self.file_logging_enabled = false;
168 Ok(())
169 }
170 else {
171 if is_file_writable(&self.log_file_path) {
172 self.file_logging_enabled = true;
173 Ok(())
174 }
175 else {
176 self.error(&format!("Failed to open file '{}' for writing!",
177 self.log_file_path));
178 Err(Error::new(ErrorKind::PermissionDenied,
179 "File is not writable!"))
180 }
181 }
182 }
183
184 /// Sets the maximum size of the log buffer.
185 ///
186 /// This method sets the maximum allowed size for the log buffer. When the
187 /// buffer exceeds this size, it will be automatically flushed to the log
188 /// file. If the buffer size is set to `0`, automatic flushing is disabled,
189 /// and the buffer can only be flushed manually.
190 ///
191 /// If a log file lock is active, the log buffer will not be flushed
192 /// automatically, regardless of the size limit.
193 ///
194 /// # Setting a custom log buffer size:
195 /// ```ignore
196 /// let mut logger = Logger::default();
197 /// logger.set_log_file_path("/path/to/file.log");
198 /// logger.toggle_file_logging(true);
199 ///
200 /// // This will force `Logger` to flush the log buffer every 16 logs:
201 /// logger.set_max_log_buffer_size(16);
202 ///
203 /// let mut i = 0;
204 /// loop {
205 /// logger.info("Yay!");
206 /// i += 1;
207 /// if i >= 16 {
208 /// break;
209 /// }
210 /// }
211 /// ```
212 pub fn set_max_log_buffer_size<I: Into<usize>>(&mut self, size: I) {
213 self.log_buffer_max_size = size.into();
214 }
215
216 /// Log file lock can be used to prevent race conditions when there is one
217 /// thread reading from the log file and another thread writing to the log
218 /// file.
219 ///
220 /// # WARNING: LEAVING THIS OPTION ON FOR A LONG PERIOD OF TIME CAN CAUSE
221 /// HIGH MEMORY USAGE AND STUTTERING!
222 ///
223 /// `true` -> When log file lock is enabled, logger won't flush into the
224 /// log file. Instead, it will wait until the lock is disabled. You will
225 /// not loose any logs, they will be stored in the log buffer even when it
226 /// exceeds its size limit.
227 /// `false` -> Logger will write to the log file normally.
228 pub fn toggle_log_file_lock<I: Into<bool>>(&mut self, enabled: I) {
229 self.log_file_lock = enabled.into();
230 }
231
232 /// Sets `Logger`'s on drop log file policy.
233 ///
234 /// ```
235 /// # use prettylogger::logging::{Logger, OnDropPolicy};
236 /// # let mut logger = Logger::default();
237 /// logger.set_on_drop_file_policy(OnDropPolicy::IgnoreLogFileLock);
238 /// ```
239 pub fn set_on_drop_file_policy<I: Into<OnDropPolicy>>(&mut self, policy: I) {
240 self.on_drop_policy = policy.into();
241 }
242}