Home/ Blog/ Explainers/ Article
Blog · Explainers

How to Use Syslog in Linux: Read, Write and Forward Your Logs

How to use syslog in Linux: read logs with journalctl and /var/log, write entries with logger, and forward them over TCP with an rsyslog queue that survives

Suriq Field Guide cover card titled How to Use Syslog in Linux

To use syslog in Linux, you read logs with journalctl or from the text files in /var/log, write your own entries with the logger command, and ship them off the box by adding a forwarding rule to rsyslog. On a modern server, the systemd journal collects every message first, and rsyslog turns those messages into plain files or forwards them to a central collector.

A plain-English way to picture it: syslog is the building's mailroom. Every program drops a short note in the slot (a log message), each note carries a department label (the facility, such as "authentication" or "mail") and an urgency stamp (the severity, from "emergency" down to "debug"), and the mailroom sorts the notes into the right pigeonholes, which are the files in /var/log. Forwarding means photocopying the notes and sending them to head office, so they still exist if someone burns down the branch.

The configs and outputs below come from a real AlmaLinux 9 server running rsyslog 8.2510, including a test where we took the central collector offline. Logs are the raw material of any log management program, so getting this layer right comes first.

What is syslog on a modern Linux server?

Syslog is both a message format and the logging service that collects those messages. The format is standardized in RFC 5424. On most current distributions, two programs share the job:

  • systemd-journald catches messages from services, the kernel and the logger command, and stores them in a binary journal that you query with journalctl.

  • rsyslog reads from the journal and applies rules: write this kind of message to that file, send everything to that remote server.

Every message has a facility (which part of the system it came from) and a severity (how bad it is). Severities run from 0 to 7: emerg, alert, crit, err, warning, notice, info and debug. An rsyslog rule is written as facility.severity, and the severity means "this level and anything more urgent". So authpriv.* means every private authentication message, and *.err means errors and worse from any source.

FacilityCodeWhat usually writes to it
kern0The kernel
user1Ordinary programs, and logger by default
daemon3Background services
auth4Security and authorization messages
cron9Scheduled jobs
authpriv10Private auth detail: sshd, sudo, PAM on most systems
local0 to local716 to 23Free for your own applications
Common syslog facilities and their numeric codes. Source: RFC 5424, section 6.2.1.

Where are the syslog files on Linux?

The file names depend on the distribution family, which is the first thing that trips people up when they move between servers.

What you wantDebian / UbuntuRHEL / AlmaLinux / Rocky
Logins, sudo, SSH/var/log/auth.log/var/log/secure
General system messages/var/log/syslog/var/log/messages
Cron jobsin /var/log/syslog/var/log/cron
Main rsyslog rulesUbuntu: /etc/rsyslog.d/50-default.conf; Debian: /etc/rsyslog.conf/etc/rsyslog.conf
Default log locations by distribution family. Your server may differ if rsyslog was customized or is not installed.

Two caveats. First, some distributions no longer install rsyslog by default (Debian 12 is one), so /var/log/syslog simply does not exist and the journal is the only log. Run systemctl is-active rsyslog to find out which world you are in. Second, the journal itself may not survive a reboot. On our AlmaLinux 9 host it lives in /run/log/journal, which is held in memory, because /var/log/journal does not exist. There, the rsyslog files are the only copy that outlives a restart.

How do I read syslog in Linux?

Use journalctl for anything the journal holds, and tail or grep for the files. Both need root (or the adm group for the Debian and Ubuntu files; on RHEL-family systems the files are root-only). As an ordinary user, journalctl shows only your own messages and says so.

terminal · read the journal
sudo journalctl -f
sudo journalctl -u sshd --since "1 hour ago"
sudo journalctl -p warning -b
sudo journalctl -t sshd -n 50 --no-pager

In order: follow new messages live, show the SSH service for the last hour, show warnings and worse since the last boot, and show the last 50 messages tagged sshd. The full option list is in the journalctl manual. On the Debian / Ubuntu layout, swap the service name to ssh. For the text files:

terminal · read the files (RHEL family paths)
sudo tail -f /var/log/secure
sudo grep "Failed password" /var/log/secure | tail -20

How do I write my own messages to syslog?

Use logger, which sends a message into syslog with the tag, facility and severity you choose. It is the right way to log from a shell script, and the best way to test a rule before relying on it.

terminal · write a test message
logger -t backup -p local0.err "nightly backup failed: disk full"

Worked example: why a login warning missed /var/log/secure

Here is a trap we found while preparing this guide. Say a script logs a fake failed login with logger -t fieldguide -p auth.warning "failed login for user deploy". You would expect it in /var/log/secure. It will not be there. The reason sits in the stock AlmaLinux 9 rules, copied from the server:

/etc/rsyslog.conf · AlmaLinux 9 default rules (excerpt)
*.info;mail.none;authpriv.none;cron.none action(type="omfile" file="/var/log/messages")
authpriv.* action(type="omfile" file="/var/log/secure")

auth and authpriv are different facilities (codes 4 and 10). Only authpriv goes to /var/log/secure; a message on auth falls through to the first rule and lands in /var/log/messages. Debian and Ubuntu route both facilities to auth.log, so a script that "worked on Ubuntu" silently drops its security events into the general log on a RHEL-family box. If you write a detection that only watches /var/log/secure, it will never see them. The fix is to log with -p authpriv.warning, or to watch both files.

How do I forward syslog to a central server?

Add an omfwd action to rsyslog on each server, pointed at a collector, with a queue so messages wait instead of vanishing when the collector is down. Forwarding matters for security: an attacker who gets root can wipe local logs (we have covered attackers suppressing logs on a hypervisor), but cannot reach back into a copy already sent elsewhere.

Programsshd, cron, loggerjournaldbinary journalrsyslog rulesfacility.severity/var/log fileslocal copyQueue + TCPwaits if collector downCollector / SIEMoff-box copy
How a log message travels on a modern Linux server: the program writes, journald collects, rsyslog applies rules, then writes a local file and forwards a copy through a queue to a central collector.

If systemctl is-active rsyslog reports inactive on any machine, install it first with sudo apt install rsyslog or sudo dnf install rsyslog.

Step 1, the collector. On the central server, create a file that listens on TCP and writes one file per sending host and program:

