User’s API¶
Reference for the main public Quill API surface.
Use Guides and Recipes for usage patterns and examples. Use this page when you want the main public options, aliases, classes, and sink types.
If you generate Doxygen for a downstream project, you can link quill:: API
types through the published tag file:
TAGFILES = https://quillcpp.readthedocs.io/en/latest/quill.tag=https://quillcpp.readthedocs.io/en/latest/
Backend Options¶
-
struct BackendOptions¶
Configuration options for the backend.
This struct defines settings for the backend thread
Public Members¶
-
std::string thread_name = "QuillBackend"¶
The name assigned to the backend, visible during thread naming queries (e.g., pthread_getname_np) or in the debugger.
-
bool enable_yield_when_idle = false¶
The backend employs “busy-waiting” by spinning around each frontend thread’s queue. If enabled, the backend will yield when there is no remaining work, potentially reducing the OS scheduler priority for the backend. This option is effective only when sleep_duration is set to 0.
-
std::chrono::nanoseconds sleep_duration = std::chrono::microseconds{100}¶
Specifies the duration the backend sleeps if there is no remaining work to process in the queues.
-
uint32_t transit_event_buffer_initial_capacity = 256¶
The backend pops all log messages from the frontend queues and buffers them in a local ring buffer queue as transit events. The transit_event_buffer is unbounded, starting with a customizable initial capacity (in items, not bytes) and will reallocate up to transit_events_hard_limit The backend will use a separate transit_event_buffer for each frontend thread. The capacity is rounded up to the next power of two.
-
size_t transit_events_soft_limit = 8192¶
The backend gives priority to reading messages from the frontend queues of all the hot threads and temporarily buffers them.
If a frontend threads continuously push messages to the queue (e.g., logging in a loop), no logs can ever be processed.
When the soft limit is reached the backend worker thread will try to process a batch of cached transit events all at once
The frontend queues are emptied on each iteration, so the actual popped messages can be much greater than the transit_events_soft_limit.
Note
This number represents a limit across the messages received from ALL frontend threads.
-
size_t transit_events_hard_limit = 65'536¶
The backend gives priority to reading messages from the frontend queues and temporarily buffers them.
If a frontend thread continuously push messages to the queue (e.g., logging in a loop), no logs can ever be processed.
As the backend buffers messages, it can keep buffering indefinitely if the frontend threads keep pushing.
This limit is the maximum size of the backend event buffer. When reached, the backend will stop reading the frontend queues until there is space available in the buffer.
Note
This number represents a limit PER frontend threads.
-
std::chrono::microseconds log_timestamp_ordering_grace_period = {5}¶
The backend iterates through all frontend lock-free queues and pops all messages from each queue. It then buffers and logs the message with the lowest timestamp among them.
Each frontend lock-free queue corresponds to a thread, and when multiple frontend threads are pushing logs simultaneously, it is possible to read a timestamp from the last queue in the iteration but miss that timestamp when the first queue was read because it was not available at that time.
When this option is set to a non-zero value, the backend takes a timestamp (
now()) before reading the queues. It uses that timestamp to ensure that each log message’s timestamp from the frontend queues is less than or equal to the storednow()timestamp minus the specified grace period, reducing the chance of processing events out of timestamp order.Messages that fail the above check remain in the lock-free queue. They are checked again in the next iteration. The timestamp check is performed with microsecond precision.
Example scenario:
Frontend thread takes a timestamp at the very start of logging, then becomes delayed (preempted, blocked, processing slowly, etc.) before pushing to the queue.
Backend thread takes timestamp
now()and subtracts the grace period, reads queues up to the adjustednow(), and writes the logs.Frontend thread wakes up and pushes the message with its already-recorded timestamp to the queue.
Backend thread reads and writes the delayed timestamp, resulting in an out-of-order log.
Setting this option to a non-zero value causes a minor delay in reading messages from the lock-free queues and protects timestamp ordering within the configured grace window. It does not guarantee ordering if a frontend thread records a timestamp and is delayed longer than the grace period before publishing the event to its queue.
Setting
log_timestamp_ordering_grace_periodto zero disables this grace-period delay.0μs: Fastest processing, may process messages out of timestamp order
1-5μs: Good default - minimal delay, occasional reordering possible
10-20μs: Better ordering when threads have different queue arrival timing
100μs+: Stricter ordering, but risk of SPSC queue filling up at high throughput logging
This compensates for timing differences in when threads push to their queues, not for timestamp accuracy itself. The backend also assumes timestamps within a single frontend queue are normally non-decreasing; if a wall clock or user-provided clock moves backwards,
ensure_monotonic_output_timestampscan correct regular output records.log_timestamp_ordering_grace_periodis the first line of defense: it delays reading newer queue entries so older timestamped events from other frontend threads have time to arrive.ensure_monotonic_output_timestampsis the optional final correction: if an older timestamped regular record still reaches the output stage, it can adjust that record’s sink-visible timestamp instead of letting output time move backwards.
-
bool ensure_monotonic_output_timestamps = false¶
Ensures sink-visible timestamps for regular log and metric records do not move backwards.
If a regular log or metric record selected for output has a timestamp lower than the last corrected output timestamp, the backend adjusts it to
last_timestamp + 1nanosecond before formatting, filtering, and writing it to sinks. This is useful when a delayed frontend event escapes the configured grace period or when a clock source moves backwards.Backtrace records are excluded because they intentionally preserve the timestamp from when the backtrace log was captured, even though they are emitted later. Control events such as flush, logger removal, backtrace setup/flush, and MDC changes are also excluded because they are not written as output records.
This option changes the timestamp displayed in the output for corrected records. It does not affect frontend timestamp capture or the timestamp used to select the next cached event for processing.
This option complements
log_timestamp_ordering_grace_period. The grace period keeps eligible queue entries back for a bounded amount of time to preserve original timestamps when possible. This option only applies later, after an event has been selected for output, and only when that event would otherwise move sink-visible time backwards.
-
bool wait_for_queues_to_empty_before_exit = true¶
When this option is enabled and the application is terminating, the backend worker thread will not exit until all the frontend queues are empty.
This assumes frontend threads stop logging before backend shutdown begins. A few trailing log statements may still drain successfully, but you should not rely on that behavior. Sustained concurrent logging while
Backend::stop()is draining the frontend queues, especially logging in a loop from another thread, can prevent the backend from exiting because the queues may never become empty.When this option is disabled, the backend will try to read the queues once and then exit. Reading the queues only once means that some log messages can be dropped. This is more likely when
log_timestamp_ordering_grace_periodis non-zero, because the grace-period cutoff can intentionally leave newer queue entries unread until a later poll.
-
std::vector<uint16_t> cpu_affinity¶
Pins the backend to the specified CPUs.
By default, the backend is not pinned to any CPU unless values are specified. It is recommended to pin the backend to shared non-critical CPUs.
Note
On macOS, only the first entry is used because the platform does not expose a per-core affinity API equivalent to Linux/Windows CPU masks.
Note
On Windows, CPU IDs are relative to the backend thread’s current processor group because this option uses SetThreadAffinityMask. Leave this empty and use a custom backend-thread hook if your application needs group-aware affinity.
-
std::function<void(std::string const&)> error_notifier = {detail::backend_options_default_error_notifier}¶
The backend may encounter exceptions that cannot be caught within user threads. In such cases, the backend invokes this callback to notify the user.
This function sets up a user error notifier to handle backend errors and notifications, such as when the unbounded queue reallocates or when the bounded queue becomes full.
To disable callback notifications, simply leave the function undefined: std::function<void(std::string const&)> backend_error_notifier = {};
Disabling this callback does not suppress Quill’s fallback formatting-error entries written to sinks. It only disables the callback notifications themselves.
It’s safe to perform logging operations within this function (e.g., LOG_INFO(…)). Calling logger->flush_log(), Backend::stop(), or Frontend::remove_logger_blocking() from the backend thread throws QuillError because the backend cannot wait on itself. If the logger has immediate flush enabled, the implicit flush is silently skipped for backend-thread log calls so generic logging code reused on the backend remains safe.
-
std::function<void()> backend_worker_on_poll_begin = {}¶
Optional hook executed by the backend worker thread at the start of each poll iteration. Any exceptions thrown are forwarded to error_notifier. Useful for thread instrumentation (e.g., Tracy). Use a guard if you need a one-time action. The same backend-thread flush behavior as error_notifier applies.
-
std::function<void()> backend_worker_on_poll_end = {}¶
Optional hook executed by the backend worker thread at the end of each poll iteration. Any exceptions thrown are forwarded to error_notifier. Useful for thread instrumentation (e.g., Tracy). Use a guard if you need a one-time action. The same backend-thread flush behavior as error_notifier applies.
-
std::chrono::milliseconds rdtsc_resync_interval = std::chrono::milliseconds{500}¶
This option is only applicable if at least one frontend is using a Logger with ClockSourceType::Tsc
When the system clock is used, this option can be ignored.
Controls the frequency at which the backend recalculates and syncs the internal RdtscClock with the system time from the system wall clock. The TSC clock can drift slightly over time and is not synchronized with NTP server updates.
Smaller values provide more accurate log timestamps at the cost of additional system clock calls. Changing this value only affects the performance of the backend worker.
-
std::chrono::milliseconds sink_min_flush_interval = std::chrono::milliseconds{200}¶
This option specifies the minimum time interval (in milliseconds) before the backend thread flushes the output buffers (flush_sink()) for all sinks in the application.
The backend thread will ensure that no sink is flushed more frequently than this interval. Explicit calls to
logger->flush_log()override this interval and trigger an immediate flush.However, if the backend thread is actively processing messages, flushing may occur less frequently than the specified interval.
Setting this value to 0 disables the feature, causing the backend thread to flush sinks whenever there is no pending work, provided a write to the sink has occurred.
This setting applies globally and affects all sinks in the application.
-
std::function<bool(char c)> check_printable_char = {detail::backend_options_default_check_printable_char}¶
This option enables a check that verifies the log message contains only printable characters before forwarding it to the sinks. This adds an extra layer of safety by filtering out non-printable characters from the log file. Any non-printable characters are converted to their equivalent hex value.
The check applies only when at least one argument in a log statement is of type string.
You can customize this callback to define your own range of printable characters if needed.
To disable this check, you can provide: std::function<bool(char c)> check_printable_char = {}
-
std::array<std::string, LogLevelCount> log_level_descriptions = {"TRACE_L3", "TRACE_L2", "TRACE_L1", "DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "CRITICAL", "BACKTRACE", "NONE"}¶
Holds descriptive names for various log levels used in logging operations. The indices correspond to LogLevel enum values defined elsewhere in the codebase. These names provide human-readable identifiers for each log level.
-
std::array<std::string, LogLevelCount> log_level_short_codes = {"T3", "T2", "T1", "D", "I", "N", "W", "E", "C", "BT", "_"}¶
Short codes or identifiers for each log level.
Provides short codes representing each log level for compact identification and usage. The indices correspond to LogLevel enum values defined elsewhere in the codebase.
-
std::string mdc_format_pattern = " [{}: {}, ]"¶
Format string used when rendering PatternFormatter’s
%(mdc).The string must contain exactly two “{}” placeholders. The text is split into four parts:
prefix: everything before the first “{}”
key-value separator: between the first and second “{}”
field separator: between the second “{}” and the last character
suffix: the last character
For example, the default “ [{}: {}, ]” renders: “ [request_id: 42, user: alice]”
When no MDC is set, %(mdc) expands to an empty string.
Invalid patterns are rejected with QuillError during backend initialization.
-
bool check_backend_singleton_instance = true¶
Enables a runtime check to detect multiple instances of the backend singleton.
When mixing shared and static libraries, linkage issues can lead to multiple instances of the backend singleton. This may result in multiple backend worker threads running simultaneously, causing unexpected behavior or crashes.
This issue commonly occurs on Windows when Quill is compiled as a static library and linked into both a shared library and the main executable, creating separate instances. While using Quill as a static library is generally recommended, in such cases, the preferred approach is to have one shared library own Quill and export/import its shared symbols consistently (for example, define
QUILL_DLL_EXPORTwhile building that DLL andQUILL_DLL_IMPORTin consumers on Windows).On Windows, this check is implemented using a named mutex, whereas on POSIX systems (Linux, macOS), it uses flock() on a lock file in /tmp. In rare cases, this mechanism may interfere with certain environments or containerized deployments. If necessary, this check can be disabled by setting this option to
false.Setting this option to
trueenables the check, while setting it tofalsedisables it.
-
std::string thread_name = "QuillBackend"¶
Backend Class¶
-
class Backend¶
Public Static Functions¶
-
static inline void start(BackendOptions const &options = BackendOptions{})¶
Starts the backend thread.
- Parameters:¶
- BackendOptions const &options = BackendOptions{}¶
Backend options to configure the backend behavior.
-
template<typename TFrontendOptions>
static inline void start(BackendOptions const &backend_options, SignalHandlerOptions const &signal_handler_options)¶ Starts the backend thread and initialises a signal handler.
Note
Enabling the built-in signal handler overrides the listed process signal handlers.
Note
When using the SignalHandler on Linux/MacOS, ensure that each spawned thread in your application has performed one of the following actions: i) Logged at least once. or ii) Called Frontend::preallocate(). or iii) Blocked signals on that thread to prevent the signal handler from running on it. This requirement is because the built-in signal handler utilizes the frontend queue state to issue log statements and wait for flushing. The queue is constructed on its first use with
new(). Failing to meet any of the above criteria means the queue may be first-constructed inside the signal handler, which is not signal-safe. Preallocating or logging once on those threads avoids that first-use allocation, but the built-in handler should still be treated as a best-effort crash-preservation facility rather than a general async-signal-safe logging API.Note
On Windows, Backend::start() installs structured exception and console control handlers. CRT signal handlers are thread-specific and must be installed explicitly with init_signal_handler<TFrontendOptions>() on each frontend/user thread that needs them, not on the backend worker thread.
- Parameters:¶
- BackendOptions const &backend_options¶
Backend options to configure the backend behavior.
- SignalHandlerOptions const &signal_handler_options¶
SignalHandler options to configure the signal handler behavior.
-
static inline void stop()¶
Stops the backend thread.
Note
On POSIX systems, when the built-in signal handler is enabled, this restores the Quill-managed signals to their default dispositions. It does not restore any previously installed user handlers.
Note
This function must not be called from backend-thread callbacks because it joins the backend worker thread.
Note
thread-safe
-
static inline void notify() noexcept¶
Notifies the backend thread to wake up. It is possible to use a long backend sleep_duration and then notify the backend to wake up from any frontend thread.
Note
thread-safe
-
static inline bool is_running() noexcept¶
Checks if the backend is currently running.
- Returns:¶
True if the backend is running, false otherwise.
-
static inline uint32_t get_thread_id() noexcept¶
Retrieves the ID of the backend thread.
- Returns:¶
The ID of the backend thread.
-
static inline uint64_t convert_rdtsc_to_epoch_time(uint64_t rdtsc_value)¶
Converts an rdtsc value to epoch time. This function uses the same clock as the backend and can be called from any frontend thread. It is useful when using a logger with ClockSourceType::Tsc and you want to obtain a timestamp synchronized with the log files generated by the backend.
Alternatively you can use the Clock class from backend/Clock.h
-
static inline ManualBackendWorker *acquire_manual_backend_worker()¶
This feature is designed for advanced users who need to run the backend worker on their own thread, providing more flexibility at the cost of complexity and potential pitfalls.
This approach is generally not recommended due to the potential for inefficiency and complexity in managing the backend worker outside the provided mechanisms.
Important notes:
Do not use this to run the library in a single threaded application. This will lead to inefficiencies. The design of this logging library assumes that the backend worker operates in a separate thread from the frontend threads that issue log statements.
The thread running the
ManualBackendWorkercan log, but it must not use backend-waiting flush paths from that same thread. SeeManualBackendWorkerfor the manual-backend threading contract.The
ManualBackendWorkershould only be used by a single thread. It is not designed to handle multiple threads callingpoll()simultaneously.You must call
ManualBackendWorker::shutdown()explicitly from the same thread that calledinit()before that thread exits. Do not rely on theManualBackendWorkerdestructor for shutdown ordering.The built-in signal handler is not set up with
ManualBackendWorker. If signal handling is required, you must manually set up the signal handler and block signals from reaching theManualBackendWorkerthread. See thestart<FrontendOptions>(BackendOptions, SignalHandlerOptions)implementation for guidance on how to do this.The following options are not supported when using
ManualBackendWorker:cpu_affinity,thread_name,sleep_duration, andenable_yield_when_idle.Avoid performing very heavy tasks in your custom thread. Significant delays in calling
poll()can lead to the SPSC queues of the frontend threads becoming full. When this happens, the frontend threads may need to allocate additional memory on the hot path.
std::thread backend_worker([]() { quill::ManualBackendWorker* manual_backend_worker = quill::Backend::acquire_manual_backend_worker(); quill::BackendOptions backend_options; manual_backend_worker->init(backend_options); while (running) { manual_backend_worker->poll(); } manual_backend_worker->shutdown(); });
-
static inline void start(BackendOptions const &options = BackendOptions{})¶
BackendTscClock Class¶
-
class BackendTscClock¶
A utility class for accessing the Time Stamp Counter (TSC) clock used by the backend logging thread.
This class provides access to the TSC clock maintained by the backend logging thread, allowing for synchronized timestamp retrieval.
Other threads can obtain timestamps synchronized with the TSC clock of the backend logging thread, ensuring synchronization with log statement timestamps.
If
ClockSourceType::Tscis not used by any Logger, this class reverts to using the system clock for providing a timestamp.Note
For more accurate timestamps, consider reducing
rdtsc_resync_intervalinBackendOptions.Note
All methods of the class are thread-safe.
Public Static Functions¶
-
static inline time_point now()¶
Provides the current synchronized timestamp obtained using the TSC clock maintained by the backend logging thread.
-
static inline RdtscVal rdtsc() noexcept¶
Returns the current value of the TSC timer maintained by the backend logging thread.
- Returns:¶
The current value of the TSC timer.
-
static inline time_point to_time_point(RdtscVal rdtsc)¶
Converts a TSC (Time Stamp Counter) value to a wall clock timestamp.
Warning
This function will return
0if no Logger with a TSC clock source has been used. The TSC clock is initialized by the backend thread when the first log statement is processed, provided that a TSC-based logger is used. If the backend thread has not processed any log statements, the function may return zero.
-
class RdtscVal¶
-
static inline time_point now()¶
SignalHandler Options¶
-
struct SignalHandlerOptions¶
Struct to hold options for the signal handler.
Public Members¶
-
std::vector<int> catchable_signals = {SIGTERM, SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV}¶
List of signals that the backend should catch if with_signal_handler is enabled. Enabling the built-in signal handler overrides the process handlers for these signals. On Windows, Backend::start() does not consume this list; pass the desired signals to init_signal_handler<TFrontendOptions>() on each thread that needs CRT signal handling.
-
uint32_t timeout_seconds = 20u¶
Defines the timeout duration in seconds for the signal handler alarm. It is only available on Linux, as Windows does not support the alarm function. The signal handler sets up an alarm to ensure that the process will terminate if it does not complete within the specified time frame. This is particularly useful to prevent the process from hanging indefinitely in case the signal handler encounters an issue.
-
std::string logger_name¶
The name of the logger instance that the signal handler will use to log errors when the application crashes. The logger is accessed by the signal handler and must be created by your application using Frontend::create_or_get_logger(…). If this parameter is left empty, the signal handler will automatically select the first valid logger it finds, excluding any loggers whose names contain substrings specified in excluded_logger_substrings. If a logger name is specified but not found, the signal handler will fall back to the automatic selection behavior described above.
-
std::vector<std::string> excluded_logger_substrings = {"__csv__"}¶
List of substrings used to exclude loggers during automatic logger selection. This option is only used when logger_name is empty or when the specified logger is not found. The signal handler will skip any logger whose name contains any of these substrings. This is useful to avoid selecting specialized loggers that write to CSV files, binary files, or other non-standard formats that may not be suitable for crash reporting. Default: {“__csv__”} to exclude CSV loggers.
-
std::vector<int> catchable_signals = {SIGTERM, SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV}¶
Frontend Options¶
-
struct FrontendOptions¶
Frontend options are expressed as a traits type.
To override only a subset of options, derive from FrontendOptions and redeclare only the members that change. New members added to FrontendOptions will then be inherited automatically unless the derived type explicitly overrides them.
struct CustomFrontendOptions : FrontendOptions { static constexpr QueueType queue_type = QueueType::BoundedDropping; static constexpr size_t initial_queue_capacity = 256u * 1024u; };Note
FrontendOptions are intended to be an application-wide choice. Mixing different FrontendImpl<TFrontendOptions> or LoggerImpl<TFrontendOptions> specializations is not a supported configuration. Use one frontend specialization consistently throughout the application.
Public Static Attributes¶
-
static QueueType queue_type = QueueType::UnboundedBlocking¶
Each frontend thread has its own queue, which can be configured with various options:
UnboundedBlocking: Starts with initial_queue_capacity and reallocates up to unbounded_queue_max_capacity, then blocks.
UnboundedDropping: Starts with initial_queue_capacity and reallocates up to unbounded_queue_max_capacity, then drops log messages.
BoundedBlocking: Starts with initial_queue_capacity and never reallocates; blocks when the limit is reached. A single message larger than the fixed queue capacity cannot fit and fails instead of blocking forever.
BoundedDropping: Starts with initial_queue_capacity and never reallocates; drops log messages when the limit is reached.
By default, the library uses an UnboundedBlocking queue, which starts with initial_queue_capacity.
-
static size_t initial_queue_capacity = 128u * 1024u¶
Initial capacity of the queue.
-
static uint32_t blocking_queue_retry_interval_ns = 800¶
Interval for retrying when using BoundedBlocking or UnboundedBlocking. Applicable only when using BoundedBlocking or UnboundedBlocking.
-
static size_t unbounded_queue_max_capacity = 2ull * 1024u * 1024u * 1024u¶
Maximum capacity for unbounded queues (UnboundedBlocking, UnboundedDropping). This defines the maximum size to which the queue can grow before blocking or dropping messages.
-
static HugePagesPolicy huge_pages_policy = HugePagesPolicy::Never¶
Enables huge pages on the frontend queues to reduce TLB misses. Available only for Linux.
-
static QueueType queue_type = QueueType::UnboundedBlocking¶
Frontend Class¶
-
template<typename TFrontendOptions>
class FrontendImpl¶ Public Static Functions¶
-
static inline void preallocate()¶
Pre-allocates the thread-local data needed for the current thread.
Although optional, it is recommended to invoke this function during the thread initialization phase before the first log message.
-
static inline void shrink_thread_local_queue(size_t capacity)¶
Shrink the thread-local SPSC queue to the specified target capacity.
This function helps manage memory usage by reducing the size of the thread-local queue. In scenarios where a thread pool executes multiple jobs, one job might log a burst of messages that causes the queue to grow significantly. Subsequent jobs may not require such a large capacity, so you can call this function to explicitly shrink the queue to a smaller size.
Note
This function only applies when using the UnboundedQueue configuration. It will have no effect if the BoundedQueue is enabled.
Note
The function will only shrink the queue if the provided target capacity is smaller than the current queue capacity. If the target capacity is greater than or equal to the current capacity, no change is made.
Warning
The Logger object may maintain multiple thread-local queues. This function will only shrink the queue associated with the calling thread, so it is important that the appropriate thread invokes it.
-
static inline size_t get_thread_local_queue_capacity() noexcept¶
Retrieve the current capacity of the thread-local SPSC queue.
This function returns the capacity of the SPSC queue that belongs to the calling thread. It is particularly useful for monitoring how much an UnboundedQueue has grown over time, while for a BoundedQueue, the capacity remains constant.
Note
When using an UnboundedQueue, the function returns the capacity as determined by the producer, reflecting the dynamic growth of the queue. For a BoundedQueue, the returned capacity is fixed.
Note
Since the Logger object can maintain multiple thread-local queues, this function always returns the capacity of the queue associated with the thread that calls it. Ensure that the correct thread is invoking this function to check its own queue.
- Returns:¶
The current capacity of the thread-local SPSC queue.
Creates a new sink with the specified name.
The name of the sink.
The arguments to pass to the sink constructor.
QuillError– if a sink with the same name already exists.std::shared_ptr<Sink> A shared pointer to the created sink.
Creates a new sink or retrieves an existing one with the specified name.
Note
If a sink with the specified name already exists, the existing sink is returned and the provided constructor arguments are ignored.
The name of the sink.
The arguments to pass to the sink constructor.
std::shared_ptr<Sink> A shared pointer to the created or retrieved sink.
-
static inline std::shared_ptr<Sink> get_sink(std::string const &sink_name)¶
Retrieves an existing sink with the specified name.
-
static inline MetricMetadata const *create_metric(std::string const &metric_key, std::string const &metric_name, std::vector<MetricLabel> const &labels = {})¶
Registers a new runtime metric and returns owned metadata for it.
The MetricManager owns the returned MetricMetadata for the process lifetime, so the returned pointer is stable and can be passed directly to QUILL_METRIC / logger->publish_metric().
metric_keyis Quill’s unique registration and lookup key for the metric metadata.metric_namemust be non-empty but does not need to be unique, so multiple metric keys may reuse the same name when that fits the sink’s export model.- Throws:¶
QuillError– ifmetric_keyhas already been registered.
-
static inline MetricMetadata const *create_or_get_metric(std::string const &metric_key, std::string const &metric_name, std::vector<MetricLabel> const &labels = {})¶
Registers a runtime metric or returns the existing MetricMetadata pointer.
metric_keyis the unique identifier.metric_namemust be non-empty but is not required to be unique.If a metric with the same
metric_keyalready exists, the existing pointer is returned unchanged andmetric_nameandlabelsare ignored. Use create_metric() if you need strict registration by unique key.
-
static inline MetricMetadata const *get_metric(std::string const &metric_key)¶
Looks up an existing metric.
Creates a new logger with the specified name.
The name of the logger.
A shared pointer to the sink to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
QuillError– if a logger with the same name already exists or is pending removal.Logger* A pointer to the created logger.
Creates a new logger with the specified name and multiple sinks.
The name of the logger.
A vector of shared pointers to sinks to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
QuillError– if a logger with the same name already exists or is pending removal.Logger* A pointer to the created logger.
Creates a new logger with the specified name and multiple sinks.
The name of the logger.
An initializer list of shared pointers to sinks to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
QuillError– if a logger with the same name already exists or is pending removal.Logger* A pointer to the created logger.
Creates a new logger or retrieves an existing one with the specified name.
Note
If a logger with the specified name already exists, the existing logger is returned and the provided sinks, pattern, clock source, and user clock parameters are ignored.
Note
Recreating a logger with the same name while a previous logger is still pending asynchronous removal will throw
QuillError. Use remove_logger_blocking() when you need synchronous removal before recreating a logger.The name of the logger.
A shared pointer to the sink to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
Logger* A pointer to the created or retrieved logger.
Creates a new logger or retrieves an existing one with the specified name and multiple sinks.
Note
If a logger with the specified name already exists, the existing logger is returned and the provided sinks, pattern, clock source, and user clock parameters are ignored.
Note
Recreating a logger with the same name while a previous logger is still pending asynchronous removal will throw
QuillError. Use remove_logger_blocking() when you need synchronous removal before recreating a logger.The name of the logger.
A vector of shared pointers to sinks to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
Logger* A pointer to the created or retrieved logger.
Creates a new logger or retrieves an existing one with the specified name and multiple sinks.
Note
If a logger with the specified name already exists, the existing logger is returned and the provided sinks, pattern, clock source, and user clock parameters are ignored.
Note
Recreating a logger with the same name while a previous logger is still pending asynchronous removal will throw
QuillError. Use remove_logger_blocking() when you need synchronous removal before recreating a logger.The name of the logger.
An initializer list of shared pointers to sinks to associate with the logger.
Contains the formatting configuration for PatternFormatter
The clock source for log timestamps.
A pointer to a custom user clock.
Logger* A pointer to the created or retrieved logger.
-
static inline logger_t *create_or_get_logger(std::string const &logger_name, detail::LoggerBase *source_logger = nullptr)¶
Creates a new logger or retrieves an existing one that shares the same options as the specified logger.
This function allows you to create or obtain a logger identified by
logger_name. If a logger with the same name already exists, its configuration options will be used. If it does not exist, a new logger will be created with the same options as the providedsource_logger.Note
Recreating a logger with the same name while a previous logger is still pending asynchronous removal will throw
QuillError. Use remove_logger_blocking() when you need synchronous removal before recreating a logger.
-
static inline void remove_logger(detail::LoggerBase *logger)¶
Asynchronously removes the specified logger.
When a logger is removed, if its underlying sinks are not shared by any other logger, they are destructed, and any associated files are also closed.
A common use case for this function is when you want to close the underlying files that the logger is using.
Since the exact removal timing is unknown, you should not attempt to create a new logger with the same name as the one being removed.
Note
This function is thread-safe. However, removing the same logger (
logger_t*) from multiple threads is not allowed. You must ensure that remove_logger is only called by a single thread for a given logger.Warning
After calling this function, no thread should use this logger.
-
static inline void remove_logger_blocking(logger_t *logger, uint32_t sleep_duration_ns = 100)¶
Asynchronously removes the specified logger and blocks until removal is complete.
When a logger is removed, any files associated with its sinks are also closed.
A use case for this function is when you want to change the sinks of a logger. You can call this function to remove the logger and then recreate it with new sinks and the same name. However, no other threads should be using the logger after the call to this function.
Note
This function is thread-safe. However, removing the same logger (
logger_t*) from multiple threads is not allowed. You must ensure that remove_logger_blocking is only called by a single thread for a given logger.Note
This function should only be called when the backend worker is running after Backend::start(…).
Note
This function must not be called from backend-thread callbacks because it waits for the backend worker.
Warning
After calling this function, no thread should use this logger.
-
static inline logger_t *get_logger(std::string const &logger_name)¶
Retrieves an existing logger with the specified name.
Note
Returns nullptr on miss on purpose so callers can check for a removed logger without catching an exception (e.g., after the async remove_logger() path). get_sink() and get_metric() are stricter and throw — they have no comparable use case for an expected miss.
-
static inline std::vector<logger_t*> get_all_loggers()¶
Retrieves a map of all registered valid loggers.
Note
If
remove_logger()is called from this or another thread, the return value of this function will become invalid.- Returns:¶
A vector containing all registered loggers.
-
static inline logger_t *get_valid_logger() noexcept¶
Returns the first valid logger that is found. This is useful when you do not want to use the std::vector<logger_t*> return value of get_all_loggers.
- Returns:¶
A pointer to the first valid logger, or nullptr if no valid logger is found.
-
static inline size_t get_number_of_loggers() noexcept¶
Counts the number of existing loggers, including any invalidated loggers. This function can be useful for verifying if a logger has been removed after calling remove_logger() by the backend, as removal occurs asynchronously.
- Returns:¶
The number of loggers.
-
static inline void preallocate()¶
Frontend Alias¶
-
using Frontend = FrontendImpl<FrontendOptions>¶
MetricLabel Struct¶
-
struct MetricLabel¶
MetricMetadata Class¶
-
class MetricMetadata : public MacroMetadata¶
MetricMetadata extends MacroMetadata so the existing header-encoding path can carry it in the
macro_metadataslot on the SPSC queue. It is markedfinalbecause MacroMetadata has no virtual destructor: any future owner ofunique_ptr<MacroMetadata>pointing at a MetricMetadata would slice or leak. MetricManager storesunique_ptr<MetricMetadata>directly, so there is no slicing today.
Log Levels¶
-
enum class LogLevel : uint8_t¶
Log level enum.
The TraceL* levels form a trace-only verbosity band:
TraceL3 is the most detailed trace level
TraceL2 is the middle trace level
TraceL1 is the least detailed trace level
Values:
-
enumerator TraceL3¶
-
enumerator TraceL2¶
-
enumerator TraceL1¶
-
enumerator Debug¶
-
enumerator Info¶
-
enumerator Notice¶
-
enumerator Warning¶
-
enumerator Error¶
-
enumerator Critical¶
-
enumerator Backtrace¶
This is only used for backtrace logging. Should not be set by the user.
-
enumerator None¶
LoggerImpl Class¶
-
template<typename TFrontendOptions>
class LoggerImpl : public detail::LoggerBase¶ Thread safe logger.
Logger must be obtained from create_or_get_logger(), therefore, constructors are private
Public Functions¶
-
template<bool enable_immediate_flush, typename ...Args>
inline bool log_statement(MacroMetadata const *macro_metadata, Args&&... fmt_args)¶ Push a log message to the spsc queue to be logged by the backend thread. One spsc queue per caller thread. This function is enabled only when all arguments are fundamental types. This is the fastest way possible to log
Note
This function is thread-safe.
-
inline bool publish_metric(MetricMetadata const *metric_metadata, double value)¶
Push a compact metric sample to the spsc queue to be processed by the backend thread. The queue stores only the value. Static metric identity and labels are carried by MetricMetadata via the existing MacroMetadata pointer in the event header.
Metrics never participate in logger immediate-flush behavior; sinks decide their own flush or batching strategy on the backend thread.
Note
This function is thread-safe.
- Parameters:¶
- MetricMetadata const *metric_metadata¶
metadata of the metric event
- double value¶
metric value
- Returns:¶
true if the metric sample is written to the queue, false if it is dropped
-
template<typename ...Args>
inline void set_mdc(Args&&... args)¶ Sets or replaces one or more MDC fields for the calling thread.
The supplied fields are propagated asynchronously to the backend thread and then appended to subsequent log messages from the same frontend thread until erased or cleared.
This operation is not on the hot path. If a dropping queue is configured and is temporarily full, this function retries until the control event is queued.
-
template<typename ...Keys>
inline void erase_mdc(Keys&&... keys)¶ Erases one or more MDC fields for the calling thread.
Missing keys are ignored. The operation retries until queued when a dropping queue is temporarily full.
-
inline void clear_mdc()¶
Clears all MDC fields for the calling thread.
The operation retries until queued when a dropping queue is temporarily full.
-
template<bool enable_immediate_flush, typename ...Args>
inline bool log_statement_runtime_metadata(MacroMetadata const *macro_metadata, char const *fmt, char const *file_path, char const *function_name, char const *tags, uint32_t line_number, LogLevel log_level, Args&&... fmt_args)¶ Push a log message with runtime metadata to the spsc queue to be logged by the backend thread.
Similar to log_statement but allows passing metadata that is only available at runtime.
Note
This function is thread-safe.
- Parameters:¶
- MacroMetadata const *macro_metadata¶
Metadata of the log message
- char const *fmt¶
Format string for the log message
- char const *file_path¶
Source file path where the log statement was called
- char const *function_name¶
Function name where the log statement was called
Optional tags associated with the log message
- uint32_t line_number¶
Line number in the source file
- LogLevel log_level¶
Severity level of the log message
- Args&&... fmt_args¶
Format arguments for the log message
- Returns:¶
true if the message is written to the queue, false if it is dropped (when a dropping queue is used)
-
inline void init_backtrace(uint32_t max_capacity, LogLevel flush_level = LogLevel::None)¶
Init a backtrace for this logger. Stores messages logged with LOG_BACKTRACE in a ring buffer and displays them later on demand.
- Parameters:¶
-
inline void flush_backtrace()¶
Dump any stored backtrace messages
-
inline void flush_log(uint32_t sleep_duration_ns = 100)¶
Blocks the calling thread until all log messages up to the current timestamp are flushed.
The backend thread will invoke the write operation on all sinks for all loggers up to the point (timestamp) when this function is invoked.
Note
This function should only be called when the backend worker is running after Backend::start(…)
Note
This function will block the calling thread until the flush message is processed by the backend thread. The calling thread can block for up to backend_options.sleep_duration. If you configure a custom long sleep duration on the backend thread, e.g., backend_options.sleep_duration = std::chrono::minutes{1}, then you should ideally avoid calling this function as you can block for long period of times unless you use another thread that calls Backend::notify()
Warning
Do not call this function from the destructor of a static object. This may lead to application crashes if the thread-local ThreadContext is destroyed before the static object invoking
flush_log.
-
template<bool enable_immediate_flush, typename ...Args>
Logger Alias¶
-
using Logger = LoggerImpl<FrontendOptions>¶
PatternFormatter Class¶
-
class PatternFormatter¶
Public Types¶
Public Functions¶
-
inline explicit PatternFormatter(PatternFormatterOptions options)¶
Main PatternFormatter class Constructor for a PatternFormatter with custom formatting options.
See also
PatternFormatterOptions for detailed information on available options.
- Parameters:¶
- PatternFormatterOptions options¶
The PatternFormatterOptions object containing the formatting configuration.
- Throws:¶
std::invalid_argument– if the format string in options is invalid
-
inline explicit PatternFormatter(PatternFormatterOptions options)¶
PatternFormatterOptions Class¶
-
class PatternFormatterOptions¶
Configuration options for the PatternFormatter.
This class encapsulates the configuration options used to customize the formatting of log messages.
Public Members¶
-
std::string format_pattern = {default_format_pattern}¶
The format pattern for log messages.
This string defines the overall structure of each log message.
It can include various placeholders that will be replaced with actual values when formatting the log message.
%(time) - Human-readable timestamp representing when the log statement was created. %(file_name) - Name of the source file where the logging call was issued. %(full_path) - Full path of the source file where the logging call was issued. %(caller_function) - Name of the function containing the logging call. %(log_level) - Textual representation of the logging level for the message. %(log_level_short_code) - Abbreviated log level name. %(line_number) - Line number in the source file where the logging call was issued. %(logger) - Name of the logger used to log the call. %(message) - The logged message itself. %(thread_id) - ID of the thread in which the logging call was made. %(thread_name) - Name of the thread. Must be set before the first log statement on that thread. %(process_id) - ID of the process in which the logging call was made. %(source_location) - Full source file path and line number as a single string. %(short_source_location) - Shortened source file name and line number as a single string. %(tags) - Additional custom tags appended to the message when _TAGS macros are used. %(mdc) - The backend-formatted MDC block for the calling thread. Empty when no MDC is set. %(named_args) - Key-value pairs appended to the message. Only applicable when the message has named args; remains empty otherwise.
Warning
The same attribute cannot be used twice in the same format pattern.
-
std::string timestamp_pattern = {"%H:%M:%S.%Qns"}¶
The format pattern for timestamps.
This string defines how timestamps are formatted in log messages. It follows the strftime() format with additional specifiers:
Qms : Milliseconds
Qus : Microseconds
Qns : Nanoseconds
-
std::string source_location_path_strip_prefix = {}¶
Sets a path prefix to be stripped from source location paths.
When set, the last occurrence of this prefix in the source location path is removed:
For example, with prefix “/home/user/”, a path like “/home/user/project/test.cpp:5” would be displayed as “project/test.cpp:5”
The same also works with a shorter marker such as “project”, which would also produce “test.cpp:5” or “subdir/test.cpp:5” depending on the remaining suffix
If empty (default), the full path is shown
This affects only the %(source_location) attribute.
-
std::string_view (*process_function_name)(char const*)¶
Function pointer for custom processing of detailed function names for %(caller_function).
This is most useful when QUILL_DETAILED_FUNCTION_NAME is enabled, as it allows custom processing of the detailed function signature provided by the compiler.
Since the format of PRETTY_FUNCTION or equivalent is compiler-specific, this function allows users to implement their own parsing/formatting logic.
The function takes one parameter:
The raw function signature string from the compiler (e.g., from PRETTY_FUNCTION)
It should return a string_view representing the processed function name.
If set to nullptr (default), the logger will use the unprocessed function name as provided by the compiler.
-
Timezone timestamp_timezone = {Timezone::LocalTime}¶
The timezone to use for timestamps.
Determines whether timestamps are formatted in local time or GMT.
-
bool add_metadata_to_multi_line_logs = {true}¶
Whether to add metadata to each line of multi-line log messages.
If true, ensures that metadata (e.g., timestamp, log level) is added to every line of multi-line log entries, maintaining consistency across all log outputs.
-
bool source_location_remove_relative_paths = {false}¶
Whether to remove relative path components from source location paths.
If true, relative path components like “../” will be processed and removed from source location paths, simplifying the displayed path.
This affects only the %(source_location) attribute.
-
char pattern_suffix = {'\n'}¶
Character to append at the end of each formatted log pattern.
This character is appended to the formatted log message pattern.
If set to a character (e.g., ‘
’), that character will be appended
If set to NO_SUFFIX, no character will be appended
-
std::string format_pattern = {default_format_pattern}¶
Sink Class¶
-
class Sink¶
Base class for sinks
Subclassed by NullSink, PrometheusSink, StreamSink
Public Functions¶
-
inline explicit Sink(std::optional<PatternFormatterOptions> override_pattern_formatter_options = std::nullopt)¶
Constructor Uses the default pattern formatter
-
virtual ~Sink() = default¶
Destructor
-
inline void set_log_level_filter(LogLevel log_level)¶
Sets a log level filter on the sink.
Note
Thread safe.
-
inline explicit Sink(std::optional<PatternFormatterOptions> override_pattern_formatter_options = std::nullopt)¶
Filter Class¶
-
class Filter¶
Base filter class. Filters can be added to Sinks
Public Functions¶
-
inline explicit Filter(std::string filter_name)¶
Constructor
-
virtual ~Filter() = default¶
Destructor
-
virtual bool filter(MacroMetadata const *log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, std::string_view logger_name, LogLevel log_level, std::string_view log_message, std::string_view log_statement) noexcept = 0¶
Filters a log message.
- Parameters:¶
- MacroMetadata const *log_metadata¶
Pointer to the macro metadata.
- uint64_t log_timestamp¶
Timestamp of the log event.
- std::string_view thread_id¶
ID of the thread.
- std::string_view thread_name¶
Name of the thread.
- std::string_view logger_name¶
Name of the logger.
- LogLevel log_level¶
Log level of the message.
- std::string_view log_message¶
The log message.
- std::string_view log_statement¶
The log statement.
- Returns:¶
true if the log message should be written to the file, false otherwise
-
inline explicit Filter(std::string filter_name)¶
FileSinkConfig Class¶
-
class FileSinkConfig¶
The FileSinkConfig class holds the configuration options for the FileSink
Subclassed by RotatingFileSinkConfig
Public Functions¶
-
inline void set_filename_append_option(FilenameAppendOption value, std::string_view append_filename_format_pattern = std::string_view{})¶
Sets the append type for the file name. Possible append types are: StartDate, StartDateTime or None. When this option is set, the file name will be appended with the start date or date and time timestamp of when the process started.
For example: application.log -> application_20230101.log (StartDate) application.log -> application_20230101_121020.log (StartDateTime)
- Parameters:¶
- FilenameAppendOption value¶
The append type to set. Valid options are None, StartDate, StartDateTime, and StartCustomTimestampFormat.
- std::string_view append_filename_format_pattern = std::string_view{}¶
Specifies a custom
strftimeformat pattern to use for the filename. This parameter is only applicable whenFilenameAppendOption::StartCustomTimestampFormatis selected
-
inline void set_timezone(Timezone time_zone)¶
Sets the timezone to use for time-based operations e.g. when appending the date to the get_filename or when setting the logging pattern. Valid options for the timezone are ‘LocalTime’ or ‘GmtTime’ The default value is ‘LocalTime’.
-
inline void set_fsync_enabled(bool value)¶
Sets whether fsync should be performed when flushing. The default value is false.
Note
On macOS, fsync() flushes data to the disk controller’s write cache but does not guarantee write-through to persistent storage.
-
inline void set_write_buffer_size(size_t value)¶
Sets the user-defined buffer size for fwrite operations.
This function allows you to specify a custom buffer size for fwrite, improving efficiency for file write operations.
To disable custom buffering and revert to the default size, pass a value of 0.
Note
By default, a buffer size of 64 KB is used.
-
inline void set_minimum_fsync_interval(std::chrono::milliseconds value)¶
Sets the minimum interval between
fsynccalls. This specifies the minimum time between consecutivefsyncoperations but does not guarantee thatfsyncwill be called exactly at that interval.For example, if some messages are flushed to the log and
fsyncis skipped because it was previously called, and no further messages are written to the file,fsyncwill not be called even if the minimum interval has passed. This is because the previous call was skipped due to the interval, and no new messages necessitate anotherfsynccall.This feature is intended to mitigate concerns about frequent
fsynccalls potentially causing disk wear.Note: This option is only applicable when
fsyncis enabled. By default, the value is 0, which means thatfsyncwill be called periodically by the backend worker thread when messages are written to the file, irrespective of the interval.
-
inline void set_override_pattern_formatter_options(std::optional<PatternFormatterOptions> const &options)¶
Sets custom pattern formatter options for this sink.
By default, the logger’s pattern formatter is used to format log messages. This function allows overriding the default formatter with custom options for this specific sink. If a custom formatter is provided, it will be used instead of the logger’s formatter.
- Parameters:¶
- std::optional<PatternFormatterOptions> const &options¶
The custom pattern formatter options to use
-
inline bool fsync_enabled() const noexcept¶
Getters
-
inline void set_filename_append_option(FilenameAppendOption value, std::string_view append_filename_format_pattern = std::string_view{})¶
FileSink Class¶
-
class FileSink : public StreamSink¶
Keep the Windows-specific FileSink split isolated under _WIN32. A previous attempt to share a FileSinkBase across all platforms introduced a measurable Linux throughput regression in BENCHMARK_quill_backend_throughput despite equivalent logic. If this is revisited, revalidate Linux performance. FileSink Writes the log messages to a file
Subclassed by RotatingSink< FileSink >, detail::JsonSink< FileSink >
File Event Types¶
-
using FileEventNotifierHandle = FILE*¶
-
struct FileEventNotifier¶
Notifies on file events by calling the appropriate callback.
Note
before_writeexecutes as part of the normal log write path.before_open,after_open,before_close, andafter_closeexecute on the thread performing 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.
RotatingSink Class¶
-
template<typename TBase>
class RotatingSink : public TBase¶ The RotatingSink class.
Public Functions¶
-
inline RotatingSink(fs::path const &filename, RotatingFileSinkConfig const &config, FileEventNotifier file_event_notifier = FileEventNotifier{}, std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now())¶
Constructor.
Creates a new instance of the RotatingSink class.
- Parameters:¶
- fs::path const &filename¶
The base file name to be used for logs.
- RotatingFileSinkConfig const &config¶
The sink configuration.
- FileEventNotifier file_event_notifier = FileEventNotifier{}¶
file event notifier
- std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now()¶
start time
-
inline void write_log(MacroMetadata const *log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, std::string const &process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector<std::pair<std::string, std::string>> const *named_args, std::string_view log_message, std::string_view log_statement) override¶
Writes a formatted log message to the stream.
- Parameters:¶
- MacroMetadata const *log_metadata¶
The metadata of the log message
- uint64_t log_timestamp¶
The timestamp of the log message
- std::string_view thread_id¶
The ID of the thread that generated the log message
- std::string_view thread_name¶
The name of the thread that generated the log message
- std::string const &process_id¶
Process Id
- std::string_view logger_name¶
logger name
- LogLevel log_level¶
Log level of the message.
- std::string_view log_level_description¶
Description of the log level.
- std::string_view log_level_short_code¶
Short code representing the log level.
- std::vector<std::pair<std::string, std::string>> const *named_args¶
Structured key-value pairs associated with the log message
- std::string_view log_message¶
The log message to write
- std::string_view log_statement¶
The full log statement
-
inline RotatingSink(fs::path const &filename, RotatingFileSinkConfig const &config, FileEventNotifier file_event_notifier = FileEventNotifier{}, std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now())¶
RotatingFileSinkConfig Class¶
-
class RotatingFileSinkConfig : public FileSinkConfig¶
The configuration options for the RotatingSink.
Public Types¶
Public Functions¶
-
inline RotatingFileSinkConfig()¶
Constructs a new RotatingFileSinkConfig object.
-
inline void set_rotation_frequency_and_interval(char frequency, uint32_t interval)¶
Sets the frequency and interval of file rotation.
-
inline void set_rotation_time_daily(std::string const &daily_rotation_time_str)¶
Sets the time of day for daily log file rotation.
-
inline void set_max_backup_files(uint32_t value)¶
Sets the maximum number of log files to keep. When the sink starts in append mode, rotated files left behind by previous runs are also counted towards this limit and the oldest ones are removed on startup, unless set_overwrite_rolled_files() is set to false.
-
inline void set_overwrite_rolled_files(bool value)¶
Sets whether the oldest rolled logs should be overwritten when the maximum backup count is reached. If set to false, the oldest logs will not be overwritten when the maximum backup count is reached, and log file rotation will stop. The default value is true.
-
inline void set_remove_old_files(bool value)¶
Sets whether previous rotated log files should be removed on process start up.
Note
This option works only when using the mode=”w” This is useful to avoid conflicting file names when the process restarts and FilenameAppendOption::StartDateTime was not set. The default value is true.
-
inline void set_rotation_naming_scheme(RotationNamingScheme value)¶
Sets the naming scheme for the rotated files. The default value is ‘Index’.
- Parameters:¶
- RotationNamingScheme value¶
The naming scheme to set.
-
inline void set_rotation_on_creation(bool value)¶
Sets whether to force rotation on file sink creation/startup. When enabled, if a log file with the same name exists on startup, it will be rotated according to the RotationNamingScheme before starting to write new logs. This allows creating a new log file for every program run. The default value is false.
-
inline size_t rotation_max_file_size() const noexcept¶
Getter methods
-
inline RotatingFileSinkConfig()¶
RotatingFileSink Alias¶
-
using RotatingFileSink = RotatingSink<FileSink>¶
JsonFileSink Class¶
-
class JsonFileSink : public detail::JsonSink<FileSink>¶
JSON File Sink
Subclassed by RotatingSink< JsonFileSink >
RotatingJsonFileSink Alias¶
-
using RotatingJsonFileSink = RotatingSink<JsonFileSink>¶
JsonConsoleSink Class¶
-
class JsonConsoleSink : public detail::JsonSink<StreamSink>¶
JSON Console Sink
StreamSink Class¶
-
class StreamSink : public Sink¶
StreamSink class for handling log messages.
Subclassed by detail::JsonSink< StreamSink >, ConsoleSink, FileSink
Public Functions¶
-
inline explicit StreamSink(fs::path stream, FILE *file = nullptr, std::optional<PatternFormatterOptions> const &override_pattern_formatter_options = std::nullopt, FileEventNotifier file_event_notifier = FileEventNotifier{})¶
Constructor for StreamSink.
- Parameters:¶
- fs::path stream¶
The stream type (stdout, stderr, or file)
- std::optional<PatternFormatterOptions> const &override_pattern_formatter_options = std::nullopt¶
override the logger pattern formatter
- FILE *file = nullptr¶
File pointer for file-based stream
- FileEventNotifier file_event_notifier = FileEventNotifier{}¶
Notifies on file events
- Throws:¶
QuillError– if an invalid parameter is provided
-
inline virtual void write_log(MacroMetadata const*, uint64_t, std::string_view, std::string_view, std::string const&, std::string_view, LogLevel, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view, std::string_view log_statement) override¶
Writes a formatted log message to the stream.
-
inline virtual void flush_sink() override¶
Flushes the stream
-
inline explicit StreamSink(fs::path stream, FILE *file = nullptr, std::optional<PatternFormatterOptions> const &override_pattern_formatter_options = std::nullopt, FileEventNotifier file_event_notifier = FileEventNotifier{})¶
ConsoleSinkConfig Class¶
-
class ConsoleSinkConfig¶
Public Functions¶
-
inline void set_colours(Colours colours)¶
Sets custom colours for each log level.
This function allows specifying a custom Colours instance, enabling fine-grained control over the colours used for different log levels in the console output.
-
inline void set_colour_mode(ColourMode colour_mode)¶
Sets the colour mode for console output.
This function determines when colours are applied in the console output. Valid options for the colour mode are:
Always: Colours are always enabled.
Automatic: Colours are enabled automatically based on the environment (e.g., terminal support).
Never: Colours are never enabled.
The default value is ‘Automatic’.
-
inline void set_stream(std::string const &stream)¶
Sets the output stream for console logging.
This function allows selecting the output stream where log messages should be printed. The valid options are:
”stdout”: Logs are printed to the standard output.
”stderr”: Logs are printed to the standard error.
The default value is “stdout”.
-
inline void set_override_pattern_formatter_options(std::optional<PatternFormatterOptions> const &options)¶
Sets custom pattern formatter options for this sink.
By default, the logger’s pattern formatter is used to format log messages. This function allows overriding the default formatter with custom options for this specific sink. If a custom formatter is provided, it will be used instead of the logger’s formatter.
- Parameters:¶
- std::optional<PatternFormatterOptions> const &options¶
The custom pattern formatter options to use
-
class Colours¶
Represents console colours
Public Functions¶
-
inline void apply_default_colours() noexcept¶
Sets some default colours for terminal
-
inline void assign_colour_to_log_level(LogLevel log_level, std::string_view colour) noexcept¶
Sets a custom colour per log level
-
inline void apply_default_colours() noexcept¶
-
inline void set_colours(Colours colours)¶
ConsoleSink Class¶
-
class ConsoleSink : public StreamSink¶
Public Functions¶
-
inline explicit ConsoleSink(ConsoleSinkConfig const &config = ConsoleSinkConfig{}, FileEventNotifier file_event_notifier = FileEventNotifier{})¶
Constructor with custom ConsoleColours config.
-
inline virtual void write_log(MacroMetadata const *log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, std::string const &process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector<std::pair<std::string, std::string>> const *named_args, std::string_view log_message, std::string_view log_statement) override¶
Write a formatted log message to the stream.
- Parameters:¶
- MacroMetadata const *log_metadata¶
log metadata
- uint64_t log_timestamp¶
log timestamp
- std::string_view thread_id¶
thread id
- std::string_view thread_name¶
thread name
- std::string const &process_id¶
Process Id
- std::string_view logger_name¶
logger name
- LogLevel log_level¶
Log level of the message.
- std::string_view log_level_description¶
Description of the log level.
- std::string_view log_level_short_code¶
Short code representing the log level.
- std::vector<std::pair<std::string, std::string>> const *named_args¶
vector of key-value pairs of named args
- std::string_view log_message¶
log message
- std::string_view log_statement¶
log statement
-
inline explicit ConsoleSink(ConsoleSinkConfig const &config = ConsoleSinkConfig{}, FileEventNotifier file_event_notifier = FileEventNotifier{})¶
AndroidSinkConfig Class¶
-
class AndroidSinkConfig¶
Holds the configuration options for the AndroidSink.
This configuration class allows you to set various parameters that determine how log messages are mapped and sent to the Android log system.
Public Functions¶
-
inline void set_tag(std::string const &tag)¶
Sets the tag that is prepended to every Android log message. Typically, this is set to the program name.
-
inline void set_format_message(bool format_message)¶
Enables or disables message formatting. If enabled, the log message will be formatted using the specified PatternFormatter before being sent to the Android log system.
-
inline void set_log_level_mapping(std::array<int, LogLevelCount> mapping)¶
Sets the mapping from quill log levels to Android log levels. This mapping determines which Android log level is used for each quill log level.
-
inline std::string const &tag() const noexcept¶
Getters
-
inline void set_tag(std::string const &tag)¶
AndroidSink Class¶
-
class AndroidSink : public quill::Sink¶
A sink that writes log messages to the Android logging system (logcat).
This sink leverages the Android log API to send log messages. It uses the configuration provided via AndroidSinkConfig to determine how the messages are formatted and mapped.
Public Functions¶
-
inline explicit AndroidSink(AndroidSinkConfig config = AndroidSinkConfig{})¶
Constructs an AndroidSink with the given configuration.
- Parameters:¶
- AndroidSinkConfig config = AndroidSinkConfig{}¶
The configuration options for the AndroidSink. Defaults to a default-configured AndroidSinkConfig.
-
inline void write_log(MacroMetadata const*, uint64_t, std::string_view, std::string_view, std::string const&, std::string_view, LogLevel log_level, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view log_message, std::string_view log_statement) override¶
Writes a formatted log message to the Android logging system.
-
inline explicit AndroidSink(AndroidSinkConfig config = AndroidSinkConfig{})¶
NullSink Class¶
-
class NullSink : public Sink¶
Public Functions¶
-
inline virtual void write_log(MacroMetadata const*, uint64_t, std::string_view, std::string_view, std::string const&, std::string_view, LogLevel, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view, std::string_view) override¶
Discards the provided log record.
-
inline virtual void flush_sink() override¶
Flushes the sink, synchronizing the associated sink with its controlled output sequence.
-
inline virtual void write_log(MacroMetadata const*, uint64_t, std::string_view, std::string_view, std::string const&, std::string_view, LogLevel, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view, std::string_view) override¶
SyslogSink Class¶
-
class SyslogSink : public quill::Sink¶
A sink that writes log messages to the system logger (syslog).
This sink leverages the syslog API to send log messages. It uses the configuration provided via SyslogSinkConfig to determine how the messages are formatted and mapped.
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.
Public Functions¶
-
inline explicit SyslogSink(SyslogSinkConfig config = SyslogSinkConfig{})¶
Constructs a SyslogSink with the given configuration. This constructor initializes the syslog connection using openlog().
- Parameters:¶
- SyslogSinkConfig config = SyslogSinkConfig{}¶
The configuration options for the SyslogSink. Defaults to a default-configured SyslogSinkConfig.
-
inline void write_log(MacroMetadata const*, uint64_t, std::string_view, std::string_view, std::string const&, std::string_view, LogLevel log_level, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view log_message, std::string_view log_statement) override¶
Writes a formatted log message to the stream.
-
inline explicit SyslogSink(SyslogSinkConfig config = SyslogSinkConfig{})¶
SyslogSinkConfig Class¶
-
class SyslogSinkConfig¶
Holds the configuration options for the SyslogSink.
When including syslog.h via SyslogSink, the header defines macros such as LOG_INFO and others that conflict with Quill’s 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 a header file. This ensures that syslog.h is only included in that specific translation unit, avoiding collisions in other files where you want to use the unprefixed Quill LOG_ macros.
Define the preprocessor flag : When this flag is defined, Quill will disable its unprefixed LOG_ macros. Instead, you must use the longer QUILL_LOG_ macros. This approach allows Quill and syslog.h to coexist in the same translation unit.
Alternatively, you can combine both approaches if you include SyslogSink in a .cpp file where you also intend to use the LOG_ macros.
However, the first solution is generally preferable, as it lets you take advantage of the more concise LOG_ macros without additional typing.
This configuration class allows you to set various parameters that determine how log messages are mapped and sent to the syslog.
Note
IMPORTANT: Handling Macro Collisions between syslog.h and Quill
Public Functions¶
-
inline void set_identifier(std::string const &identifier)¶
Sets the identifier that is prepended to every syslog message. Typically, this is set to the program name.
-
inline void set_options(int options)¶
Sets the options to be passed to openlog(). These options control various aspects of syslog behavior.
-
inline void set_facility(int facility)¶
Sets the facility code for syslog. The facility code indicates the type of program logging the message.
-
inline void set_format_message(bool format_message)¶
Enables or disables message formatting. If enabled, the log message will be formatted using the specified PatternFormatter before being sent to syslog.
-
inline void set_log_level_mapping(std::array<int, LogLevelCount> mapping)¶
Sets the mapping from quill log levels to syslog levels. This mapping determines which syslog level is used for each quill log level.
-
inline std::string const &identifier() const noexcept¶
Getters
SystemdSink Class¶
-
class SystemdSink : public quill::Sink¶
A sink that writes log messages to the system logger (systemd).
This sink leverages the systemd API to send log messages. It uses the configuration provided via SystemdSinkConfig to determine how the messages are formatted and mapped.
Public Functions¶
-
inline explicit SystemdSink(SystemdSinkConfig config = SystemdSinkConfig{})¶
Constructs a SystemdSink with the given configuration. This constructor stores the configuration used when sending log messages to systemd.
- Parameters:¶
- SystemdSinkConfig config = SystemdSinkConfig{}¶
The configuration options for the SystemdSink. Defaults to a default-configured SystemdSinkConfig.
-
inline void write_log(MacroMetadata const *log_metadata, uint64_t, std::string_view thread_id, std::string_view, std::string const&, std::string_view logger_name, LogLevel log_level, std::string_view, std::string_view, std::vector<std::pair<std::string, std::string>> const*, std::string_view log_message, std::string_view log_statement) override¶
Writes a formatted log message to the stream.
-
inline explicit SystemdSink(SystemdSinkConfig config = SystemdSinkConfig{})¶
SystemdSinkConfig Class¶
-
class SystemdSinkConfig¶
Holds the configuration options for the SystemdSink.
When including systemd.h via SystemdSink, the header defines macros such as LOG_INFO and others that conflict with Quill’s 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 a header file. This ensures that systemd.h is only included in that specific translation unit, avoiding collisions in other files where you want to use the unprefixed Quill LOG_ macros.
Define the preprocessor flag : When this flag is defined, Quill will disable its unprefixed LOG_ macros. Instead, you must use the longer QUILL_LOG_ macros. This approach allows Quill and systemd.h to coexist in the same translation unit.
Alternatively, you can combine both approaches if you include SystemdSink in a .cpp file where you also intend to use the LOG_ macros.
However, the first solution is generally preferable, as it lets you take advantage of the more concise LOG_ macros without additional typing.
This configuration class allows you to set various parameters that determine how log messages are mapped and sent to the systemd.
Note
IMPORTANT: Handling Macro Collisions between systemd.h and Quill
Public Functions¶
-
inline void set_identifier(std::string const &identifier)¶
Sets the identifier that is prepended to every systemd message. Typically, this is set to the program name.
-
inline void set_format_message(bool format_message)¶
Enables or disables message formatting. If enabled, the log message will be formatted using the specified PatternFormatter before being sent to systemd.
-
inline void set_log_level_mapping(std::array<int, LogLevelCount> mapping)¶
Sets the mapping from quill log levels to systemd levels. This mapping determines which systemd level is used for each quill log level.
-
inline std::string const &identifier() const noexcept¶
Getters
PrometheusSink Class¶
Optional sink for exporting Quill metric samples through prometheus-cpp.
-
class PrometheusSink : public Sink¶
Optional sink that forwards Quill metric samples to a prometheus-cpp registry.
Only translation units including this header require prometheus-cpp headers and linking against
prometheus-cpp::coreandprometheus-cpp::pull. Quill itself does not depend on prometheus-cpp.
PrometheusSink::ExposerConfiguration Struct¶
-
struct ExposerConfiguration¶
PrometheusSink::Options Struct¶
-
struct Options¶
PrometheusSink::SummaryQuantile Struct¶
-
struct SummaryQuantile¶
A single quantile target for a summary metric.
quantileis the target rank in [0, 1] (e.g. 0.5 for the median, 0.99 for p99).erroris the allowed absolute error around that rank used by the CKMS streaming algorithm: smallererrorproduces more accurate quantiles but uses more memory and CPU.Common defaults:
{0.5, 0.05},{0.9, 0.01},{0.99, 0.001}— these mirror what prometheus-cpp and the official Prometheus client libraries suggest, and match the typical cost/accuracy trade-off (looser error at the median, tighter at the tails).
PrometheusSink::GaugeUpdateMode Enum¶
-
enum class PrometheusSink::GaugeUpdateMode¶
Controls how a gauge applies the sample value it receives.
Set: replace the gauge with the sample value (the value is the current reading).Add: increment the gauge by the sample value (the value is a delta; pass a negative sample to subtract).Sub: decrement the gauge by the sample value (the value is a positive magnitude to remove; equivalent toAddwith a negated sample).
Values:
-
enumerator Add¶
-
enumerator Set¶
-
enumerator Sub¶
ManualBackendWorker Class¶
-
class ManualBackendWorker¶
This class can be used when you want to run the backend worker on your own thread.
Threading contract:
The thread running
ManualBackendWorkermay log.That same thread must not use any path that waits for the backend to flush its own queue. In particular, it must not call
logger->flush_log()orFrontend::remove_logger_blocking(). If a logger has immediate flush enabled, the implicit flush is skipped for log calls from this thread.The thread that calls
init()must also callshutdown()explicitly before it exits. Do not rely on the destructor to perform shutdown for you.
Public Functions¶
-
inline void init(BackendOptions options)¶
Initializes the ManualBackendWorker with the specified backend options.
This function must be called before any other functions in this class. It configures the backend worker for manual operation, disabling certain options that are incompatible with manual control.
- Parameters:¶
- BackendOptions options¶
The
BackendOptionsto configure the backend worker.
-
inline void shutdown()¶
Flushes remaining frontend queues and marks the manual backend worker as stopped.
This function must be called from the same thread that called init() and performs the same shutdown work that the automatic backend thread executes during stop(). Call this explicitly before the manual backend thread exits. Do not rely on the destructor to do this for you.
-
inline void poll_one()¶
Polls all thread-local SPSC queues and caches the log statements, processing and writing the log statement with the minimum timestamp to the corresponding output sinks.
This function should be called periodically by the thread to process and dispatch log entries. It assumes that the
init()function has been called first to properly configure the backend worker.
-
inline void poll()¶
Continuously polls the backend worker until all queues are empty.
This function keeps polling until all frontend queues and cached transit events are processed.
CsvWriter Class¶
-
template<typename TCsvSchema, typename TFrontendOptions>
class CsvWriter¶ A CSV writer class for asynchronous logging of CSV files.
This class facilitates the asynchronous logging of CSV files, where formatting and I/O operations are handled by the backend worker thread.
Call close() before Backend::stop() when deterministic logger removal and file closure are required. The destructor performs best-effort asynchronous cleanup and does not block.
The TCsvSchema struct should define the CSV header and format, for example:
struct OrderCsvSchema { static constexpr char const* header = "order_id,symbol,quantity,price,side"; static constexpr char const* format = "{},{},{},{:.2f},{}"; };- Template Parameters:¶
Public Functions¶
-
inline explicit CsvWriter(std::string const &filename, char open_mode = 'w', FilenameAppendOption filename_append = FilenameAppendOption::None)¶
Constructs a CsvWriter object that writes to a file.
- Parameters:¶
-
inline CsvWriter(std::string const &filename, FileSinkConfig sink_config, bool should_write_header = true)¶
Constructs a CsvWriter object that writes to a file.
- Parameters:¶
- std::string const &filename¶
The name of the CSV file to write to.
- FileSinkConfig sink_config¶
Configuration settings for the file sink.
- bool should_write_header = true¶
Whether to write the header at the beginning of the CSV file.
-
inline CsvWriter(std::string const &filename, RotatingFileSinkConfig sink_config, bool should_write_header = true)¶
Constructs a CsvWriter object that writes to a rotating file.
- Parameters:¶
- std::string const &filename¶
The name of the CSV file to write to.
- RotatingFileSinkConfig sink_config¶
Configuration settings for the file sink.
- bool should_write_header = true¶
Whether to write the header at the beginning of the CSV file.
Constructs a CsvWriter object that writes to a specified sink.
A unique name for this CsvWriter instance.
The sink to output the data to (e.g., a ConsoleSink or a user-defined Sink).
Whether to write the header at the beginning of the CSV file.
Constructs a CsvWriter object that writes to multiple sinks.
A unique name for this CsvWriter instance.
A list of sinks to output the data to.
Whether to write the header at the beginning of the CSV file.
-
inline ~CsvWriter()¶
Destructor for CsvWriter.
The destructor performs best-effort asynchronous cleanup. Call close() before Backend::stop() when deterministic logger removal and file closure are required.
-
template<typename ...Args>
inline void append_row(Args&&... fields)¶ Appends a row to the CSV file. This function is also thread safe.
-
inline void write_header()¶
Writes the csv header
-
inline void write_header(FileEventNotifierHandle file)¶
Writes the csv header to the specified file
- Parameters:¶
- FileEventNotifierHandle file¶
file to write
-
inline void close()¶
Removes the logger synchronously and closes the underlying file sink before returning.
After calling close(), this CsvWriter instance must no longer be used.
Note
This function must only be used while the backend worker is running.
-
inline void flush()¶
Flushes the log to ensure all data is written to the file. This method will block the caller thread until the file is flushed, ensuring that all data are flushed to the file.