Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:ClickHouse ClickHouse Poco RemoteSyslogChannel

From Leeroopedia


base/poco/Net/src/RemoteSyslogChannel.cpp:1-348 ClickHouse_ClickHouse ClickHouse_ClickHouse_Remote_Syslog_Logging

Source File base/poco/Net/src/RemoteSyslogChannel.cpp
Lines of Code 348
Principle Principle:ClickHouse_ClickHouse_Remote_Syslog_Logging
Domain Networking, Logging
Language C++
Last Updated 2026-02-08 00:00 GMT

Purpose

Implements a Poco logging channel that sends syslog messages over UDP to a remote syslog collector. Supports both RFC 5424 (modern) and RFC 3164 (BSD legacy) message formats. This enables ClickHouse to forward log events to centralized logging infrastructure such as rsyslog, syslog-ng, or cloud log aggregators.

Code Reference

Message Formatting and Sending

void RemoteSyslogChannel::log(const Message& msg)
{
    Poco::FastMutex::ScopedLock lock(_mutex);
    if (!_open) open();

    std::string m;
    m.reserve(1024);
    m += '<';
    Poco::NumberFormatter::append(m, getPrio(msg) + _facility);
    m += '>';
    if (_bsdFormat)
    {
        // RFC 3164: <PRI>Mmm dd HH:MM:SS hostname message
        Poco::DateTimeFormatter::append(m, msg.getTime(), BSD_TIMEFORMAT);
        m += ' ';
        m += _host;
    }
    else
    {
        // RFC 5424: <PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID SD MSG
        m += "1 "; // version
        Poco::DateTimeFormatter::append(m, msg.getTime(), SYSLOG_TIMEFORMAT);
        m += ' ';
        m += _host;
        m += ' ';
        m += _name;
        m += ' ';
        Poco::NumberFormatter::append(m, msg.getPid());
        m += ' ';
        m += msg.getSource();
        m += ' ';
        m += "-"; // no structured data
    }
    m += ' ';
    m += msg.getText();
    _socket.sendTo(m.data(), static_cast<int>(m.size()), _socketAddress);
}

Priority Mapping

int RemoteSyslogChannel::getPrio(const Message& msg)
{
    switch (msg.getPriority())
    {
    case Message::PRIO_TEST:
    case Message::PRIO_TRACE:
    case Message::PRIO_DEBUG:         return SYSLOG_DEBUG;
    case Message::PRIO_INFORMATION:   return SYSLOG_INFORMATIONAL;
    case Message::PRIO_NOTICE:        return SYSLOG_NOTICE;
    case Message::PRIO_WARNING:       return SYSLOG_WARNING;
    case Message::PRIO_ERROR:         return SYSLOG_ERROR;
    case Message::PRIO_CRITICAL:      return SYSLOG_CRITICAL;
    case Message::PRIO_FATAL:         return SYSLOG_ALERT;
    default:                          return 0;
    }
}

Channel Opening

void RemoteSyslogChannel::open()
{
    if (_open) return;
    if (_logHost.find(':') != std::string::npos)
        _socketAddress = SocketAddress(_logHost);
    else
        _socketAddress = SocketAddress(_logHost, SYSLOG_PORT);

    _socket = DatagramSocket(_socketAddress.family());

    if (_host.empty())
    {
        try { _host = DNS::thisHost().name(); }
        catch (Poco::Exception&)
        { _host = _socket.address().host().toString(); }
    }
    _open = true;
}

I/O Contract

Input Output Side Effects
`log(msg)` -- a `Poco::Message` with priority, text, timestamp, source, PID None (void) Formats a syslog message (RFC 5424 or RFC 3164) and sends it as a single UDP datagram to `_socketAddress`. Auto-opens the channel on first call.
`open()` None (void) Resolves the log host address, creates a `DatagramSocket`, resolves the local hostname via DNS if not set.
`close()` None (void) Closes the underlying `DatagramSocket` and marks channel as closed.
`setProperty(name, value)` None (void) Configures channel properties: `name`, `facility`, `format` ("bsd"/"rfc3164" vs default RFC 5424), `loghost`, `host`.
`getProperty(name)` Property value as `std::string` None. Returns current property values; facility is returned as uppercase string (e.g., "USER", "DAEMON").

Usage Examples

// Create channel targeting a remote syslog server
RemoteSyslogChannel* pChannel = new RemoteSyslogChannel(
    "logserver.example.com:514",  // target address
    "clickhouse-server",           // application name
    RemoteSyslogChannel::SYSLOG_DAEMON,  // facility
    false                          // use RFC 5424 format
);

pChannel->open();

// Send a log message
Poco::Message msg("QueryEngine", "Query completed in 150ms",
                   Poco::Message::PRIO_INFORMATION);
pChannel->log(msg);

// Or configure via properties
pChannel->setProperty("facility", "LOCAL0");
pChannel->setProperty("format", "bsd");  // switch to RFC 3164
pChannel->setProperty("loghost", "192.168.1.100:1514");

// Register with logging factory for config-based setup
RemoteSyslogChannel::registerChannel();

Internal Details

Message Format

RFC 5424 format:

<PRI>1 TIMESTAMP HOSTNAME APP-NAME PROCID MSGID - MESSAGE
Example: <14>1 2024-01-15T10:30:00.000000+00:00 server1 clickhouse 12345 QueryEngine - Query completed

RFC 3164 (BSD) format:

<PRI>Mmm dd HH:MM:SS hostname MESSAGE
Example: <14>Jan 15 10:30:00 server1 Query completed

Priority Calculation

The syslog priority value is facility + severity. Facility values are pre-shifted by 3 bits (e.g., `SYSLOG_USER = 8`, `SYSLOG_DAEMON = 24`), and severity occupies the lower 3 bits (0-7).

Facility Codes Supported

KERN, USER, MAIL, DAEMON, AUTH, AUTHPRIV, SYSLOG, LPR, NEWS, UUCP, CRON, FTP, NTP, LOGAUDIT, LOGALERT, CLOCK, LOCAL0 through LOCAL7.

Thread Safety

The `log` method acquires a `FastMutex`, ensuring that concurrent logging from multiple threads produces well-formed, non-interleaved UDP datagrams.

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment