Releases: odygrd/quill
v3.5.1
v3.5.0
- Fixed
LOG_TRACE_CFORMAT
macros. - Added support for compile-time custom tags in
quill::MacroMetadata
to enhance message filtering and incorporate
static information. New log macros suffixed with_WITH_TAGS
introduced for this feature.
Additionally,%(custom_tags)
parameter added toPatternFormatter
. (#349)
See example_custom_tags.cpp - Some code improvements aiming to reduce total compilation time
v3.4.1
- Reduce backend worker unnecessary allocation. (#368)
- Adjusted handling for empty
std::string_view
instances, addressing an issue where logging empty strings triggered an unintendedmemcpy
with zero size and a nullptr, leading to address sanitizer warnings. - Fix clang build error when using
-DQUILL_NO_EXCEPTIONS:BOOL=ON
. (#357)
v3.4.0
-
Resolved
bad_variant_access
error occurring when using Quill as a pre-compiled library with a distinct queue
type. (#276) -
Resolved a bug in
RotatingFileHandler
associated with logfiles located outside the working directory,
specifically when used with open_modea
. (#340) -
Added a
name()
method to the Logger class which provides the logger name. (#345) -
Fixed library and include paths in the pkg-config configuration. (#352)
-
Move
get_root_logger()
definition from cpp to the header file (#348) -
Introduced support for logging character arrays. You can now log character arrays, even when they don't contain a null-terminating character. Additionally, character arrays with null characters in the middle are supported, and the logger will capture the content until the null character is encountered. (#353)
For example
union { char no_0[2]; char mid_0[6]{'1', '2', '3', '4', '\0', 6}; } char_arrays; // only output "12" even if there's no '\0' at the end LOG_INFO(logger, R"(This is a log info example for char array without '\0': {})", char_arrays.no_0); // output "1234" until the '\0' LOG_INFO(logger, R"(This is a log info example for char array with '\0' in middle: {})", char_arrays.mid_0);
-
Minor improvements in
BoundedQueue
andUnboundedQueue
. Throughput is slightly improved.
Previous: 2.21 million msgs/sec average, total time elapsed: 1809 ms for 4000000 log messages.
New: 2.24 million msgs/sec average, total time elapsed: 1787 ms for 4000000 log messages. -
Disable
fmt::join(data, "")
at compile time. (#356) -
Fix compile error in Apple Clang 12. (#360)
-
Add guards for redefined preprocessor variables.
-
Fix
uint64_t
totime_t
implicit conversion error in Clang 18. -
Update bundled
libfmt
tov10.1.1
v3.3.1
v3.3.0
-
Added a
quill::get_handler(handler_name)
function that allows easy lookup of an existingHandler
by name. This
function proves helpful when you want to retrieve a handler and pass it to a new logger. -
Fix build failure of Intel Compiler Classic. (#332)
-
Introduced
QUILL_BLOCKING_QUEUE_RETRY_INTERVAL_NS
option for user-configurable retry interval in the blocking queue.
Default value is 800 nanoseconds. (#330) -
Improved backend thread handling. Now verifies that all producer SPSC queues are empty before entering
sleep
. -
Fixed a race condition and potential crash in
quill::remove_logger(Logger*)
when called without priorquill::flush()
. -
Added protection to prevent removal of the root logger with
quill::remove_logger(Logger*)
. -
Improved exception handling on the backend thread when calling
fmt::format()
.While compile-time checks ensure that the format string and arguments match, runtime errors can still occur.
Previously, such exceptions would affect and drop subsequent log records. Now, exceptions are caught and logged
in the log file and reported via the backend thread notification handler (default iscerr
).For example, if a dynamic precision is used (
LOG_INFO(logger, "Support for floats {:.{}f}", 1.23456, 3.321312)
),
the log file will show the following error message:LOG_INFO root [format: "Support for floats {:.{}f}", error: "precision is not integer"]
Additionally, an error message will be printed to
cerr
Quill ERROR: [format: "Support for floats {:.{}f}", error: "precision is not integer"]
-
Fixed a bug in timestamp formatting that occasionally displayed an hour component of 0 as
24. (#329) -
Added support for specifying a runtime log level, allowing dynamic log level configuration at runtime.
The new runtime log level feature provides flexibility when needed, with a minor overhead cost.
It is recommended to continue using the existing static log level macros for optimal
performance. (#321)For example
std::array<quill::LogLevel, 4> const runtime_log_levels = {quill::LogLevel::Debug, quill::LogLevel::Info, quill::LogLevel::Warning, quill::LogLevel::Error}; for (auto const& log_level : runtime_log_levels) { LOG_DYNAMIC(logger, log_level, "Runtime {} {}", "log", "level"); }
-
Added support for printf-style formatting with
_CFORMAT
macros. These macros use theprintf
format string syntax,
simplifying the migration of legacy codebases usingprintf
statements.For example
std::array<uint32_t, 4> arr = {1, 2, 3, 4}; LOG_INFO(logger, "This is a log info example using fmt format {}", arr); LOG_INFO_CFORMAT(logger, "printf style %s supported %d %f", "also", 5, 2.32);
-
Added a
metadata()
member function to theTransitEvent
class. It provides access to theMetadata
object
associated with the log record, simplifying syntax for retrieving log record metadata in custom Handlers.For example
void CustomHandler::write(fmt_buffer_t const& formatted_log_message, quill::TransitEvent const& log_event) { MacroMetadata const macro_metadata = log_event.metadata(); }
-
Simplified file handler configuration. Now, instead of passing multiple arguments to the constructor,
you only need to provide a singleFileHandlerConfig
object. This change makes creating file handlers objects
much easier and more flexible.For example
quill::FileHandlerConfig file_handler_cfg; file_handler_cfg.set_open_mode('w'); file_handler_cfg.set_append_to_filename(quill::FilenameAppend::StartDateTime); std::shared_ptr<quill::Handler> file_handler = quill::file_handler("application.log", file_handler_cfg); quill::Logger* logger_foo = quill::create_logger("my_logger", std::move(file_handler)); LOG_INFO(my_logger, "Hello from {}", "application");
-
Combined the functionalities of
RotatingFileHandler
(rotating based on file size) andTimeRotatingFileHandler
(rotating on a time interval) into a single, more versatileRotatingFileHandler
. Users can now conveniently rotate
logs based on both file size and time intervals simultaneously. The updatedRotatingFileHandler
offers a variety of
customization options for improved flexibility. For more information on available configurations,
refer to theRotatingFileHandlerConfig
documentation.For example
// Create a rotating file handler which rotates daily at 18:30 or when the file size reaches 2GB std::shared_ptr<quill::Handler> file_handler = quill::rotating_file_handler(filename, []() { quill::RotatingFileHandlerConfig cfg; cfg.set_rotation_time_daily("18:30"); cfg.set_rotation_max_file_size(2'000'000'000); return cfg; }()); // Create a logger using this handler quill::Logger* logger_bar = quill::create_logger("daily_logger", std::move(file_handler));
-
Improved compatibility with older versions of external
libfmt
. Quill now compiles for all versions
oflibfmt >= 8.0.0
.
v2.0.3
v3.2.0
- Addition of
std::is_trivially_copyable<T>
to default copy loggable types. (#318) - By default, the static library now builds with
-fPIC
to generate position-independent code.
To disable this feature, you can use the CMake optionQUILL_DISABLE_POSITION_INDEPENDENT_CODE
. - The
LOG_<LEVEL>_LIMIT
macros now support usingstd::chrono
duration types for specifying the log interval.
Instead of providing a raw number, you can use:
LOG_INFO_LIMIT(std::chrono::milliseconds {100} , quill::get_logger(), "log message");
v3.1.0
- It is now possible to set a minimum logging interval for specific logs. For example:
for (uint64_t i = 0; i < 10; ++i)
{
LOG_INFO_LIMIT(2000, default_logger, "log in a loop with limit 1 message every 2000 micros for i {}", i);
std::this_thread::sleep_for(std::chrono::microseconds{1000});
}
-
quill::utility::to_string()
now usesfmt::to_string()
-
Quill now utilizes a custom namespace (
fmtquill
) for the bundled fmt library. This enables smooth integration with
your own external fmt library, even if it's a different version.