Sink Types¶
Reference for all built-in sink implementations. See Sinks for how to create, share, and extend sinks.
ConsoleSink¶
The ConsoleSink class sends logging output to streams stdout or stderr. Printing color codes to terminal or Windows console is also supported.
FileSink¶
The FileSink is a straightforward sink that outputs to a file. The filepath of the FileSink serves as a unique identifier, allowing you to retrieve the same sink later using FrontendImpl::get_sink().
Each file can only have a single instance of FileSink.
Note
When using FileEventNotifier with FileSink, the callback handle type is
platform-dependent and is exposed as quill::FileEventNotifierHandle. On Windows it is a native
HANDLE. On other platforms it is a FILE*.
before_write runs as part of normal log writing. before_open, after_open,
before_close, and after_close run on whichever thread performs the file open/close
operation. Different callbacks, and different invocations of the same callback, may therefore
run on different threads over the sink lifetime. Callbacks must be thread-safe and must not
assume a single calling thread.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
RotatingFileSink¶
The RotatingFileSink is built on top of the FileSink and provides log file rotation based on specified time intervals, file sizes, or daily schedules.
Note
When the sink starts in append mode, rotated files left behind by previous runs are detected
for every RotationNamingScheme and count towards max_backup_files whether or not the
base filename has an extension; the oldest ones are removed on startup if they exceed the
limit, so log files do not accumulate across restarts. Set
set_overwrite_rolled_files(false) to prevent append-mode recovery from deleting existing
rotated files, or use FilenameAppendOption::StartDateTime to give each run its own
independent set of files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | |
JsonFileSink/JsonConsoleSink¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
RotatingJsonFileSink¶
The RotatingJsonFileSink is built on top of the JsonFileSink and provides log file rotation based on specified time intervals, file sizes, or daily schedules.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | |
SyslogSink¶
The SyslogSink leverages the syslog API to send messages.
Note
Syslog uses process-global state. Multiple SyslogSink instances are therefore not
independent if they use different identifiers, options, or facilities. Use a single
SyslogSink configuration per process.
StreamSink¶
The StreamSink is a base sink class used to write log messages to C-style FILE* streams, such as
stdout, stderr, or files opened with fopen.
It is typically used as a foundation for higher-level sinks like ConsoleSink.
AndroidSink¶
The AndroidSink sends log messages to the Android logging system using the Android NDK logging API.
NullSink¶
The NullSink discards all log messages, useful for performance testing or disabling specific logger output without removing logging calls.
Note
Macro Collision Notice
When including syslog.h via SyslogSink, the header defines macros such as LOG_INFO
(and others) that may collide with Quill’s unprefixed LOG_ macros. To resolve this issue, consider one
of the following solutions:
Include SyslogSink in a .cpp file only: Instantiate the SyslogSink in a source file rather than in a header file. This ensures that
syslog.his included only in that specific translation unit, allowing the rest of your code to use the unprefixed QuillLOG_macros without conflict.Define the preprocessor flag ``QUILL_DISABLE_NON_PREFIXED_MACROS``: This flag disables the unprefixed Quill
LOG_macros and forces the use of the longerQUILL_LOG_macros instead. This approach allows Quill to work alongsidesyslog.hin the same translation unit.
Alternatively, you can combine both solutions if you include SyslogSink in a .cpp file where you
also want to use the unprefixed LOG_ macros. However, the first solution is generally preferred since it
allows for less typing with the concise LOG_ macros.
#define QUILL_DISABLE_NON_PREFIXED_MACROS
#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/sinks/SyslogSink.h"
#include <string>
#include <utility>
int main()
{
quill::BackendOptions backend_options;
quill::Backend::start(backend_options);
// Frontend
auto sink = quill::Frontend::create_or_get_sink<quill::SyslogSink>(
"app", []()
{
quill::SyslogSinkConfig config;
config.set_identifier("app");
return config;
}());
quill::Logger* logger = quill::Frontend::create_or_get_logger("root", std::move(sink));
QUILL_LOG_INFO(logger, "A {} message with number {}", "log", 1);
QUILL_LOG_WARNING(logger, "test message {}", 123);
}
SystemdSink¶
The SystemdSink integrates with the systemd journal, allowing messages to be sent directly to systemd. To use this sink, ensure the systemd-devel package is installed. Additionally, link your program against lsystemd.
find_package(PkgConfig REQUIRED)
pkg_check_modules(SYSTEMD REQUIRED libsystemd)
target_link_libraries(${TARGET} ${SYSTEMD_LIBRARIES})
Note
Macro Collision Notice
When including syslog.h via SystemdSink, the header defines macros such as LOG_INFO
(and others) that may collide with Quill’s unprefixed LOG_ macros. To resolve this issue, consider one
of the following solutions:
Include SystemdSink in a .cpp file only: Instantiate the SystemdSink in a source file rather than in a header file. This ensures that
syslog.his included only in that specific translation unit, allowing the rest of your code to use the unprefixed QuillLOG_macros without conflict.Define the preprocessor flag ``QUILL_DISABLE_NON_PREFIXED_MACROS``: This flag disables the unprefixed Quill
LOG_macros and forces the use of the longerQUILL_LOG_macros instead. This approach allows Quill to work alongsidesyslog.hin the same translation unit.
Alternatively, you can combine both solutions if you include SystemdSink in a .cpp file where you
also want to use the unprefixed LOG_ macros. However, the first solution is generally preferred since it
allows for less typing with the concise LOG_ macros.
#define QUILL_DISABLE_NON_PREFIXED_MACROS
#include "quill/Backend.h"
#include "quill/Frontend.h"
#include "quill/LogMacros.h"
#include "quill/Logger.h"
#include "quill/sinks/SystemdSink.h"
#include <string>
#include <utility>
int main()
{
quill::BackendOptions backend_options;
quill::Backend::start(backend_options);
// Frontend
auto sink = quill::Frontend::create_or_get_sink<quill::SystemdSink>(
"app", []()
{
quill::SystemdSinkConfig config;
config.set_identifier("app");
return config;
}());
quill::Logger* logger = quill::Frontend::create_or_get_logger("root", std::move(sink));
QUILL_LOG_INFO(logger, "A {} message with number {}", "log", 1);
QUILL_LOG_WARNING(logger, "test message {}", 123);
}