Understanding Syslog Implementations: Comparing syslog(), rsyslog, and syslog-ng with Source Code Examples


2 views

The syslog() function is the fundamental system logging API in Unix-like systems, defined in the C standard library. Here's how to view its implementation:

// Example of syslog() usage
#include <syslog.h>

int main() {
    openlog("myapp", LOG_PID|LOG_CONS, LOG_USER);
    syslog(LOG_INFO, "Test message from %s", "myapp");
    closelog();
    return 0;
}

To examine the source code:

# On Linux systems
apt-get source glibc
# Then look for syslog.c in the source tree

The original syslog daemon (syslogd) provides basic logging functionality with these characteristics:

  • UDP port 514 for network logging
  • Simple configuration via /etc/syslog.conf
  • Limited filtering capabilities

rsyslog (rsyslogd is the daemon name) introduces significant improvements:

# Sample rsyslog.conf with advanced features
module(load="imfile" PollingInterval="10")

template(name="DynFile" type="string" 
    string="/var/log/%programname%/%$year%-%$month%-%$day%.log")

if $programname == 'nginx' then {
    action(type="omfile" dynafile="DynFile")
    stop
}

Key advantages over traditional syslog:

  • TCP transport with TLS encryption
  • High-performance queuing
  • Reliable forwarding with disk-assisted memory queues
  • Advanced filtering using RainerScript

syslog-ng offers even more flexibility with its configuration syntax:

# syslog-ng.conf example
source s_network {
    network(
        ip("0.0.0.0")
        port(514)
        transport("tcp")
    );
};

destination d_mysql {
    sql(
        type(mysql)
        host("db.example.com")
        database("logs")
        table("system_logs_${HOST}")
        columns("datetime", "host", "program", "pid", "message")
        values("$R_DATE", "$HOST", "$PROGRAM", "$PID", "$MSG")
    );
};

log {
    source(s_network);
    destination(d_mysql);
};

Notable syslog-ng features:

  • Content-based filtering with regex and patterndb
  • Native support for various databases (SQL, MongoDB)
  • Message parsing and normalization
  • JSON format support
Feature syslog rsyslog syslog-ng
Configuration syntax Simple, single-line RainerScript (flow control) Object-oriented
Network protocol UDP only UDP/TCP with TLS UDP/TCP with TLS
Performance Basic High (multi-threaded) High (modular)

Consider these factors when selecting a logging solution:

  • Simple systems: Traditional syslog may suffice
  • Enterprise environments: rsyslog offers good balance
  • Complex parsing needs: syslog-ng excels

Traditional syslog refers to the original Unix logging system developed in the 1980s. The syslog() function call is actually part of the standard C library (glibc). You can find its source code in the glibc repository:

// Example syslog() call
#include <syslog.h>

int main() {
    openlog("myapp", LOG_PID|LOG_CONS, LOG_USER);
    syslog(LOG_INFO, "Test message from my application");
    closelog();
    return 0;
}

rsyslog (where 'r' stands for "reliable") is an enhanced syslog daemon that maintains backward compatibility while adding features like:

  • TCP transport with TLS encryption
  • Database output (MySQL, PostgreSQL, etc.)
  • Fine-grained filtering using RainerScript

syslog-ng (next-generation) takes a different architectural approach with:

  • Content-based filtering
  • Native message parsing (JSON, etc.)
  • Better performance for high-volume logging

The difference between rsyslog and rsyslogd is simply terminology - rsyslogd refers specifically to the daemon process, while rsyslog is the project name. They're essentially the same codebase.

Here's a basic rsyslog configuration example that logs to both a file and remote server:

# /etc/rsyslog.conf
module(load="imuxsock") # local system logging
module(load="imklog")   # kernel logging

*.info;mail.none;authpriv.none;cron.none    /var/log/messages
authpriv.*                                  /var/log/secure

# Remote logging via TCP
*.* @@logs.example.com:514

For syslog-ng, the equivalent would look like:

# /etc/syslog-ng/syslog-ng.conf
source s_src {
    system();
    internal();
};

destination d_mesg { file("/var/log/messages"); };
destination d_remote { tcp("logs.example.com" port(514)); };

filter f_default { level(info..emerg) and not facility(mail,authpriv,cron); };
filter f_auth { facility(authpriv); };

log { source(s_src); filter(f_default); destination(d_mesg); };
log { source(s_src); filter(f_auth); destination(d_remote); };

For high-throughput systems, rsyslog offers queueing mechanisms:

# High-performance rsyslog configuration
module(load="imptcp")
input(type="imptcp" port="514" ruleset="remote"
      MaxSessions="500" Threads="5")

ruleset(name="remote" queue.type="linkedList"
        queue.size="100000" queue.dequeuebatchsize="1000") {
    # Processing rules here
}

While syslog-ng handles similar loads with its internal threading model, requiring less explicit configuration for optimal performance.