Releases: odygrd/quill
v11.0.1
v11.0.0
- Update bundled
libfmttov12.1.0 - Minor correction to
_last_sink_flush_time updatewhenfflush()fails - Added retry logic and shared access handling for file open and rotation on Windows
- Use
::WriteFileinstead offwriteto prevent\r\r\nline endings on Windows - Avoid file descriptor leaks by setting
O_CLOEXECon Unix andHANDLE_FLAG_INHERITon Windows - Added
SimpleSetup.hconvenience header for trivial program cases to easily setup a logger. For example#include "quill/SimpleSetup.h" #include "quill/LogMacros.h" int main() { auto* logger = quill::simple_logger(); LOG_INFO(logger, "Hello from {}!", "Quill"); auto* logger2 = quill::simple_logger("test.log"); LOG_INFO(logger2, "This message goes to a file"); }
- Fixed argument forwarding when encoding user-defined types with
DeferredFormatCodecor STL containers to properly
handle rvalue references. For example, the following move-only type will now work correctly:class MoveOnlyType { public: MoveOnlyType(std::string name, std::string value, uint32_t count) : name(std::move(name)), value(std::move(value)), count(count) {} MoveOnlyType(MoveOnlyType&&) = default; MoveOnlyType(MoveOnlyType const&) = delete; std::string name; std::string value; uint32_t count; }; template <> struct fmtquill::formatter<MoveOnlyType> { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } auto format(MoveOnlyType const& obj, format_context& ctx) const { return fmtquill::format_to(ctx.out(), "MoveOnlyType(name: {}, value: {}, count: {})", obj.name, obj.value, obj.count); } }; template <> struct quill::Codec<MoveOnlyType> : quill::DeferredFormatCodec<MoveOnlyType> {}; MoveOnlyType obj{"Test", "Value1", 42}; LOG_INFO(logger, "obj: {}", std::move(obj)); // Properly forwards and moves
v10.2.0
- Added fuzzing tests to CI to catch memory and undefined behavior issues
- Fixed
PatternFormatterautomatic newline appending by making the suffix ('\n') configurable or optionally disabled viaPatternFormatterOptions - Fixed segmentation fault when
DirectFormatCodecwas used with enums types (#848) - Fixed segmentation fault when
DirectFormatCodecwas used with STL containers of enums - Fixed a compiler error when
LOG_DYNAMICis used withQUILL_DISABLE_FILE_INFO(#847) - Fixed process ID capture in
BackendWorkerto supportfork()correctly (#860) - Fixed undefined behavior caused by passing
nullptrtomemcpywhen encoding an emptystd::vector - Updated
BackendOptions::check_printable_charto allow tab (\t) and carriage return (\r) characters by default (#856) - Increased
RdtscClockresync lag thresholds to improve cross-system compatibility - Added
QUILL_ENABLE_ASSERTIONSCMake option and preprocessor flag to enable assertions in release builds - Allow
RotatingSinkto rotate the file on creation withrotation_on_creation() - Improved
SignalHandlerOptionsconfigurability by replacing hardcoded logger exclusion string withexcluded_logger_substringsoption - Silence MSVC warnings (4324, 4996) in source code instead of CMake
v10.1.0
- Fixed potential conflicts by adding unique prefixes to internal macro variables to prevent conflicts with user variable names in the same scope. (#799)
- Fixed potential
UBSanwarnings by adding overflow check when doubling resync interval inRdtscClock::resync()(#809) - Minor improvements in
Utility::to_hexfunction andStringFromTime - Fixed an issue where
BackendWorker::_exitwas always executed during destruction, even when the backend thread had already stopped (#815) - Fixed
RotatingFileSinkto correctly handleFilenameAppendOption::StartDateconfiguration (#822) - Fixed unnecessary allocation caused by empty
std::vectorwhileBackendWorkeris idle on Windows (#827) - Fixed
FileSink::open_modestring comparison for file mode flags - Adjusted default
BackendOptionsvalues for broader system compatibility
v10.0.1
v10.0.0
New Features
-
There is a new macro-free mode that allows logging without macros. You have two options: either
#include "quill/LogMacros.h"or#include "quill/LogFunctions.h". The macro mode still remains the recommended and main method for logging. The new macro-free log has higher overhead than using macros. To use the macro-free mode, for example:quill::debug(logger, "A {} message with number {}", "test", 123);
See macro-free mode documentation here for details.
-
Added
BinaryDataDeferredFormatCodecfor efficient binary data logging. This codec allows efficient logging of variable-sized binary data by copying the raw bytes on the hot path and deferring the formatting to the backend thread. This is particularly useful for logging binary protocol messages (like SBE or custom binary formats), network packets, and raw binary data without impacting application performance. See the example sbe_logging and binary_protocol_logging for details. For documentation, see here. -
The immediate flush feature has been enhanced to support interval-based flushing and moved to runtime. This feature helps with debugging by ensuring log statements are flushed to the sink, blocking the caller thread. (#660)
-
Added the
QUILL_DISABLE_FILE_INFOpreprocessor flag and CMake option. This disables__FILE__and__LINE__information in log statements at compile time when location-related patterns (%(file_name),%(line_number),%(short_source_location),%(source_location)) are not needed in thePatternFormatter. This removes embedded source path strings from built binaries from the security viewpoint. -
Added the
QUILL_DETAILED_FUNCTION_NAMECMake option. When enabled, this option uses compiler-specific detailed function signatures (such as__PRETTY_FUNCTION__on GCC/Clang or__FUNCSIG__on MSVC) instead of the standard__FUNCTION__in log macros. This provides more complete function information, including return types, namespaces, and parameter types. This option is only relevant when%(caller_function)is used in the pattern formatter. (#785) -
Added
source_location_path_strip_prefixoption inPatternFormatterOptionsto customize the display of the%(source_location)attribute ofPatternFormatter. When set, any paths that contain this prefix will have the prefix and everything before it stripped from the displayed path. For example, with prefix "projects", a source location like "/home/user/projects/app/main.cpp:5" would be displayed as "app/main.cpp:5". (#772) -
Added
source_location_remove_relative_pathsoption inPatternFormatterOptionsto remove relative path components from the%(source_location)attribute ofPatternFormatter. When enabled, relative path components like "../" are processed and removed, simplifying paths from__FILE__which might contain relative paths like "../../../test/main.cpp". (#778) -
Added
process_function_namecustomisation point inPatternFormatterOptions. This function allows custom processing of the function signature before it's displayed in logs. This makes more sense to use whenQUILL_DETAILED_FUNCTION_NAMEis used. This provides flexibility to trim, format, or otherwise modify function signatures to improve readability in log output when using the%(caller_function)pattern. (#785) -
Added helper macros for easy logging of user-defined types. Two new macros are available in
quill/HelperMacros.h:QUILL_LOGGABLE_DIRECT_FORMAT(Type): For types that contain pointers or have lifetime dependenciesQUILL_LOGGABLE_DEFERRED_FORMAT(Type): For types that only contain value types and are safe to copy
Note that these macros require you to provide either an
operator<<for your type and they are just shortcuts to existing functionality. (#777)Example usage:
class User { /* ... */ }; std::ostream& operator<<(std::ostream& os, User const& user) { /* ... */ } // For types with pointers - will format immediately QUILL_LOGGABLE_DIRECT_FORMAT(User) class Product { /* ... */ }; std::ostream& operator<<(std::ostream& os, Product const& product) { /* ... */ } // For types with only value members - can format asynchronously QUILL_LOGGABLE_DEFERRED_FORMAT(Product)
Improvements
-
Internally, refactored how runtime metadata are handled for more flexibility, providing three macros for logging with runtime metadata:
QUILL_LOG_RUNTIME_METADATA_DEEP- Takes a deep copy offmt,file,functionandtags. Most flexible
option, useful for forwarding logs from another logging library.QUILL_LOG_RUNTIME_METADATA_HYBRID- Will take a deep copy offmtandtagsand will takefileand
functionas reference. This is used for the new macro-free mode.QUILL_LOG_RUNTIME_METADATA_SHALLOW- Will take everything as reference. This is used when logging with
compile-time metadata and using, for example, a dynamic log-level such asLOG_DYNAMIC.
-
When using a sink with overridden
PatternFormatterOptions, the optionadd_metadata_to_multi_line_logswill now be correctly applied at the Sink level. Previously, this option was only available and effective at the Logger levelPatternFormatter. -
When a Sink with override
PatternFormatterOptionsis used and if no other sink exists using theLoggerPatternFormatterOptions, then the backend thread will no longer perform a redundant format log statement. -
When using a sink with overridden
PatternFormatterOptions, thelog_statementthat is passed to theFilter::filter()will now be formatted based on the overridden options instead of using theLoggerPatternFormatterOptions. -
Update bundled
libfmttov11.2.0
API Changes
-
If you were previously setting
QUILL_ENABLE_IMMEDIATE_FLUSHto1, this functionality has been moved to runtime with more flexibility. Instead of using a boolean flag, you can now specify the flush interval by callinglogger->set_immediate_flush(flush_every_n_messages)on each logger instance. Set it to1for per-message flushing, or to a higher value to flush after that many messages. Setting it to0disables flushing which is the default behaviour.QUILL_ENABLE_IMMEDIATE_FLUSHstill exists as a compile-time preprocessor flag and is set to1by default. SettingQUILL_ENABLE_IMMEDIATE_FLUSH 0in the preprocessor will eliminate theifbranch from the hot path and disable this feature entirely, regardless of the value passed toset_immediate_flush(flush_every_n_messages). -
The
QUILL_LOG_RUNTIME_METADATAmacro requiresfile,functionandfmtto be passed aschar const*andline_numberasuint32_t. This is a breaking change from the previous version.
v9.0.3
v9.0.2
v9.0.1
v9.0.0
API Changes
- Replaced the
bool huge_pages_enabledflag inFrontendOptionswithquill::HugePagesPolicy huge_pages_policyenum, allowing huge page allocation to be attempted with a fallback to normal pages if unavailable. If you are using a customFrontendOptionstype, you will need to update it to use the new flag. (#707) - Previously,
QueueType::UnboundedDroppingandQueueType::UnboundedBlockingcould grow up to 2 GB in size. This limit is now configurable viaFrontendOptions::unbounded_queue_max_capacity, which defaults to 2 GB. QueueType::UnboundedUnlimitedhas been removed, as the same behavior can now be achieved by settingFrontendOptions::unbounded_queue_max_capacityto the maximum value.- The
ConsoleSinkconstructor now optionally accepts aConsoleSinkConfig, similar to other sinks. If noConsoleSinkConfigis provided, a default one is used, logging tostdoutwithColourMode::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
Loggercan 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_instanceflag inBackendOptions. (#687) -
Added the
QUILL_DISABLE_FUNCTION_NAMEpreprocessor 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
PatternFormatteron 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
libfmtto11.1.4. -
When
add_metadata_to_multi_line_logsin thePatternFormatterwas 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_Nmacros to log on the first occurrence (0th call) instead of waiting until the Nth call. -
Added a
nullptrcheck forchar*andconst char*during encoding, ensuring the library handlesnullptrvalues gracefully (#735) -
The
CsvWritercould previously be used withRotatingFileSinkvia 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
CsvWriterwithopen_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
rdtsccalibration during init -
Fixed
QUILL_ATTRIBUTE_HOTandQUILL_ATTRIBUTE_COLDclang 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