open atlas
↑ Back to track
Linux, the operating system LIN · 10 · 03

Syslog and rsyslog

The syslog model classifies messages by facility (auth, cron, daemon…) cross severity (emerg…debug). rsyslog rules route by facility.severity to files or remote collectors. journald can forward to syslog via imjournal, bridging the structured and classic worlds.

LIN Middle ◷ 22 min
Level
FoundationsJuniorMiddleSenior

You inherit a server where all auth events go to /var/log/auth.log, cron output goes to /var/log/syslog, and kernel messages are in /var/log/kern.log — but nobody set this up recently and there is no journald config that explains it. This is rsyslog at work, implementing a routing scheme that predates systemd by 30 years: the syslog model. Every log message carries two tags — a facility (what subsystem sent it) and a severity (how bad it is) — and rsyslog rules route the cross-product of those two dimensions to files, pipes, or remote servers. Understanding this model is essential because rsyslog still runs on most Linux boxes alongside journald, it is the standard way to ship logs to a central collector, and every observability pipeline you encounter in production grew from this same facility/severity taxonomy.

Goal

After this lesson you can read the syslog facility/severity matrix, interpret rsyslog routing rules in rsyslog.conf, configure rsyslog to forward logs to a remote collector, and understand how journald bridges to the classic syslog world via imjournal.

1

The syslog model: facility × severity.

Every syslog message has two classification dimensions:

# FACILITIES — what subsystem generated the message:
# kern      kernel messages
# user      user-level messages
# mail      mail subsystem
# daemon    system daemons
# auth      security/authorization (also: authpriv for sensitive auth)
# syslog    messages generated by syslogd itself
# lpr       line printer subsystem
# news      network news subsystem
# cron      clock daemon (cron and at)
# local0-7  reserved for local use

# SEVERITIES (0=most critical, 7=least):
# 0 emerg    system is unusable
# 1 alert    action must be taken immediately
# 2 crit     critical conditions
# 3 err      error conditions
# 4 warning  warning conditions
# 5 notice   normal but significant condition
# 6 info     informational messages
# 7 debug    debug-level messages

# In rsyslog rules, the selector is facility.severity:
# auth.err       → auth messages at err level and above
# *.warning      → all facilities at warning and above
# kern.=debug    → kernel debug messages ONLY (= means exact match)
# auth,authpriv.* → auth and authpriv at any severity

The facility/severity pair is encoded as an integer in the syslog protocol. The kernel uses kern.emerg for panics; SSH uses auth.info for logins; cron uses cron.notice for job completions.

2

Reading rsyslog.conf routing rules.

/etc/rsyslog.conf and files in /etc/rsyslog.d/ contain rules that match selectors and route them to actions:

# View the main config:
cat /etc/rsyslog.conf

# Typical Ubuntu/Debian routing block:
# auth,authpriv.*          /var/log/auth.log
# *.*;auth,authpriv.none   -/var/log/syslog
# kern.*                   -/var/log/kern.log
# mail.*                   -/var/log/mail.log
# cron.*                   /var/log/cron.log

# Syntax: <selector>  <action>
# Selector: facility.severity (comma-separate multiple facilities)
# Action: /path/to/file  (leading - means async write, slightly faster)
#         @host:port     (UDP forwarding)
#         @@host:port    (TCP forwarding)
#         |/path/pipe    (named pipe)

# The .none modifier excludes a facility:
# *.*;auth,authpriv.none  → all facilities at all severities
#                           EXCEPT auth and authpriv

# Check rsyslog is running:
systemctl status rsyslog

rsyslog processes rules top-to-bottom. A message can match multiple rules and be written to multiple destinations. Unlike iptables, there is no implicit “stop” — a message continues down the ruleset unless you explicitly use the stop action or a discard modifier (~).

3

Forwarding logs to a central collector.

The most common production use of rsyslog beyond local routing is shipping logs to a central syslog server (Graylog, Loki rsyslog input, a SIEM, or another rsyslog instance).

# Forward all logs to a remote syslog server over TCP:
# /etc/rsyslog.d/50-forward.conf
cat <<'EOF' | sudo tee /etc/rsyslog.d/50-forward.conf
# Load the TCP output module:
module(load="omfwd")

# Forward everything to central collector at 10.0.0.5:514 via TCP:
*.* action(type="omfwd"
           target="10.0.0.5"
           port="514"
           protocol="tcp"
           action.resumeRetryCount="-1"
           queue.type="linkedList"
           queue.size="10000"
           queue.filename="fwd-queue"
           queue.saveOnShutdown="on")
EOF

sudo systemctl restart rsyslog

# Verify rsyslog loaded the config without errors:
sudo rsyslogd -N1
# rsyslogd: version ..., config validation run ...
# rsyslogd: End of config validation run. Bye.

# Test by sending a message manually:
logger -p auth.info "test message from $(hostname)"
# On the collector, you should see the message arrive

The queue.saveOnShutdown="on" setting persists the outbound queue to disk so messages are not lost if rsyslog is restarted while the network is down. action.resumeRetryCount="-1" retries indefinitely instead of dropping messages after N failures.

4

journald forwarding to syslog via imjournal.

