3 releases (stable)
new 2.0.0 | Feb 20, 2025 |
---|---|
1.0.0 | Feb 15, 2025 |
0.1.0 | Feb 12, 2025 |
#242 in Development tools
227 downloads per month
3.5MB
1K
SLoC
Table of Contents
TL;DR
Installing the library:
cargo add libprettylogger
Using the library in your project:
// Include stuff from the library:
use prettylogger::Logger;
use prettylogger::config::Verbosity;
// A `Logger` struct with default configuration
let mut logger = Logger::default();
// Configure `Logger` to your liking
logger.set_verbosity(Verbosity::All); // Don't suppress any log messages
// Print logs:
logger.debug("A debug message!");
logger.info("Info message!");
logger.warning("A warning!");
logger.error("An error!");
logger.fatal("A fatal error!");
Installation
To install the library with cargo
, run:
cargo add libprettylogger
Or add this to your Cargo.toml
:
[dependencies]
libprettylogger = "2.0.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 it's fields are private, only allowing for
modification via setters.
Creating a Logger
struct with default configuration:
# use prettylogger::Logger;
let mut logger = Logger::default();
Controlling Terminal Output
By default, Logger
streams all logs to stdout
and stderr
. If you only want
to write logs to a file or store them in a custom buffer, use:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.toggle_console_output(false);
Custom Log Buffer
Logger
can store logs in a buffer instead of printing them or writing them
to a file. Later, you can reference that buffer and do whatever you want with it.
Enabling custom log buffer:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.toggle_custom_log_buffer(true);
And when you need a reference to that buffer, call:
# use prettylogger::Logger;
# let mut logger = Logger::default();
let buffer = logger.log_buffer();
Log Format
A basic 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
Those headers can then be formatted using a log format string, similarly to how you would format a datetime string.
Here is a log message with all it's headers 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
.
Use this method to set the datetime format of a Logger
:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.set_datetime_format("%H:%M:%S");
You can set a custom log format like this:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.set_log_format("[ %h %d %m ]");
Note that the %m
(message) placeholder is mandatory and you will get an error
unless you include it in your format string.
Log type headers can be customized with their corresponding methods:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.set_debug_header("DEBUG");
logger.set_info_header("INFO");
logger.set_warning_header("WARNING");
logger.set_error_header("ERROR");
logger.set_fatal_header("FATAL ERROR");
And you can also customize their colors:
# use prettylogger::{Logger, colors::Color};
# let mut logger = Logger::default();
logger.set_debug_color(Color::Blue);
logger.set_info_color(Color::Green);
logger.set_warning_color(Color::Yellow);
logger.set_error_color(Color::Red);
logger.set_fatal_color(Color::Magenta);
Using the LogStruct
LogStruct
is a type that represents a single log entry. You can create LogStruct
instance using one of it's constructors:
debug(message: &str)
info(message: &str)
warning(message: &str)
error(message: &str)
fatal_error(message: &str)
Using LogStruct
's debug
constructor to create a debug log, and then formatting
with logger.format_log(...)
:
# use prettylogger::{Logger, config::LogStruct};
# let mut logger = Logger::default();
let log_formatted = logger.format_log(&LogStruct::debug("A debug log!"));
Log Filtering
Logs are filtered based on the current LogLevel
and the Logger
's verbosity
setting. config::Verbosity
enum can be used to set the verbosity of a Logger
.
The Verbosity
level determines which logs are filtered out:
All
→ Disables log filtering, allowing all logs to pass through.Standard
(default) → Filters out debug logs.Quiet
→ Only allows errors and warnings to be displayed.ErrorsOnly
→ Only allows errors to be shown.
To modify the verbosity of the Logger
, use:
# use prettylogger::{Logger, config::Verbosity};
# let mut logger = Logger::default();
logger.set_verbosity(Verbosity::All);
To toggle log filtering, use:
# use prettylogger::{Logger, config::Verbosity};
# let mut logger = Logger::default();
logger.toggle_log_filtering(false);
File Logging
File logging is a feature that allows you to automatically save log output to a file.
Enabling file logging:
# use prettylogger::Logger;
# let mut logger = Logger::default();
# let mut path = std::env::temp_dir();
# path.push("libprettylogger-tests/readme-doc1.log");
# let path = &path.to_str().unwrap().to_string();
// Set the log file path first:
logger.set_log_file_path(path);
// Then enable file logging:
logger.toggle_file_logging(true);
logger.info("Yay!"); // Yay!
logger.flush(); // Flush the log buffer to a file
It is CRUCIAL to set the log file path FIRST. If you try to enable file
logging before specifying a valid path, Logger
will check the log file path, and
since the default path is an empty string, it will result in 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. The lock is only ignored when a
Logger
is being dropped and the OnDropPolicy
is set to IgnoreLogFileLock
(off by default).
Log file lock is not persistent (it's not saved when calling
logger.save_template("path")
).
Toggling log file lock:
# use prettylogger::Logger;
# let mut logger = Logger::default();
logger.toggle_log_file_lock(true);
// Do some I/O operations on the log file here
logger.toggle_log_file_lock(false);
To set the on drop log file policy, use:
# use prettylogger::{Logger, config::OnDropPolicy};
# let mut logger = Logger::default();
logger.set_on_drop_file_policy(OnDropPolicy::IgnoreLogFileLock);
Automatic Log Buffer Flushing
You can either flush the log buffer automatically or set up automatic flushing based on the log buffer size:
# use prettylogger::Logger;
# let mut logger = Logger::default();
# let mut path = std::env::temp_dir();
# path.push("libprettylogger-tests/readme-doc2.log");
# let path = &path.to_str().unwrap().to_string();
logger.set_log_file_path(path);
logger.toggle_file_logging(true);
// This will make `Logger` to flush the log buffer every 16 logs:
logger.set_max_log_buffer_size(16 as u32);
let mut i = 0;
loop {
logger.info("Yay!");
i += 1;
if i >= 16 {
break;
}
}
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 what a Logger
struct looks like in JSON format:
{
"stdout_enabled": true,
"use_custom_log_buffer": false,
"verbosity": "Standard",
"filtering_enabled": true,
"log_header_color_enabled": true,
"debug_color": "Blue",
"info_color": "Green",
"warning_color": "Yellow",
"error_color": "Red",
"fatal_color": "Magenta",
"debug_header": "DBG",
"info_header": "INF",
"warning_header": "WAR",
"error_header": "ERR",
"fatal_header": "FATAL",
"log_format": "[%h] %m",
"datetime_format": "%Y-%m-%d %H:%M:%S",
"file_logging_enabled": false,
"log_file_path": "",
"file_log_buffer_max_size": 128,
"on_drop_policy": "DiscardLogBuffer"
}
Loading Logger
from a template file:
# use prettylogger::Logger;
# let mut path = std::env::temp_dir();
# path.push("libprettylogger-tests/readme-doc3.log");
# let path = &path.to_str().unwrap().to_string();
# Logger::default().save_template(path);
let mut logger = Logger::from_template(path);
Saving Logger
to a template file:
# use prettylogger::Logger;
let mut logger = Logger::default(); // Create a default `Logger`
# let mut path = std::env::temp_dir();
# path.push("libprettylogger-tests/readme-doc4.log");
# let path = &path.to_str().unwrap().to_string();
logger.save_template(path);