libprettylogger
A highly customizable logger library written in Rust.
Table of Contents
TL;DR
Include the library in your Cargo.toml:
Update your Cargo.toml:
[]
= "0.1.0"
Use the library in your project:
// Include stuff from the library:
use Logger;
use Verbosity;
// A `Logger struct with default configuration`
let mut logger = default;
// Configure `Logger` to your liking
logger.set_verbosity; // Don't suppress any log messages
// Print logs:
logger.debug;
logger.info;
logger.warning;
logger.error;
logger.fatal;
Installation
To install the library with cargo, run:
cargo install prettylogger
And add this to your Cargo.toml:
[]
= "0.1.0"
The Logger
The Logger struct is the core of the entire project.
This is what you are going to use when you want to print a log, set filtering
rules or modify log formatting.
All of its fields are private, only allowing for modification via setters.
Creating a Logger struct with default configuration:
let mut logger = default;
Constructors:
default()->Loggerwith default configuration.from_template(path: &str)-> DeserializesLoggerfrom a JSON template file. (see this)
Logging Methods:
debug(&mut self, message: &str)-> Prints a debug message.info(&mut self, message: &str)-> Prints info message.warning(&mut self, message: &str)-> Prints a warning.error(&mut self, message: &str)-> Prints an error.fatal(&mut self, message: &str)-> Prints a fatal error.
BTW, debug, info and warning methods have their variants that bypass
filtering:
debug_no_filtering(&mut self, message: &str)-> Prints a debug message, bypasses filtering.info_no_filtering(&mut self, message: &str)-> Prints info message, bypasses filtering.warning_no_filtering(&mut self, message: &str)-> Prints a warning, bypasses filtering.
Note thaterror and fatal methods don't have _no_filtering variants.
This is because errors can't be suppressed.
Setters:
Log filtering (see this):
set_verbosity(&mut self, verbosity: &Verbosity)-> Sets theLoggerverbosity.Verbosityis declared inprettylogger::filtering.toggle_log_filtering(&mut self, enabled: &bool)-> Toggles log filtering.
Log formatting (see this):
toggle_log_header_color(&mut self, enabled: &bool)-> Toggles log type header color, same as setting all the log type header colors toColor::None.set_debug/info/warning/error/fatal_header(&mut self, header: &str)-> Sets the log type header for different log types (debug, info, warning, error, fatal).set_debug/info/warning/error/fatal_color(&mut self, color: &Color)-> Sets the log type header color for different log types. TheColorenum is declared inprettylogger::colors.set_datetime_format(&mut self, format: &str)-> Sets the timestamp format.set_log_format(&mut self, format: &str)-> Sets the log format.
File logging (see this):
set_log_file_path(&mut self, path: &str)-> Sets the log file path.toggle_file_logging(&ut self, enabled: &bool)-> Toggles file logging.set_max_log_buffer_size(&mut self, size: &usize)-> Sets the maximum size of the log buffer. When log buffer exceeds this limit, it gets flushed.toggle_log_file_lock(&mut self, enabled: &bool)-> Toggles log file lock used to avoid race conditions.
Other Methods:
format_log(&mut self, log: &LogStruct)-> Returns a formatted log based on theLogStructandLoggerconfiguration. TheLogStructis declared inprettylogger::logging.flush(&mut self)-> Flushes the log buffer.save_template(&self, path: &str)-> SerializesLoggerinto a JSON template file. (see this)
The Log Anatomy
A log consists of several headers:
- Log Type -> The type of the log (debug, info, warning etc.)
- Timestamp -> Contains the date and time the log was created
- Message -> The actual log message
Here is a log message with all its parts marked:
[ DEBUG 21:52:37 An example debug message ]
^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | the message
| timestamp
log type
This specific effect was achieved by setting the datetime format to %H:%M:%S,
log format to [ %h %d %m ] and the debug log type header to DEBUG.
Log Filtering
Logs are filtered based on the current LogLevel and the Logger's Verbosity
setting.
The Verbosity level determines which logs are filtered out:
Verbosity::All: Disables log filtering, allowing all logs to pass through.Verbosity::Standard(default): Filters out debug logs.Verbosity::Quiet: Only allows errors and warnings to be displayed.Verbosity::ErrorsOnly: Only allows errors to be shown.
The Verbosity enum is defined in prettylogger::filtering.
To modify the Verbosity of the Logger, use:
logger.set_verbosity;
To temporarily disable or enable log filtering, use:
logger.toggle_log_filtering;
File Logging
File logging is a feature that allows you to automatically save log output to a file.
Enabling file logging:
// Set the log file path first:
logger.set_log_file_path;
// Then enable file logging:
logger.toggle_file_logging;
logger.info; // Yay!
logger.flush; // Flush the log buffer to a file
It is CRUTIAL to set the log file path FIRST. This is because when
you attempt to enable file logging, Logger will check if the log file path is
correct and since the default log file path is an empty string, you will get an
error.
Locking the Log File
The log file can be locked to prevent race conditions when there are multiple
threads accessing it at the same time. It prevents Logger from writing to the
log file until the lock has been released. Logger only ignores the log file
lock when its being dropped and the OnDropPolicy is set to IgnoreLogFileLock
(off by default).
Note that log file lock is not persistent (its not saved when calling
logger.save_template("path")).
To toggle log file lock, use:
logger.toggle_lock_file_lock;
// Do some I/O operations on the log file here
logger.toggle_lock_file_lock;
To set the on drop log file policy, use:
logger.set_on_drop_file_policy;
OnDropPolicy is declared in the logging module, and all its possible values
are:
IgnoreLogFileLock-> Ignore the log file lock and write to the log file anyway.DiscardLogBuffer(default) -> Don't write to the log file.
Automatic Log Buffer Flushing
You can either flush the log buffer automatically or set up automatic flushing based on the log buffer size:
logger.set_log_file_path;
logger.toggle_file_logging;
// This will make `Logger` to flush the log buffer every 16 logs:
logger.set_max_log_buffer_size;
let mut i = 0;
loop
Logger Templates
A Logger Template is a JSON file that defines the configuration of a
Logger struct. This allows you to easily manage and store logging settings in a
file.
Here’s an example of how a Logger struct looks like in JSON format:
Deserializing Logger from a template file:
let mut logger = from_template;
Serializing Logger to a template file:
let mut logger = default; // Create a default `Logger`
logger.save_template;