Linux Log Files Explained: Where to Find and How to Read Them

4 min read
Beginner Linux Logs Sysadmin Troubleshooting

Quick Answer: Most logs are in /var/log/. journalctl -xe shows recent system logs. tail -f /var/log/syslog follows live logs. grep "error" /var/log/nginx/error.log searches for errors. journalctl -u nginx shows logs for a specific service.

Where Are the Logs?

Log File What It Contains
/var/log/syslog General system messages (Debian/Ubuntu)
/var/log/messages General system messages (CentOS/RHEL)
/var/log/auth.log Authentication — SSH logins, sudo, failed passwords
/var/log/kern.log Kernel messages — hardware, drivers
/var/log/dmesg Boot messages, hardware detection
/var/log/nginx/access.log Nginx web server requests
/var/log/nginx/error.log Nginx errors
/var/log/apache2/access.log Apache web server requests
/var/log/mysql/error.log MySQL/MariaDB errors
/var/log/postgresql/ PostgreSQL logs
/var/log/fail2ban.log Fail2ban bans and actions
/var/log/ufw.log UFW firewall logs
/var/log/cron.log Cron job execution
/var/log/mail.log Email server logs
/var/log/dpkg.log Package installation history
/var/log/boot.log Boot process

Reading Logs

tail — Watch Live

# Last 20 lines
tail -20 /var/log/syslog

# Follow (live updates)
tail -f /var/log/syslog

# Follow multiple files
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

# Follow with filter
tail -f /var/log/auth.log | grep "Failed"

grep — Search

# Find errors
grep "error" /var/log/syslog
grep -i "error" /var/log/syslog        # Case insensitive

# Find SSH login attempts
grep "sshd" /var/log/auth.log

# Find failed logins
grep "Failed password" /var/log/auth.log

# Count occurrences
grep -c "404" /var/log/nginx/access.log

# Search with context (lines before/after)
grep -B 2 -A 2 "error" /var/log/syslog

# Search in compressed logs
zgrep "error" /var/log/syslog.1.gz

less — Scroll Through

less /var/log/syslog

# Search inside less: type /keyword then Enter
# Next match: n
# Previous match: N
# Go to end: G
# Go to start: g
# Quit: q

awk — Extract Fields

# Nginx: count requests per IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Nginx: count status codes
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# Auth: list all users who logged in
grep "Accepted" /var/log/auth.log | awk '{print $9}' | sort -u

journalctl — Modern Logging

Most modern Linux systems use systemd's journal alongside traditional log files.

# All logs
journalctl

# Recent logs (last boot)
journalctl -b

# Follow (live)
journalctl -f

# Specific service
journalctl -u nginx
journalctl -u ssh
journalctl -u mysql

# Follow a service
journalctl -u nginx -f

# Last N entries
journalctl -u nginx -n 50

# By time
journalctl --since "1 hour ago"
journalctl --since "2026-04-06 10:00" --until "2026-04-06 12:00"
journalctl --since yesterday

# Errors only
journalctl -p err
journalctl -p warning
# Levels: emerg, alert, crit, err, warning, notice, info, debug

# By PID
journalctl _PID=1234

# Kernel messages
journalctl -k

# Disk usage
journalctl --disk-usage

# Clean old logs
journalctl --vacuum-size=500M
journalctl --vacuum-time=2weeks

Common Log Analysis Tasks

Find Who's Trying to Hack Your Server

# Failed SSH attempts
grep "Failed password" /var/log/auth.log | tail -20

# Count failed attempts per IP
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# Successful logins
grep "Accepted" /var/log/auth.log | tail -10

Analyze Web Traffic

# Top 10 IPs by requests
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Top 10 most requested pages
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Count 404 errors
grep " 404 " /var/log/nginx/access.log | wc -l

# Find 500 errors
grep " 500 " /var/log/nginx/access.log | tail -20

# Requests per hour
awk -F: '{print $2":00"}' /var/log/nginx/access.log | sort | uniq -c

Check Why a Service Crashed

# Check service status
systemctl status myapp

# Recent logs for that service
journalctl -u myapp -n 50 --no-pager

# Check for OOM (out of memory) kills
dmesg | grep -i "oom\|killed"
journalctl -k | grep -i "oom\|killed"

Log Rotation

Logs grow forever without rotation. Linux uses logrotate to compress and delete old logs.

Check Current Config

cat /etc/logrotate.conf
ls /etc/logrotate.d/

Create a Custom Rotation

Create /etc/logrotate.d/myapp:

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data www-data
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}
Option Meaning
daily Rotate every day
rotate 7 Keep 7 rotated files
compress Gzip old logs
delaycompress Don't compress the most recent rotated file
missingok Don't error if log file is missing
notifempty Don't rotate if empty
create Create new log file with these permissions
postrotate Run command after rotating
# Test rotation (dry run)
logrotate -d /etc/logrotate.d/myapp

# Force rotation now
logrotate -f /etc/logrotate.d/myapp

journald Limits

# Edit /etc/systemd/journald.conf
SystemMaxUse=500M
SystemMaxFileSize=50M

# Apply
systemctl restart systemd-journald

See Also