How to Configure spdlog Periodic Flush for Log Durability
Call spdlog::set_periodic_flush(std::chrono::seconds(interval)) to start a background thread that automatically flushes all registered loggers at the specified interval, ensuring buffered messages are persisted to disk even if the application crashes unexpectedly.
The gabime/spdlog library buffers log messages for performance, which risks data loss during sudden termination. Configuring spdlog periodic flush creates a dedicated worker thread that force-flushes buffers to underlying sinks at regular intervals, providing durability without requiring manual flush() calls after every log statement.
How Periodic Flush Works Under the Hood
When you log messages, spdlog stores them in internal buffers before writing to files or other sinks. If the process terminates unexpectedly, unflushed buffers are lost. The periodic flush mechanism creates a spdlog::details::periodic_worker thread that invokes a flush callback every N seconds.
According to the source code in include/spdlog/spdlog.h, the public API delegates to the global registry that manages a std::unique_ptr<spdlog::details::periodic_worker> stored as periodic_flusher_ in include/spdlog/details/registry.h. This worker runs a blocking loop that sleeps for the specified interval, then executes the callback—by default spdlog::flush_all()—ensuring all registered loggers sync their buffers to the operating system.
The Core API: set_periodic_flush
Global Flush Configuration
The simplest approach flushes every registered logger at the same cadence. In include/spdlog/spdlog.h (around line 83), the function signature is:
void set_periodic_flush(std::chrono::seconds interval);
Passing std::chrono::seconds(5) creates a thread that flushes all loggers every 5 seconds. Passing std::chrono::seconds(0) stops and destroys the flusher thread entirely.
Selective Logger Flush with Pattern Matching
For applications with multiple loggers, you can restrict flushing to specific ones using glob pattern matching:
void set_periodic_flush(std::chrono::seconds interval, const std::string& logger_name_pattern);
This overload, also defined in include/spdlog/spdlog.h, only flushes loggers whose names match the provided pattern (e.g., "file_*" matches file_logger but not console).
Practical Configuration Examples
Basic Periodic Flush Every 5 Seconds
Enable automatic flushing for the default logger set to ensure logs reach disk regularly:
#include <spdlog/spdlog.h>
#include <chrono>
int main() {
auto logger = spdlog::basic_logger_mt("my_logger", "app.log");
spdlog::set_default_logger(logger);
// Flush all loggers every 5 seconds
spdlog::set_periodic_flush(std::chrono::seconds(5));
logger->info("Application started");
// Logs persist to disk automatically every 5 seconds, even on crash
return 0;
}
Selective Flushing for High-Value Loggers Only
Limit periodic flushing to file-based loggers while keeping console loggers unflushed to reduce I/O overhead:
#include <spdlog/spdlog.h>
#include <chrono>
int main() {
auto file_log = spdlog::basic_logger_mt("file_backend", "output.log");
auto console_log = spdlog::stdout_logger_mt("console");
// Only flush loggers with names starting with "file_"
spdlog::set_periodic_flush(std::chrono::seconds(2), "file_*");
file_log->info("This gets flushed every 2 seconds");
console_log->info("This stays buffered until process exit");
return 0;
}
Custom Flush Callback
For advanced use cases, provide a custom callback that flushes a specific logger or performs additional cleanup:
#include <spdlog/spdlog.h>
#include <chrono>
#include <functional>
int main() {
auto my_logger = spdlog::basic_logger_mt("my_logger", "my.log");
// Custom callback that flushes only this specific logger
auto my_flush = [&my_logger]() { my_logger->flush(); };
// Register custom callback with 1-second interval
spdlog::set_periodic_flush(std::chrono::seconds(1), my_flush);
my_logger->info("Message flushed every second via custom callback");
return 0;
}
Key Implementation Files
| File | Purpose |
|---|---|
include/spdlog/spdlog.h |
Exposes set_periodic_flush() overloads that start or restart the periodic worker |
include/spdlog/details/periodic_worker.h |
Defines periodic_worker class that runs the background thread and timed wait loop |
include/spdlog/details/registry.h |
Holds periodic_flusher_ member and connects the worker to the logger registry |
src/spdlog.cpp |
Implements the glue logic that instantiates the worker when set_periodic_flush is invoked |
Summary
- spdlog periodic flush prevents data loss by running a background thread that calls
flush_all()(or a custom callback) at fixed intervals. - Use
spdlog::set_periodic_flush(interval)ininclude/spdlog/spdlog.hto enable global flushing across all loggers. - Use the pattern overload
set_periodic_flush(interval, "pattern")to target specific loggers without affecting others. - The implementation relies on
spdlog::details::periodic_workermanaged by the global registry viaperiodic_flusher_. - Pass
std::chrono::seconds(0)to stop the flusher and terminate the background thread cleanly.
Frequently Asked Questions
What happens if I don't configure periodic flush?
Without periodic flush, log messages remain in internal buffers until the logger is explicitly flushed or destroyed. If your application crashes, buffered messages are lost. Synchronous loggers flush immediately, but buffered or asynchronous loggers require manual or periodic flushing for durability.
Does periodic flush impact application performance?
The impact is minimal but measurable. The background thread sleeps for the specified interval and only wakes to execute the flush callback. For high-throughput applications, choose an interval that balances durability needs (e.g., 5-10 seconds) against I/O overhead. Sub-second intervals may cause noticeable disk contention.
Can I change the flush interval dynamically?
Yes. Calling spdlog::set_periodic_flush() with a new interval stops the existing periodic_worker and starts a new one with the updated timing. As implemented in src/spdlog.cpp, the registry handles thread cleanup and recreation automatically, making runtime reconfiguration thread-safe.
Is the periodic flush mechanism thread-safe with multiple loggers?
Absolutely. The flush operation locks each logger individually, and the registry's periodic_flusher_ management is protected by internal synchronization. You can register, deregister, or log from multiple threads while the periodic flush operates in the background without explicit synchronization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →