Logging
Chapter 36: System Logging - rsyslog, syslog-ng Deep Dive
Section titled “Chapter 36: System Logging - rsyslog, syslog-ng Deep Dive”Mastering Linux System Logging for Production Environments
Section titled “Mastering Linux System Logging for Production Environments”36.1 Understanding Linux Logging Architecture
Section titled “36.1 Understanding Linux Logging Architecture”The Linux Logging Ecosystem
Section titled “The Linux Logging Ecosystem”Linux logging is a multi-layered system that captures, processes, and stores system and application events. Understanding this architecture is crucial for effective system administration and troubleshooting.
Linux Logging Architecture+------------------------------------------------------------------+| || Application Layer || +-------------+ +-------------+ +-------------+ || | nginx | | sshd | | systemd | || +-------------+ +-------------+ +-------------+ || | | | || v v v || +-------------------------------------------------------------+ || | syslog() / journalctl API | || +-------------------------------------------------------------+ || | || v || Kernel Layer || +-------------------------------------------------------------+ || | /proc/kmsg (Kernel Messages) | || +-------------------------------------------------------------+ || | || v || System Logging Daemons || +-------------+ +-------------+ +-------------+ || | rsyslogd | | syslog-ng | | systemd-journald| || +-------------+ +-------------+ +-------------+ || | || +---------------+---------------+ || | | | || v v v || Local Files Remote syslog Database || /var/log/messages Central server (MySQL/PostgreSQL) || |+------------------------------------------------------------------+Syslog Facilities and Priorities
Section titled “Syslog Facilities and Priorities” Syslog Facilities (0-23)+------------------------------------------------------------------+| || 0 (kern) - Kernel messages || 1 (user) - User-level messages || 2 (mail) - Mail system || 3 (daemon) - System daemons || 4 (auth) - Authentication messages || 5 (syslog) - Syslogd internal messages || 6 (lpr) - Line printer subsystem || 7 (news) - Network news subsystem || 8 (uucp) - UUCP subsystem || 9 (cron) - Clock daemon || 10 (authpriv) - Private authentication || 11 (ftp) - FTP daemon || 12-23 - Local use 0-11 || || Syslog Priorities (0-7) || +----------------------------------------------------------+ || | 0 (emerg) - Emergency: system is unusable | || | 1 (alert) - Alert: must be taken immediately | || | 2 (crit) - Critical: critical conditions | || | 3 (err) - Error: error conditions | || | 4 (warn) - Warning: warning conditions | || | 5 (notice) - Notice: normal but significant | || | 6 (info) - Informational: informational | || | 7 (debug) - Debug: debug-level messages | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+36.2 rsyslog Deep Dive
Section titled “36.2 rsyslog Deep Dive”rsyslog Architecture
Section titled “rsyslog Architecture”rsyslog is the most widely used syslog daemon on Linux, offering reliable log forwarding, filtering, and output formatting.
rsyslog Processing Pipeline+------------------------------------------------------------------+| || Input Module Processing Output Module || +----------+ +---------+ +----------+ || | imuxsock |<---->| Queue |<------>| omfile | || +----------+ +---------+ +----------+ || | imtcp | | Filter | | omfwd | || +----------+ +---------+ +----------+ || | imudp | | Template| | omprog | || +----------+ +---------+ +----------+ || | imjournal| | Parser | | ommysql | || +----------+ +---------+ +----------+ || || Key Concepts: || +----------------------------------------------------------+ || | - Input: Where logs come from | || | - Queue: Buffer before processing | || | - Filter: Select/drop messages based on rules | || | - Template: Format output | || | - Output: Where logs go | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Comprehensive rsyslog Configuration
Section titled “Comprehensive rsyslog Configuration”# /etc/rsyslog.conf - Production Configuration
# =============================================================================# MODULES# =============================================================================
# Load modulesmodule(load="imuxsock") # Local logging via /dev/logmodule(load="imjournal") # Systemd journalmodule(load="imklog") # Kernel loggingmodule(load="imudp") # UDP syslog receptionmodule(load="imtcp") # TCP syslog receptionmodule(load="imrelp") # RELP protocol (reliable)module(load="ommysql") # MySQL outputmodule(load="ompgsql") # PostgreSQL outputmodule(load="omelasticsearch")# Elasticsearch output
# =============================================================================# GLOBAL DIRECTIVES# =============================================================================
# Default permissions for new log files$FileOwner root$FileGroup adm$FileCreateMode 0640$DirCreateMode 0755$Umask 0022
# Template for standard format$template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%"$template RFC5424fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32% %msg:::sp-if-no-msg%"
# JSON template for structured logging$template json-log,"{\"time\":\"%TIMESTAMP%\",\"host\":\"%HOSTNAME%\",\"syslogtag\":\"%syslogtag%\",\"pri\":\"%PRI%\",\"msg\":\"%msg:::jsonf:::replace-all-cntrl:::jsonf-replace:::jsonf-replace%\"}%newline%"
# =============================================================================# LOG FILTERS# =============================================================================
# Kernel messageskern.* /var/log/kern.log
# Critical and higher to console*.crit /dev/console
# Authenticationauth,authpriv.* /var/log/secure
# Mailmail.* -/var/log/maillogmail.* @remote-logserver
# Croncron.* /var/log/cron
# Emergency messages to all users*.emerg :omusrmsg:*
# All info but exclude mail and authpriv*.info;mail.none;authpriv.none;cron.none /var/log/messages
# Warnings to separate file*.warn;*.err /var/log/warnings
# Debug messages*.=debug /var/log/debug
# =============================================================================# TEMPLATES# =============================================================================
# Remote logging template with hostname$template RemoteLogs,"/var/log/%HOSTNAME%/%programname%.log"*.* ?RemoteLogs
# High-precision timestamps$template precise,"%TIMESTAMP% %hostname% %syslogtag%%msg%"*.* -?precise
# =============================================================================# FORWARDING TO REMOTE SERVER# =============================================================================
# UDP forwarding (default, faster but unreliable)*.* @remote-server.example.com:514
# TCP forwarding (reliable)*.* @@remote-server.example.com:514
# RELP forwarding (most reliable)*.* :omrelp:remote-server.example.com:1514
# Forward with specific template*.* @@remote-server.example.com:514;RFC3164fmt
# =============================================================================# CONDITIONAL LOGGING# =============================================================================
# Log to file based on program nameif $programname == 'nginx' then /var/log/nginx.logif $programname == 'nginx' then stop
if $msg contains "error" then /var/log/errors.log& stop
# Log specific severityif $syslogseverity <= 3 then /var/log/critical.log& stoprsyslog Filtering Rules
Section titled “rsyslog Filtering Rules”# Drop messages from specific host:hostname , !isequal , "trusted-host.example.com" ~
# Drop messages containing specific pattern:msg , !contains , "heartbeat" ~
# Drop messages from specific facility:facility, !isequal , "local7" ~
# Rate limiting (drop if more than 100 messages in 5 seconds):msg, startswith, "audit" rate-limit:100 0
# Discard after logging*.* /var/log/everything.log& ~
# Parse structured data$syslogtag, contains, "apache2" then { action(type="omfile" file="/var/log/apache.log") action(type="omfwd" protocol="tcp" target="logs.example.com" port="514")}36.3 systemd Journal Deep Dive
Section titled “36.3 systemd Journal Deep Dive”Journal Architecture
Section titled “Journal Architecture” systemd Journal Architecture+------------------------------------------------------------------+| || +-------------+ +-------------+ +-------------+ || | Kernel | | Services | | Users | || | /dev/kmsg | | journalctl | | systemd-sys | || +-------------+ +-------------+ +-------------+ || | | | || v v v || +-------------------------------------------------------------+ || | journald (Journal Daemon) | || | | || | - Collects logs from all sources | || | - Structured logging (key-value pairs) | || | - Indexing for fast searching | || | - Binary format | || +-------------------------------------------------------------+ || | | || v v || /run/log/journal /var/log/journal || (volatile) (persistent - if configured) || |+------------------------------------------------------------------+Comprehensive journalctl Usage
Section titled “Comprehensive journalctl Usage”# =============================================================================# BASIC VIEWING# =============================================================================
# View all logsjournalctl
# View since last bootjournalctl -bjournalctl -b -1 # Previous boot
# View specific bootjournalctl -b abc123
# =============================================================================# TIME-BASED FILTERING# =============================================================================
# Since specific timejournalctl --since "2024-01-01 00:00:00"journalctl --since "1 hour ago"journalctl --since yesterdayjournalctl --since "2024-01-01" --until "2024-01-02"
# Since specific datejournalctl --since "2024-01-01"
# Time rangejournalctl --since "2024-01-01 10:00:00" --until "2024-01-01 11:00:00"
# =============================================================================# PRIORITY FILTERING# =============================================================================
# Priority levels: emerg(0), alert(1), crit(2), err(3), warning(4), notice(5), info(6), debug(7)journalctl -p err # Error and abovejournalctl -p warning # Warning and abovejournalctl -p 0..3 # Emergency to error
# =============================================================================# UNIT/SERVICE FILTERING# =============================================================================
# Specific servicejournalctl -u nginx.servicejournalctl -u nginx.service -f # Follow
# Multiple servicesjournalctl -u nginx.service -u mysql.service
# Failed servicesjournalctl --failedjournalctl -p 3 -b # Errors since boot
# Services that crashedjournalctl --fault
# =============================================================================# PROCESS FILTERING# =============================================================================
# Specific PIDjournalctl _PID=1234
# Specific userjournalctl _UID=1000journalctl _UID=$(id -u username)
# Specific groupjournalctl _GID=1000
# Executable pathjournalctl _EXE=/usr/bin/nginx
# =============================================================================# MESSAGE FILTERING# =============================================================================
# Filter by message contentjournalctl MESSAGE="Failed to start"journalctl -g "error|failed|exception"
# Match fieldjournalctl _SYSTEMD_UNIT="nginx.service"
# Kernel messagesjournalctl -kjournalctl --dmesg
# =============================================================================# OUTPUT FORMATTING# =============================================================================
# Short output (like syslog)journalctl -o short
# Short-iso formatjournalctl -o short-iso
# Export to JSONjournalctl -o json
# Pretty JSONjournalctl -o json-pretty
# Verbose (show all fields)journalctl -o verbose
# Export to catjournalctl -o cat
# =============================================================================# MANIPULATION# =============================================================================
# Follow (tail -f)journalctl -f
# Show last N entriesjournalctl -n 100
# Disk usagejournalctl --disk-usage
# Vacuum old logsjournalctl --vacuum-size=100M # Keep last 100MBjournalctl --vacuum-time=2weeks # Keep 2 weeks
# Vacuum specific timejournalctl --vacuum-files=5 # Keep 5 filesJournal Configuration
Section titled “Journal Configuration”[Journal]# Storage locationStorage=persistent # persistent (disk), volatile (memory), auto, noneCompress=yesSeal=yes
# Size limitsSystemMaxUse=500MSystemKeepFree=500MSystemMaxFileSize=50MSystemMaxFiles=100
# Runtime limitsRuntimeMaxUse=100MRuntimeKeepFree=100M
# ForwardingForwardToSyslog=yesForwardToKMsg=noForwardToConsole=no
# Rate limitingRateLimitIntervalSec=30sRateLimitBurst=1000
# Split user/root journalsSplitMode=uid36.4 Remote Logging
Section titled “36.4 Remote Logging”Centralized Logging Architecture
Section titled “Centralized Logging Architecture” Centralized Logging+------------------------------------------------------------------+| || Client Servers Log Server || +----------------+ +----------------+ || | web1 | | | || | app1 |------->| rsyslogd | || | db1 | | | || | +--------+ | | +----------+ | || | |rsyslog |---------->| |Storage | | || | +--------+ | | |Elastic | | || +----------------+ | |search | | || +----------+ | || | | || +------v------+ || | Kibana | || +------------+ || |+------------------------------------------------------------------+Setting Up Remote Logging
Section titled “Setting Up Remote Logging”# =============================================================================# RSYSLOG SERVER - /etc/rsyslog.conf# =============================================================================
# Enable TCP/UDP listenersmodule(load="imudp")module(load="imtcp")
# TCP listenerinput(type="imtcp" port="514" ruleset="RemoteLogging")
# UDP listenerinput(type="imudp" port="514" ruleset="RemoteLogging")
# Ruleset for remote loggingruleset(name="RemoteLogging") { # Store by client hostname template(name="RemoteHost" type="string" string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")
# Create directory if needed action(type="omdir" dir="/var/log/remote/%HOSTNAME%")
# Log to file action(type="omfile" file="?RemoteHost" template="RSYSLOG_FileFormat")
# Also log to central file action(type="omfile" file="/var/log/remote-all.log" template="RSYSLOG_FileFormat")}
# =============================================================================# RSYSLOG CLIENT - /etc/rsyslog.conf# =============================================================================
# Forward all to remote server*.* @@logserver.example.com:514
# Forward with specific template*.* @@logserver.example.com:514;RSYSLOG_SyslogProtocol23Format
# Selective forwardingif $programname == "nginx" then @@logserver.example.com:514& ~
# =============================================================================# TLS-ENCRYPTED REMOTE LOGGING# =============================================================================
# Server: Enable TLSmodule(load="imtcp" tls.tlscfgcmd="")input(type="imtcp" port="514" ruleset="RemoteLogging" tls="on")
# Client: Connect with TLSaction(type="omfwd" protocol="tcp" target="logserver.example.com" port="514" tls="on")36.5 logrotate Deep Dive
Section titled “36.5 logrotate Deep Dive”logrotate Configuration
Section titled “logrotate Configuration”# /etc/logrotate.conf - Main Configuration
# Global settingsweekly # Rotate weeklyrotate 4 # Keep 4 weeks of logscreate # Create new empty file after rotationcompress # Compress rotated logsdelaycompress # Don't compress immediately (wait for next rotate)dateext # Use date suffixdateformat -%Y%m%d # Date formatmaxage 365 # Delete logs older than 365 days
# Include additional configsinclude /etc/logrotate.d
# Default settings for packages/var/log/wtmp { monthly # Rotate monthly create 0664 root utmp # Permissions minsize 1M # Minimum size rotate 1 # Keep 1 copy}
/var/log/btmp { missingok monthly create 0600 root utmp rotate 1}logrotate for Applications
Section titled “logrotate for Applications”/var/log/nginx/*.log { daily # Daily rotation missingok # Don't error if missing rotate 14 # Keep 14 days compress # Compress delaycompress # Wait for next rotation notifempty # Don't rotate if empty create 0640 www-data adm # Permissions
# Execute script after rotation postrotate [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid) endscript
# Shared scripts run once per rotation sharedscripts}
/etc/logrotate.d/apache2/var/log/apache2/*.log { daily missingok rotate 30 compress delaycompress notifempty create 0640 root adm sharedscripts
postrotate /bin/systemctl reload apache2 > /dev/null 2>&1 || true endscript}
/etc/logrotate.d/mysql/var/log/mysql/*.log { daily rotate 7 missingok create 660 mysql mysql compress postrotate test -x /usr/bin/mysqladmin || exit 0 mysqladmin --silent flush-logs endscript}36.6 Exam Tips
Section titled “36.6 Exam Tips”- Syslog facilities: Know 0-23 (kern, user, mail, daemon, auth, etc.)
- Syslog priorities: Know 0-7 (emerg to debug)
- rsyslog: Understand filters, templates, and output modules
- journalctl: Know filtering by time, priority, unit, and field
- journald config: Storage, size limits, forwarding settings
- Remote logging: Understand UDP vs TCP vs RELP
- logrotate: Know directives (rotate, compress, missingok, etc.)
- Troubleshooting: Use journalctl for debugging
- Centralized logging: Understand architecture
- Security: Know log file permissions
Summary
Section titled “Summary”In this chapter, you learned:
- ✅ Linux logging architecture overview
- ✅ Syslog facilities and priorities
- ✅ rsyslog configuration and filtering
- ✅ systemd journal and journalctl usage
- ✅ Remote logging setup
- ✅ logrotate configuration
- ✅ Log management best practices
Next Chapter
Section titled “Next Chapter”Chapter 37: Logrotate and Log Management
Last Updated: February 2026