Releases: odygrd/quill
v9.0.0
API Changes
- Replaced the
bool huge_pages_enabled
flag inFrontendOptions
withquill::HugePagesPolicy huge_pages_policy
enum, allowing huge page allocation to be attempted with a fallback to normal pages if unavailable. If you are using a customFrontendOptions
type, you will need to update it to use the new flag. (#707) - Previously,
QueueType::UnboundedDropping
andQueueType::UnboundedBlocking
could grow up to 2 GB in size. This limit is now configurable viaFrontendOptions::unbounded_queue_max_capacity
, which defaults to 2 GB. QueueType::UnboundedUnlimited
has been removed, as the same behavior can now be achieved by settingFrontendOptions::unbounded_queue_max_capacity
to the maximum value.- The
ConsoleSink
constructor now optionally accepts aConsoleSinkConfig
, similar to other sinks. If noConsoleSinkConfig
is provided, a default one is used, logging tostdout
withColourMode::Automatic
. For example:Frontend::create_or_get_sink<ConsoleSink>("console_sink", []() { ConsoleSinkConfig config; config.set_colour_mode(ConsoleSinkConfig::ColourMode::Never); config.set_stream("stderr"); return config; }());
New Features
-
The default log level for each
Logger
can now be configured using the environment variableQUILL_LOG_LEVEL
. Supported values:"tracel3"
,"tracel2"
,"tracel1"
,"debug"
,"info"
,"notice"
,"warning"
,"error"
,"critical"
,"none"
. When set, the logger is initialized with the corresponding log level. Iflogger->set_log_level(level)
is explicitly called in code, it will override the log level set via the environment variable. -
Added the
LOG_RUNTIME_METADATA(logger, log_level, file, line_number, function, fmt, ...)
macro. This enables passing runtime metadata (such as file, line number, and function) along with a log message, providing greater flexibility when forwarding logs from other logging libraries. (#696)LOG_RUNTIME_METADATA(logger, quill::LogLevel::Info, "main.cpp", 20, "foo()", "Hello number {}", 8);
-
Added a runtime check to detect duplicate backend worker threads caused by inconsistent linkage (e.g., mixing static and shared libraries). If needed, this check can be disabled using the
check_backend_singleton_instance
flag inBackendOptions
. (#687) -
Added the
QUILL_DISABLE_FUNCTION_NAME
preprocessor flag and CMake option. This allows disabling__FUNCTION__
inLOG_*
macros when%(caller_function)
is not used inPatternFormatter
, eliminating Clang-Tidy warnings when logging inside lambdas. -
It is now possible to override a logger's
PatternFormatter
on a per-sink basis. This allows the same logger to output different formats for different sinks. Previously, achieving this required creating a custom sink type, but this functionality is now built-in. See the example: sink_formatter_override. -
Added
Frontend::remove_logger_blocking(...)
, which blocks the caller thread until the specified logger is fully removed. -
Added
Frontend::shrink_thread_local_queue(capacity)
andFrontend::get_thread_local_queue_capacity()
. These functions allow dynamic management of thread-local SPSC queues when using an unbounded queue configuration. They enable on-demand shrinking of a queue that has grown due to bursty logging, helping to reduce memory usage, although in typical scenarios they won't be required. -
Added the
SyslogSink
, which logs messages to the system's syslog.auto sink = quill::Frontend::create_or_get_sink<quill::SyslogSink>( "app", []() { quill::SyslogSinkConfig config; config.set_identifier("app"); return config; }());
-
Added the
SystemdSink
, which logs messages to systemd.auto sink = quill::Frontend::create_or_get_sink<quill::SystemdSink>( "app", []() { quill::SystemdSinkConfig config; config.set_identifier("app"); return config; }());
-
Added the
AndroidSink
, which integrates with Android's logging system.auto sink = quill::Frontend::create_or_get_sink<quill::AndroidSink>( "s1", []() { quill::AndroidSinkConfig config; config.set_tag("app"); config.set_format_message(true); return config; }());
Improvements
-
Updated bundled
libfmt
to11.1.4
. -
When
add_metadata_to_multi_line_logs
in thePatternFormatter
was set to false, fixed a bug where the last character of the log message was dropped and added protection for empty messages. -
Updated
LOG_EVERY_N
macros to log on the first occurrence (0th call) instead of waiting until the Nth call. -
Added a
nullptr
check forchar*
andconst char*
during encoding, ensuring the library handlesnullptr
values gracefully (#735) -
The
CsvWriter
could previously be used withRotatingFileSink
via the constructor that acceptedstd::shared_ptr<Sink>
, but rotated files did not include the CSV header. This has now been improvedβwhen using the new constructor that acceptsquill::RotatingFileSinkConfig
, the CSV header is written at the start of each new rotated file. (#700)quill::RotatingFileSinkConfig sink_config; sink_config.set_open_mode('w'); sink_config.set_filename_append_option(FilenameAppendOption::None); sink_config.set_rotation_max_file_size(512); sink_config.set_rotation_naming_scheme(RotatingFileSinkConfig::RotationNamingScheme::Index); quill::CsvWriter<OrderCsvSchema, quill::FrontendOptions> csv_writer{"orders.csv", sink_config}; for (size_t i = 0; i < 40; ++i) { csv_writer.append_row(132121122 + i, "AAPL", i, 100.1, "BUY"); }
-
When using
CsvWriter
withopen_mode == 'a'
, the header will no longer be rewritten if the file already exists. -
On Linux, setting a long backend thread name now truncates it instead of failing. (#691)
-
Fixed BSD builds. (#688)
-
Added adaptive termination for stable measurements in
rdtsc
calibration during init -
Fixed
QUILL_ATTRIBUTE_HOT
andQUILL_ATTRIBUTE_COLD
clang detection -
CMake improvements: switched to range syntax for minimum required version and bumped minimum required CMake version to
3.12
. (#686) -
Correct the installation location of pkg-config files. They are now properly placed in
/usr/local/lib
. (#715) -
Removed deprecated
TriviallyCopyableTypeCodec
v8.2.0
-
Added
DeferredFormatCodec
andDirectFormatCodec
for easier logging of user-defined types and smoother migration from pre-v4
versions. Previously, users had to define a customCodec
for every non-trivially copyable user-defined type they wanted to log.template <> struct quill::Codec<UserTypeA> : quill::DeferredFormatCodec<UserTypeA> { }; template <> struct quill::Codec<UserTypeB> : quill::DirectFormatCodec<UserTypeB> { };
DeferredFormatCodec
now supports both trivially and non-trivially copyable types:- For trivially copyable types, it behaves the same as
TriviallyCopyableTypeCodec
. - For non-trivially copyable types, it works similarly to pre-
v4
by taking a copy of the object using the copy constructor and placement new.
- For trivially copyable types, it behaves the same as
DirectFormatCodec
formats the object immediately in the hot path, serving as a shortcut to explicitly formatting the object when logging.- For advanced use cases, a custom
Codec
can still be defined for finer control over encoding/decoding.
See:
-
Added support for C-style arrays of user-defined types in
std/Array.h
-
Fixed warnings:
-Wimplicit-int-float-conversion
,-Wfloat-equal
, and-Wdocumentation
. -
Marked
TriviallyCopyableTypeCodec
as deprecated.DeferredFormatCodec
should be used instead, requiring no further changes. -
Raised minimum
CMake
required version from3.8
to3.10
to avoid deprecation warnings.
v8.1.1
v8.1.0
v8.0.0
- Updated bundled
libfmt
to11.1.2
- Suppress
-Wredundant-decls
warning in GCC builds. - Remove
-Wno-gnu-zero-variadic-macro-arguments
for GCC in CMake. - Unified
JsonFileSink.h
andJsonConsoleSink.h
into a single header,JsonSink.h
, with both classes now sharing a common implementation - Users can now inherit from
JsonFileSink
orJsonConsoleSink
and override thegenerate_json_message(...)
function to implement their own custom JSON log formats - Removed
JsonFileSinkConfig
. Please rename it toFileSinkConfig
, which retains the same API and is fully compatible. - Added
RotatingJsonFileSink
. Functions likeRotatingFileSink
, but specifically designed for rotating JSON log files. (#637) - Simplified
ConsoleSink
by applying ANSI colour codes universally across all platforms, including Windows. The previous Windows-specific implementation has been removed. Note thatquill::ConsoleColours
has been replaced withquill::ConsoleSink::Colours
, andquill::ConsoleColours::ColourMode
has been renamed toquill::ConsoleSink::ColourMode
. - Changed class member visibility in
FileSink
,JsonSink
, andRotatingSink
from private to protected, enabling easier customization through inheritance for user-defined implementations. - Added a new
sink_min_flush_interval
option inBackendOptions
, which specifies the minimum time interval (in milliseconds) before the backend thread flushes the output buffers callingflush_sink()
for all sinks, with a default value of 200ms; The backend thread ensures sinks aren't flushed more frequently than this interval, while explicit calls tologger->flush_log()
trigger an immediate flush, and flushing may occur less frequently if the backend thread is busy, with this setting applying globally to all sinks. Setting this value to 0 disables the feature. (#641) - Added a
StopWatch
utility for easy logging of elapsed time. It can log the time elapsed since construction in various formats. You can use eitherquill::StopWatchTsc
for high-resolution TSC-based timing orquill::StopWatchChrono
for standard std::chrono-based timing. (#640)
For example:
#include "quill/StopWatch.h"
quill::StopWatchTsc swt;
std::this_thread::sleep_for(std::chrono::seconds(1));
LOG_INFO(logger, "After 1s, elapsed: {:.6}s", swt); // => After 1s, elapsed: 1.00849s
std::this_thread::sleep_for(std::chrono::milliseconds(500));
LOG_INFO(logger, "After 500ms, elapsed: {}s", swt); // => After 500ms, elapsed: 1.521880274s
LOG_INFO(logger, "elapsed: {}", swt.elapsed_as<std::chrono::nanoseconds>()); // => elapsed: 1521807324ns
v7.5.0
-
The
LOG_LEVEL_LIMIT
time-based rate-limiting macros now log the count of how many times a message would be logged when throttled. For example, a log message may appear asA log message with number 123 (21x)
to indicate that the message would have been logged 21 times. (#616) -
New macros
LOG_LEVEL_LIMIT_EVERY_N
have been added, allowing for count-based rate limiting and giving developers greater control over logging frequency. (#616) -
In previous versions, logging on Windows automatically included
windows.h
in all components. The frontend will no longer includewindows.h
. By following the recommended usage example provided here as guidance, you can create a wrapper library around Quill for the backend, allowing you to log on Windows without includingwindows.h
in the frontend or main program. (#618) -
Renamed
PACKED
used inlibfmt
toQUILLPACKED
to avoid naming collisions. (#620) -
The
set_thread_name
function has been fixed to provide accurate error reporting, ensuring that the correct error message is displayed in the event of a failure.
v7.4.0
-
Fixed a build issue when compiling with
-fno-rtti
. This ensures compatibility with projects that disableRTTI
. (#604) -
Fixed an incorrectly triggered assertion in debug builds when
BackendOptions::log_timestamp_ordering_grace_period
is set to 0. (#605) -
Fixed a compile-time error in
CsvWriter
that occurred when passing a customFrontendOptions
type as a template parameter. (#609) -
Added accessors to
Logger
for sinks, user clock source, clock source type, and pattern formatter options that can be used to create anotherLogger
with similar configuration. -
Added
ConsoleColours::ColourMode
toConsoleSink
, allowing colors to be explicitly forced or conditionally enabled based on the environment. Previously, colors were only conditionally enabled. (#611).For example:
quill::Frontend::create_or_get_sink<quill::ConsoleSink>( "sink_id_1", quill::ConsoleColours::ColourMode::Automatic);
v7.3.0
- Added the option to explicitly specify the
Logger
used by the built-inSignalHandler
for logging errors during application crashes. (#590) - Prevented error logs from the
SignalHandler
from being output to CSV files when aCsvWriter
is in use. (#588) - Introduced
SignalHandlerOptions
to simplify and unify the API.Backend::start_with_signal_handler
is now deprecated, replaced by a newBackend::start
overload that acceptsSignalHandlerOptions
for enabling signal handling. - Added a new
create_or_get_logger
overload that accepts astd::vector<std::shared_ptr<Sink>>
, improving flexibility by allowing a variable number of sinks to be passed at runtime when creating a logger. - Added a new overload to
create_or_get_logger
to create a logger that inherits configuration options from a specified logger. (#596) - Implemented a workaround to resolve false positive warnings from
clang-tidy
on Windows.