How to Set Custom Error Handlers in spdlog: Global and Per-Logger Methods
You can intercept spdlog internal errors by installing a custom callback via spdlog::set_error_handler() for global scope or logger::set_error_handler() for individual loggers.
When logging operations fail—such as being unable to open a file sink or write to disk—the gabime/spdlog library routes these internal errors through a customizable handler. Learning how to set custom error handlers in spdlog allows you to redirect failures to monitoring systems, trigger alerts, or execute cleanup code instead of silently writing to stderr.
Understanding spdlog Error Handling
spdlog triggers error handlers when sink operations encounter filesystem or I/O failures. By default, the library writes error messages to standard error, but this behavior is fully customizable through two distinct APIs that operate at different scopes.
Error Handler Signature
Both global and per-logger handlers conform to the same function signature, accepting a const std::string& containing the error description:
void handler(const std::string& msg);
Setting a Global Error Handler
The global API affects every logger in your application unless explicitly overridden. According to the spdlog source code, the global handler is declared in include/spdlog/spdlog.h at line 91 and implemented in include/spdlog/spdlog-inl.h at line 54.
To register a global handler, call spdlog::set_error_handler() before creating any loggers:
#include <spdlog/spdlog.h>
#include <iostream>
void global_error_handler(const std::string& msg)
{
std::cerr << "[Global Error] " << msg << std::endl;
// Optional: send to monitoring, throw exception, etc.
}
int main()
{
spdlog::set_error_handler(global_error_handler);
// All subsequent loggers will use this handler by default
}
The registry class manages the propagation of this global handler to newly created logger instances. The relevant declarations exist in include/spdlog/details/registry.h at line 79, with the implementation logic residing in registry-inl.h at lines 165-168.
Setting a Per-Logger Error Handler
For logger-specific error handling, use the set_error_handler member function declared in include/spdlog/logger.h at line 310 and implemented in include/spdlog/logger-inl.h at line 112. This method overrides the global handler for that specific logger instance.
auto file_logger = spdlog::basic_logger_mt("file", "app.log");
file_logger->set_error_handler([](const std::string& msg)
{
std::cerr << "[File Logger Error] " << msg << std::endl;
});
Complete Implementation Example
The following example demonstrates both global and per-logger error handling strategies as implemented in the gabime/spdlog repository:
#include <spdlog/spdlog.h>
#include <iostream>
// 1. Define a custom error handler
void my_error_handler(const std::string& msg)
{
std::cerr << "[spdlog error] " << msg << std::endl;
// Optionally: std::terminate();
}
int main()
{
// 2. Install globally before creating loggers
spdlog::set_error_handler(my_error_handler);
// 3. Create logger using global handler
auto console = spdlog::stdout_color_mt("console");
console->info("Using global error handler");
// 4. Override for specific logger
auto file_logger = spdlog::basic_logger_mt("file", "logs.txt");
file_logger->set_error_handler([](const std::string& msg)
{
std::cerr << "[file-specific] " << msg << std::endl;
});
return 0;
}
Summary
- Global handlers apply to all loggers via
spdlog::set_error_handler(), declared ininclude/spdlog/spdlog.hat line 91. - Per-logger handlers override the global setting via
logger::set_error_handler(), declared ininclude/spdlog/logger.hat line 310. - The registry propagates global handlers to new loggers through
include/spdlog/details/registry.h. - Handlers receive error details as
const std::string&and can execute arbitrary cleanup, monitoring, or termination logic. - The default handler writes to
stderrwhen no custom handler is registered.
Frequently Asked Questions
What types of errors trigger the spdlog error handler?
The error handler executes when sink operations fail, such as failing to open a log file due to permissions, disk full errors when writing, or other I/O exceptions caught during the logging process. These are internal spdlog failures, not application logic errors.
Can I use a lambda function as an error handler?
Yes, spdlog accepts any callable matching the signature void(const std::string&), including lambdas, std::function objects, or regular function pointers. The err_handler type alias in the source code supports this flexibility.
Does setting a per-logger handler affect other loggers?
No, calling set_error_handler() on a specific logger instance only affects that logger. Other loggers continue using the global handler or their own individually assigned handlers, as managed by the registry in include/spdlog/details/registry-inl.h.
Where is the default error handler implemented?
The default handler that writes to stderr is managed by the registry class in include/spdlog/details/registry-inl.h at lines 165-168 and applied automatically when no custom handler is specified at the global or logger level.
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 →