Setup log aggregation with rsyslog and logrotate for centralized system monitoring

Intermediate 45 min Apr 30, 2026 760 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure rsyslog for centralized log collection across servers, implement advanced logrotate policies for automated retention, and set up remote log shipping with filtering for comprehensive system monitoring and audit compliance.

Prerequisites

  • Root or sudo access
  • Multiple Linux servers
  • Basic networking knowledge
  • Understanding of syslog facilities

What this solves

Centralized logging is essential for monitoring distributed systems, troubleshooting issues across servers, and maintaining audit compliance. This tutorial configures rsyslog for collecting logs from multiple sources, implements logrotate policies for automated retention management, and sets up remote log shipping with filtering to create a robust centralized monitoring system.

Step-by-step configuration

Update system packages

Start by updating your package manager to ensure you have the latest versions of rsyslog and logrotate.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install rsyslog and logrotate

Install the required packages for centralized logging and log rotation management.

sudo apt install -y rsyslog logrotate
sudo dnf install -y rsyslog logrotate

Configure rsyslog server for centralized logging

Configure the rsyslog server to receive logs from remote clients. This creates a centralized collection point for all your servers.

# Enable UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 0.0.0.0

# Enable TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

# Create log directories based on hostname
$template DynFile,"/var/log/centralized/%HOSTNAME%/%PROGRAMNAME%.log"
$template LogFormat,"%TIMESTAMP% %HOSTNAME% %syslogtag% %msg%\n"

# Store remote logs in separate files by hostname
*.* ?DynFile;LogFormat

# Stop processing after writing to dynamic file
& stop

Create log directory structure

Create the directory structure for centralized logs and set proper ownership for the syslog user.

sudo mkdir -p /var/log/centralized
sudo chown syslog:adm /var/log/centralized
sudo chmod 750 /var/log/centralized

Configure client log forwarding

Set up client servers to forward their logs to the central rsyslog server. Add this configuration to each client server.

# Forward all logs to central server
*.* @@203.0.113.10:514

# Forward specific facilities with different priorities
auth,authpriv.* @@203.0.113.10:514
mail.* @@203.0.113.10:514
cron.* @@203.0.113.10:514

# Local logging with filtering
local0.info /var/log/application.log
local1.warn /var/log/security.log

# Stop processing forwarded messages locally
& stop

Configure advanced log filtering

Implement filtering rules to process different log types and reduce noise in your centralized system.

# Filter by program name
:programname, isequal, "sshd" /var/log/centralized/ssh.log
:programname, isequal, "nginx" /var/log/centralized/nginx.log
:programname, isequal, "mysql" /var/log/centralized/mysql.log

# Filter by facility and severity
kern.crit /var/log/centralized/kernel-critical.log
auth.info /var/log/centralized/auth.log
mail.* /var/log/centralized/mail.log

# Filter messages containing specific strings
:msg, contains, "Failed password" /var/log/centralized/failed-logins.log
:msg, contains, "connection refused" /var/log/centralized/connection-errors.log
:msg, contains, "Out of memory" /var/log/centralized/memory-issues.log

# Discard debug messages to reduce log volume
kern.debug ~
*.debug ~

Configure firewall for log reception

Open the required ports for rsyslog communication between servers.

sudo ufw allow 514/udp comment 'rsyslog UDP'
sudo ufw allow 514/tcp comment 'rsyslog TCP'
sudo ufw reload
sudo firewall-cmd --permanent --add-port=514/udp --add-port=514/tcp
sudo firewall-cmd --reload

Configure logrotate for centralized logs

Set up comprehensive logrotate policies to manage disk space and retention for your centralized logging system.