On modern Ubuntu/Debian, journald is the primary log collector. rsyslog reads from the journal via the imjournal input module, bridging structured journal entries into the classic syslog pipeline.

# The imjournal module is usually already enabled in /etc/rsyslog.conf:
grep -A5 'imjournal' /etc/rsyslog.conf
# module(load="imjournal"
#        StateFile="/var/spool/rsyslog/imjournal.state"
#        RateLimit.Interval="600"
#        RateLimit.Burst="20000"
#        IgnorePreviousMessages="off")

# This means:
# - rsyslog reads new journal entries as they arrive
# - StateFile tracks position (so a restart does not re-send old messages)
# - RateLimit prevents a logging storm from overwhelming rsyslog

# The alternative — ForwardToSyslog in journald.conf — was deprecated:
# DO NOT use ForwardToSyslog=yes (creates a Unix socket that rsyslog reads;
# less reliable than imjournal and not recommended in recent systemd versions)

# To verify messages are flowing from journal → rsyslog:
logger "test-syslog-routing"
grep "test-syslog-routing" /var/log/syslog

The key insight: on a modern box you usually only need to configure rsyslog’s forwarding destination. The journald → rsyslog bridge (imjournal) is already wired up. You are not replacing journald with rsyslog — you are using rsyslog as the forwarding agent for journal data.

5

Using logger to send test messages and verify routing.

logger is the command-line syslog client. It sends a message to syslog using any facility and severity you specify — essential for testing routing rules without triggering real events.

# Send a message at auth.info:
logger -p auth.info "login attempt from 203.0.113.42"

# Send a message at daemon.err:
logger -p daemon.err "connection pool exhausted"

# Send with a custom tag (appears in the log as the program name):
logger -t myapp -p local0.warning "rate limit hit for user 9812"

# Verify routing:
grep "login attempt" /var/log/auth.log       # should appear here
grep "connection pool" /var/log/syslog        # should appear here
grep "rate limit hit" /var/log/syslog         # local0 → syslog by default

# Send to a remote rsyslog (useful for end-to-end test):
logger --server 10.0.0.5 --port 514 -p daemon.warning "remote test message"

logger is indispensable when verifying a new rsyslog routing rule before it goes live: create the rule, restart rsyslog, send a logger test, confirm it appears in the right destination.

Worked example

Configuring rsyslog to forward only auth events to a SIEM.

Security team asks: forward all auth and authpriv messages at any severity to a SIEM at 10.0.1.100:6514 over TCP. Local routing should be unchanged.

# Create a targeted forwarding rule:
sudo tee /etc/rsyslog.d/60-siem-forward.conf <<'EOF'
module(load="omfwd")

# Forward auth and authpriv at all severities to SIEM:
if ($syslogfacility-text == "auth" or $syslogfacility-text == "authpriv") then {
    action(type="omfwd"
           target="10.0.1.100"
           port="6514"
           protocol="tcp"
           queue.type="linkedList"
           queue.size="5000"
           queue.saveOnShutdown="on")
}
EOF

# Validate config before restarting:
sudo rsyslogd -N1
# rsyslogd: config validation run: OK

sudo systemctl restart rsyslog

# Test:
logger -p auth.warning "sudo: user artemmac ran ls as root"
# Check SIEM received it (from the collector side)

# Verify it still appears locally:
tail /var/log/auth.log
# Jun 21 15:32:01 host artemmac: sudo: user artemmac ran ls as root
# Local routing intact — the forward rule does not remove from local files
Why this works

Why rsyslog still matters alongside journald. journald is excellent for local structured storage and querying. It is not a log shipper. rsyslog (or Fluentd, Vector, Promtail) is how logs leave the box. The facility/severity taxonomy from 1983 is still the universal language: Graylog, Elasticsearch, Splunk, and every SIEM accept syslog-formatted input. Understanding facility.severity lets you write routing rules that send noisy daemon.debug to /dev/null locally while forwarding auth.* to the SIEM — without changing the application.

Common mistake

ForwardToSyslog=yes in journald.conf is deprecated and unreliable. An older pattern had journald forward over a Unix socket to rsyslog. This is superseded by rsyslog’s imjournal module, which reads the journal natively and tracks its position with a state file. If you see ForwardToSyslog=yes in a journald config, it may still work but is not recommended — use imjournal instead.

Check yourself
Quiz

An rsyslog rule reads: auth,authpriv.* /var/log/auth.log. A second rule reads: *.*;auth,authpriv.none -/var/log/syslog. An SSH login event arrives tagged auth.info. Which files does it appear in?

Recap

The syslog model classifies every log message by facility (which subsystem: auth, cron, daemon, kern…) and severity (how bad: emerg through debug). rsyslog reads these and routes by facility.severity selectors to files, pipes, or remote destinations. On modern Ubuntu/Debian, rsyslog reads from journald via the imjournal module — journald is the collector, rsyslog is the router and shipper. omfwd forwards messages over TCP/UDP to a central collector. logger sends test syslog messages to verify routing rules. The .none modifier excludes a facility from a wildcard match (*.*;auth.none = everything except auth). rsyslog processes rules top to bottom; messages can match multiple rules and reach multiple destinations.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.