How to Send Logs to Syslog Using spdlog: A Complete Implementation Guide
spdlog provides a dedicated syslog sink in spdlog/sinks/syslog_sink.h that forwards formatted log messages to the Unix syslog service through the syslog_logger_mt and syslog_logger_st factory functions.
The gabime/spdlog library ships with native Unix syslog integration, allowing you to route application logs directly to the system logger. If you need to send logs to syslog using spdlog, you can leverage the syslog_sink class and its accompanying factory functions to handle openlog initialization and priority mapping automatically.
Understanding the spdlog Syslog Sink Architecture
The syslog implementation follows spdlog’s standard sink architecture defined in include/spdlog/sinks/base_sink.h. According to the gabime/spdlog source code, the syslog_sink class inherits from base_sink<Mutex> and overrides the sink_it_ and flush_ methods to interface with the system ::syslog call.
Key components in include/spdlog/sinks/syslog_sink.h include:
- syslog_sink: The core sink class that maps spdlog severity levels to syslog priorities using the internal
syslog_levels_array. - syslog_logger_mt: A convenience factory that creates a thread-safe logger instance backed by a mutex-protected sink.
- syslog_logger_st: A factory for single-threaded contexts that uses a null-mutex to eliminate synchronization overhead.
Creating a Syslog Logger in spdlog
To begin sending logs to syslog, include the syslog sink header and instantiate a logger using one of the provided factory functions.
Multi-Threaded Syslog Logger
For applications logging from multiple threads, use the syslog_logger_mt factory. This creates a logger with a mutex-backed sink to prevent race conditions during message emission.
#include <spdlog/spdlog.h>
#include <spdlog/sinks/syslog_sink.h>
int main() {
// ident: program name, option: LOG_PID, facility: LOG_USER, formatting: disabled
auto logger = spdlog::syslog_logger_mt("syslog_demo",
"my_app",
LOG_PID,
LOG_USER,
false);
spdlog::register_logger(logger);
logger->info("Application started");
logger->error("Failed to open configuration file");
}
Syslog Logger with Custom Formatting
When enable_formatting is set to true, the sink applies your configured pattern formatter before transmitting to syslog. This allows timestamps, thread IDs, and custom layout patterns to appear in system logs.
#include <spdlog/spdlog.h>
#include <spdlog/sinks/syslog_sink.h>
#include <spdlog/pattern_formatter.h>
int main() {
// Create a formatter with timestamp and thread ID
auto formatter = std::make_unique<spdlog::pattern_formatter>(
"%Y-%m-%d %H:%M:%S [%t] %v");
// Construct sink with formatting enabled
auto sink = std::make_shared<spdlog::sinks::syslog_sink_mt>(
"my_app", LOG_PID, LOG_LOCAL0, true);
sink->set_formatter(std::move(formatter));
auto logger = std::make_shared<spdlog::logger>("formatted_syslog", sink);
spdlog::register_logger(logger);
logger->warn("Custom formatted message");
}
Single-Threaded Variant for Performance
If your application guarantees single-threaded logging, use syslog_logger_st to avoid mutex contention entirely. The _st variant uses a null-mutex template parameter, reducing overhead as implemented in the source.
auto logger = spdlog::syslog_logger_st("single_thread_logger",
"my_app",
LOG_PID,
LOG_LOCAL1,
false);
Configuring Syslog Sink Parameters
The syslog_sink constructor and factory functions accept four critical parameters that control syslog behavior:
- ident: A string identifier passed to
openlog(). If empty, the system defaults to the program name. - option: Bitwise flags such as
LOG_PID(include PID in messages) orLOG_CONS(write to console on syslog failure). - facility: The syslog facility code determining the message category, such as
LOG_USER,LOG_DAEMON, orLOG_LOCAL0throughLOG_LOCAL7. - enable_formatting: When
false, the sink transmits raw log payloads. Whentrue, it processes messages through the attached spdlog formatter before calling::syslog.
Summary
- Include
spdlog/sinks/syslog_sink.hto access the syslog implementation in gabime/spdlog. - Choose syslog_logger_mt for multi-threaded applications or syslog_logger_st for single-threaded performance.
- Configure the ident, option, and facility parameters to match your system logging requirements.
- Enable formatting to apply spdlog patterns, or disable it to transmit raw messages to syslog.
Frequently Asked Questions
What header file is required for spdlog syslog support?
You must include <spdlog/sinks/syslog_sink.h> in addition to the main spdlog header. This file defines the syslog_sink class and the syslog_logger_mt and syslog_logger_st factory functions.
How does spdlog map its log levels to syslog priorities?
The syslog_sink class maintains an internal syslog_levels_ array that translates spdlog severity levels (trace, debug, info, warning, error, critical) to their corresponding syslog priority constants (LOG_DEBUG, LOG_INFO, LOG_WARNING, etc.) before calling the system syslog() function.
Can I use custom formatting with the spdlog syslog sink?
Yes. Construct the sink with enable_formatting set to true, then attach a custom pattern_formatter using the set_formatter() method. The sink will apply your pattern before transmitting the message to the syslog service.
Which factory should I use, syslog_logger_mt or syslog_logger_st?
Use syslog_logger_mt when your application logs from multiple threads concurrently, as it uses a std::mutex to protect shared state. Use syslog_logger_st only when logging from a single thread, as it avoids mutex overhead by using a null-mutex implementation, improving performance in single-threaded contexts.
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 →