# How to Send Logs to Syslog Using spdlog: A Complete Implementation Guide

> Learn how to send logs to syslog using spdlog. Implement a syslog sink for your C++ applications with this complete guide. Streamline your log management today.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: how-to-guide
- Published: 2026-07-19

---

**spdlog provides a dedicated syslog sink in [`spdlog/sinks/syslog_sink.h`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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.

```cpp
#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.

```cpp
#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.

```cpp
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) or `LOG_CONS` (write to console on syslog failure).
- **facility**: The syslog facility code determining the message category, such as `LOG_USER`, `LOG_DAEMON`, or `LOG_LOCAL0` through `LOG_LOCAL7`.
- **enable_formatting**: When `false`, the sink transmits raw log payloads. When `true`, it processes messages through the attached spdlog formatter before calling `::syslog`.

## Summary

- Include [`spdlog/sinks/syslog_sink.h`](https://github.com/gabime/spdlog/blob/main/spdlog/sinks/syslog_sink.h) to 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.