/var/log/centralized/*/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 syslog adm
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

/var/log/centralized/ssh.log {
    daily
    rotate 90
    compress
    delaycompress
    missingok
    notifempty
    create 644 syslog adm
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

/var/log/centralized/auth.log {
    weekly
    rotate 52
    compress
    delaycompress
    missingok
    notifempty
    create 640 syslog adm
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}

Configure application-specific logrotate policies

Create specialized rotation policies for high-volume applications with different retention requirements.

/var/log/application.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 app-user app-group
    copytruncate
    postrotate
        systemctl reload application-service || true
    endscript
}

/var/log/security.log {
    daily
    rotate 365
    compress
    delaycompress
    missingok
    notifempty
    create 600 root root
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi \
    endscript
    postrotate
        systemctl reload rsyslog || true
    endscript
}

Set up log monitoring and alerting

Create monitoring scripts to watch for critical log events and send alerts when thresholds are exceeded.

#!/bin/bash

# Log monitoring script for centralized logging
LOG_DIR="/var/log/centralized"
ALERT_EMAIL="admin@example.com"
TMP_DIR="/tmp/log-monitor"

mkdir -p "$TMP_DIR"

# Check for failed login attempts
fail_count=$(grep -c "Failed password" "$LOG_DIR/failed-logins.log" 2>/dev/null || echo 0)
if [ "$fail_count" -gt 50 ]; then
    echo "High number of failed login attempts: $fail_count" | \
    mail -s "Security Alert: Failed Logins" "$ALERT_EMAIL"
fi

# Check for disk space issues
df -h "$LOG_DIR" | awk 'NR==2 {if(int($5) > 85) print "Log partition usage: " $5}' | \
while read alert; do
    echo "$alert" | mail -s "Disk Space Alert" "$ALERT_EMAIL"
done

# Check for service errors
grep -i "error\|critical\|emergency" "$LOG_DIR"/*/*.log | \
head -20 > "$TMP_DIR/recent-errors.log"

if [ -s "$TMP_DIR/recent-errors.log" ]; then
    mail -s "System Errors Detected" "$ALERT_EMAIL" < "$TMP_DIR/recent-errors.log"
fi
sudo chmod +x /usr/local/bin/log-monitor.sh

Create systemd timer for log monitoring

Set up automated monitoring that runs every 15 minutes to check for critical events in your centralized logs.

[Unit]
Description=Log Monitoring Service
After=rsyslog.service

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/log-monitor.sh
StandardOutput=journal
StandardError=journal
[Unit]
Description=Run Log Monitor every 15 minutes
Requires=log-monitor.service

[Timer]
OnCalendar=*:0/15
Persistent=true

[Install]
WantedBy=timers.target

Enable and start services

Enable rsyslog and the monitoring timer to start automatically on boot and begin collecting logs immediately.

sudo systemctl enable --now rsyslog
sudo systemctl enable --now log-monitor.timer
sudo systemctl daemon-reload
sudo systemctl restart rsyslog

Test logrotate configuration

Verify that your logrotate policies work correctly before putting them into production use.

sudo logrotate -d /etc/logrotate.d/centralized-logs
sudo logrotate -d /etc/logrotate.d/application-logs
sudo logrotate -f /etc/logrotate.d/centralized-logs

Verify your setup

Test your centralized logging configuration to ensure logs are being collected, filtered, and rotated properly.

# Check rsyslog status
sudo systemctl status rsyslog

# Verify log reception
echo "Test log message" | logger -p local0.info
tail -f /var/log/centralized/*/application.log

# Test remote logging from client
ssh client-server "echo 'Remote test message' | logger -p auth.info"

# Check log rotation
sudo logrotate -v /etc/logrotate.d/centralized-logs

# Monitor log monitoring timer
sudo systemctl status log-monitor.timer
journalctl -u log-monitor.service -f
Note: Replace 203.0.113.10 with your actual rsyslog server IP address in client configurations.

Common issues

SymptomCauseFix
Logs not arriving from clientsFirewall blocking port 514Open UDP/TCP 514 on server firewall
Permission denied creating log filesIncorrect directory ownershipsudo chown syslog:adm /var/log/centralized
Logrotate not workingInvalid configuration syntaxsudo logrotate -d /etc/logrotate.conf to check
Disk space filling up quicklyNo log rotation or compressionEnable compress and adjust rotate count
Lost log messagesUDP packet lossSwitch to TCP: . @@server:514
Monitoring alerts not workingMissing mail configurationInstall and configure postfix or sendmail

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and tuned across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 01:27 · reachable in a message, no ticket form