Linux logs are your system's black box recorder. In this lab you will explore the /var/log/ structure, send messages with logger, configure logrotate, understand rsyslog basics, and analyze structured application logs — skills critical for debugging and operations.
total 304
drwxr-xr-x 3 root root 4096 Feb 10 14:05 .
drwxr-xr-x 11 root root 4096 Feb 10 14:12 ..
-rw-r--r-- 1 root root 4860 Feb 10 14:11 alternatives.log
drwxr-xr-x 2 root root 4096 Feb 10 14:12 apt
-rw-r--r-- 1 root root 64549 Feb 10 14:05 bootstrap.log
-rw-rw---- 1 root utmp 0 Feb 10 14:05 btmp
-rw-r--r-- 1 root root 186634 Feb 10 14:12 dpkg.log
-rw-r--r-- 1 root root 3232 Feb 10 14:05 faillog
-rw-rw-r-- 1 root utmp 29492 Feb 10 14:05 lastlog
-rw-rw-r-- 1 root utmp 0 Feb 10 14:05 wtmp
Key log files on a full system:
Log File
Contents
/var/log/syslog
General system messages (Debian/Ubuntu)
/var/log/messages
General system messages (RHEL/CentOS)
/var/log/auth.log
Authentication: SSH, sudo, PAM
/var/log/kern.log
Kernel messages
/var/log/dpkg.log
Package installations/removals
/var/log/apt/
APT package manager logs
/var/log/nginx/
Web server access/error logs
/var/log/journal/
systemd journal binary logs
💡 Log files have different permission levels.auth.log is often readable only by root and the adm group — add your user to adm with usermod -aG adm youruser to read auth logs without sudo.
Step 2: The logger Command — Write to System Log
logger sends messages to the syslog daemon from the command line or scripts.
📸 Verified Output:
Syslog priorities (severity levels):
Level
Number
Use Case
emerg
0
System is unusable
alert
1
Action must be taken immediately
crit
2
Critical conditions
err
3
Error conditions
warn
4
Warning conditions
notice
5
Normal but significant
info
6
Informational messages
debug
7
Debug-level messages
💡 Use logger in shell scripts for proper log integration. Instead of echo "Error occurred", use logger -t myscript -p user.err "Error occurred" — this integrates with syslog, journald, and centralized log aggregators automatically.
Step 3: journalctl — Query the systemd Journal
journalctl queries the binary journal maintained by systemd-journald. It's the primary log tool on modern Linux systems.
📸 Verified Output:
💡 journalctl --no-pager is essential in scripts. Without it, journalctl opens an interactive pager (less) which blocks automation. Always add --no-pager in scripts, cron jobs, and monitoring tools.
Step 4: logrotate — Prevent Logs from Filling Your Disk
logrotate automatically rotates, compresses, and deletes old log files.
📸 Verified Output:
📸 Verified Output:
📸 Verified Output:
logrotate directives explained:
Directive
Meaning
daily / weekly / monthly
Rotation frequency
rotate 7
Keep 7 rotated files
compress
gzip rotated files
delaycompress
Don't compress the most recent rotation
missingok
Don't error if log doesn't exist
notifempty
Skip rotation if log is empty
create 0640 user group
Create new log with these perms
postrotate
Shell script to run after rotation
sharedscripts
Run postrotate once for all matching files
💡 Test logrotate configs with logrotate -d (debug/dry-run mode): logrotate -d /etc/logrotate.d/myapp. It shows what would happen without doing it. Use logrotate -f to force rotation even if not due yet.
Step 5: rsyslog — Traditional Syslog Daemon
rsyslog receives, filters, and routes log messages.
📸 Verified Output:
💡 rsyslog vs journald: On modern systemd systems, journald captures all logs in binary format. rsyslog can subscribe to journald and forward logs to files or remote servers. They complement each other — journald for local structured queries, rsyslog for forwarding and text-file compatibility.
Step 6: Create & Analyze Structured Log Entries
Good log format makes analysis easy. Learn to write and parse structured logs.
📸 Verified Output:
💡 Design logs for grep. Use consistent field ordering, include key=value pairs for easy parsing, and choose a timestamp format that sorts lexicographically (ISO 8601: 2024-01-15 08:00:01). Avoid log messages that span multiple lines — they're hard to grep.
Step 7: tail -f Simulation — Following Logs in Real Time
📸 Verified Output:
💡 tee writes to both stdout and a file simultaneously.command | tee file.log shows output on screen AND saves to file. Use tee -a to append instead of overwrite. Critical for capture logs from interactive processes.
Step 8: Capstone — Log Analysis & Alerting Script
Scenario: Build a log monitoring script that detects anomalies and generates an alert report.
📸 Verified Output:
💡 Integrate log monitoring with alerting. Pipe this script's output to mail -s "Log Alert" [email protected] for email alerts, or use curl -X POST to send to Slack/PagerDuty webhooks. Schedule with cron: */15 * * * * /usr/local/bin/log-monitor.sh >> /var/log/monitor.log 2>&1.
# Basic usage
logger "Application started successfully"
echo "exit: $?"
# With priority (facility.severity)
logger -p user.info "INFO: Service health check passed"
logger -p user.warn "WARN: Disk usage above 80%"
logger -p user.err "ERROR: Database connection failed"
logger -p daemon.crit "CRIT: Out of memory condition"
# With tag (identifies the program)
logger -t myapp -p user.info "User login: alice from 192.168.1.10"
logger -t backup -p user.notice "Backup completed: 1.2GB in 45s"
# Show the message would go to syslog
logger --stderr -p user.info "This also prints to stderr" 2>&1
echo "logger exit code: $?"
exit: 0
This also prints to stderr
logger exit code: 0
apt-get update -qq && apt-get install -y -qq systemd 2>/dev/null | tail -3
# Key journalctl flags:
echo "=== journalctl command reference ==="
cat << 'EOF'
journalctl # All logs (oldest first)
journalctl -n 20 # Last 20 lines
journalctl -f # Follow (like tail -f)
journalctl -p err # Priority: err and above
journalctl -p warning..err # Priority range
journalctl -u nginx.service # Specific unit
journalctl --since "2024-01-15 08:00:00"
journalctl --until "2024-01-15 09:00:00"
journalctl --since "1 hour ago"
journalctl --since today
journalctl --no-pager # Don't use pager (good for scripts)
journalctl -o json # JSON output
journalctl -o json-pretty # Pretty JSON
journalctl --disk-usage # Show journal disk usage
journalctl --vacuum-size=500M # Reduce journal to 500MB
journalctl --vacuum-time=30d # Delete entries older than 30 days
journalctl -b # This boot only
journalctl -b -1 # Previous boot
journalctl _PID=1234 # Messages from specific PID
journalctl _SYSTEMD_UNIT=sshd.service _PRIORITY=3 # Combined filters
EOF
=== journalctl command reference ===
journalctl # All logs (oldest first)
journalctl -n 20 # Last 20 lines
journalctl -f # Follow (like tail -f)
journalctl -p err # Priority: err and above
journalctl -p warning..err # Priority range
journalctl -u nginx.service # Specific unit
journalctl --since "2024-01-15 08:00:00"
journalctl --until "2024-01-15 09:00:00"
journalctl --since "1 hour ago"
journalctl --since today
journalctl --no-pager # Don't use pager (good for scripts)
journalctl -o json # JSON output
journalctl -o json-pretty # Pretty JSON
journalctl --disk-usage # Show journal disk usage
journalctl --vacuum-size=500M # Reduce journal to 500MB
journalctl --vacuum-time=30d # Delete entries older than 30 days
journalctl -b # This boot only
journalctl -b -1 # Previous boot
journalctl _PID=1234 # Messages from specific PID
journalctl _SYSTEMD_UNIT=sshd.service _PRIORITY=3 # Combined filters
# see "man logrotate" for details
# global options do not affect preceding include directives
# rotate log files weekly
weekly
# use the adm group by default, since this is the owning group
# of /var/log/syslog.
su root adm
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
#dateext
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /etc/logrotate.d
# View installed logrotate configs
ls /etc/logrotate.d/