/etc/rsyslog.d/10-collector.conf · central server
module(load="imtcp")
input(type="imtcp" port="514")
template(name="PerHost" type="string" string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")
*.* action(type="omfile" dynaFile="PerHost")

The collector's own local messages match this rule too, so they also appear under /var/log/remote/<collector-hostname>/. On RHEL-family collectors with SELinux enforcing (the default), TCP port 514 is labeled for rsh, not syslog, so rsyslog is denied the port and nothing arrives. Relabel it, then open the firewall to your servers only (adjust the subnet):

terminal · RHEL-family collector
sudo semanage port -m -t syslogd_port_t -p tcp 514
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="514" protocol="tcp" accept'
sudo firewall-cmd --reload

On Ubuntu with ufw, the firewall equivalent is sudo ufw allow from 10.0.0.0/24 to any port 514 proto tcp, and no SELinux step is needed.

Step 2, each sending server. Forward everything over TCP with a queue. Replace the address with your collector's:

/etc/rsyslog.d/90-forward.conf · every sending server (not the collector)
*.* action(type="omfwd" target="10.0.0.5" port="514" protocol="tcp"
           queue.type="LinkedList" queue.filename="fwd_central"
           queue.maxDiskSpace="1g" queue.saveOnShutdown="on"
           action.resumeRetryCount="-1")

LinkedList keeps the queue in memory, queue.filename lets it spill to disk when memory fills and on shutdown, and a retry count of -1 means keep trying forever instead of giving up. The rsyslog queue documentation explains the trade-offs.

Step 3, check the syntax, then restart. rsyslog will validate a config without loading it, which beats finding a typo after logs stop:

terminal · validate and apply
sudo rsyslogd -N1
sudo systemctl restart rsyslog

A clean run ends with End of config validation run. Bye.

Step 4, prove it end to end. From a sending server, log a line and look for it on the collector. Our test used port 10514 so it could run without root; the config was otherwise identical.

terminal · sending server
logger -t sshd -p authpriv.info "Failed password for invalid user admin from 203.0.113.7 port 52144 ssh2"
collector · /var/log/remote/<host>/sshd.log (actual output)
2026-11-12T12:06:51.150065+02:00 suriqbot sshd Failed password for invalid user admin from 203.0.113.7 port 52144 ssh2

Then the test that matters: stop the collector, send three messages, start it again. With the queue in place, all three arrived about 40 seconds after the collector came back, because rsyslog retries on a timer rather than instantly. But the first message arrived twice:

collector · after the outage (actual output)
2026-11-12T12:07:03+02:00 suriqbot sshd Failed password for root from 198.51.100.1 port 40001 ssh2
2026-11-12T12:07:03+02:00 suriqbot sshd Failed password for root from 198.51.100.2 port 40002 ssh2
2026-11-12T12:07:03+02:00 suriqbot sshd Failed password for root from 198.51.100.3 port 40003 ssh2
2026-11-12T12:07:03+02:00 suriqbot sshd Failed password for root from 198.51.100.1 port 40001 ssh2

Nothing was lost, which is the point of the queue. The duplicate comes from how plain TCP syslog works, and it leads into the limits below.

How do I get syslog into a SIEM like Wazuh?

There are two routes, and the choice depends on whether you can install software on the source. A SIEM (security information and event management system, explained in our guide to what a SIEM is) reads these logs and raises alerts on patterns such as repeated failed logins.

  • Install an agent on the server. The Wazuh agent reads files such as /var/log/secure directly, and can read the journal itself with a journald log format, per the Wazuh localfile reference. This is the better route for servers; our Wazuh agent walkthrough covers setup.

  • Send raw syslog to the Wazuh server. For devices you cannot install an agent on (firewalls, switches, appliances), point their syslog at the server and enable a listener:

/var/ossec/etc/ossec.conf · Wazuh server
<remote>
  <connection>syslog</connection>
  <port>514</port>
  <protocol>tcp</protocol>
  <allowed-ips>192.168.2.0/24</allowed-ips>
</remote>

The Wazuh syslog documentation notes that the allowed-ips setting is mandatory: leave it out and the listener does not take effect. Restart with sudo systemctl restart wazuh-manager. Two cautions: if rsyslog on the same machine already listens on 514, pick another port, and once logs arrive, use wazuh-logtest to confirm a sample line is decoded and matched by the rule you expect.

Where syslog breaks

Syslog is old, simple and everywhere, which also means it fails quietly. The limits we plan around:

  • UDP loses messages without telling you. Classic syslog over UDP port 514 has no delivery confirmation (RFC 5426 says as much). A busy network or a restarting collector means silent gaps. Use TCP.

  • Plain TCP can duplicate or drop a message at reconnect. Our duplicate above is the visible half. The sender cannot be sure what the receiver got before a connection broke. When every event counts, use RELP, rsyslog's acknowledged protocol (the omrelp module), which needs the rsyslog-relp package on both ends.

  • Plain syslog is unencrypted. Login names and IP addresses cross the network in clear text. Over anything but a private link, add TLS to the forwarding action.

  • Bursts get rate-limited. journald drops messages from a service that logs faster than its limit (RateLimitBurst in journald.conf), and leaves a "Suppressed" note. A brute-force attack is exactly the kind of burst that can hit it.

  • Local logs are only as safe as root. Anyone with root can edit or truncate /var/log. Forwarding is what preserves the evidence.

None of this makes syslog a poor choice. It makes it a pipe that needs checking: confirm the files exist, test with logger, forward over TCP with a queue, and test that pipe again after any change.

Topics

Frequently asked questions

Where is the syslog file in Linux?

It depends on the distribution. Debian and Ubuntu write general messages to /var/log/syslog and logins to /var/log/auth.log. RHEL, AlmaLinux and Rocky use /var/log/messages and /var/log/secure. If rsyslog is not installed, there are no text files and the journal is the only log.

How do I view syslog in Linux?

Run sudo journalctl -f to follow messages live, or sudo journalctl -u sshd --since "1 hour ago" for one service. For the text files, use sudo tail -f /var/log/secure on RHEL-family systems or /var/log/auth.log on Debian and Ubuntu.

How do I write a message to syslog from a script?

Use the logger command, for example logger -t backup -p local0.err "nightly backup failed". The -t flag sets the tag and -p sets the facility and severity, which decide which file the message lands in.

Should I forward syslog over UDP or TCP?

Use TCP. UDP syslog has no delivery confirmation, so messages vanish silently when the network is busy or the collector restarts. Pair TCP with an rsyslog queue so messages wait during an outage, and use RELP when every event must arrive exactly once.

What is the difference between auth and authpriv in syslog?

They are two separate facilities, codes 4 and 10. On RHEL and AlmaLinux, only authpriv goes to /var/log/secure, so a message on auth lands in /var/log/messages instead. Debian and Ubuntu send both to auth.log.

See what Suriq finds on your own servers.

Agentless checks for uptime and your cloud, a lightweight agent for detection on each server, and one console that ranks and explains what it finds.