Logs are one of the first places you look when a Linux system or application behaves unexpectedly. They show service starts, authentication attempts, kernel events, web server requests, and application errors.
For DevOps engineers, log management is not only about reading files. It is also about knowing where logs live, how to filter them quickly, and how to prevent them from filling the disk.
/var/log DirectoryTraditional Linux log files are usually stored under /var/log.
Useful examples include:
/var/log/syslog for general system messages on many Debian based systems/var/log/auth.log for authentication related events/var/log/kern.log for kernel messages/var/log/nginx/ for Nginx access and error logs/var/log/apache2/ for Apache logsYou can inspect the directory with:
ls /var/log
ls /var/log/nginxDifferent distributions place logs differently, so learn the layout of the systems you operate.
tail -fOne of the quickest ways to follow activity is tail -f.
tail -f /var/log/syslog
tail -f /var/log/nginx/access.logThis keeps the terminal open and streams new lines as they are written.
It is especially useful while restarting a service, testing a deployment, or reproducing an error.
Tip: Open one terminal to follow a log and another terminal to reproduce the issue. Seeing the event appear live often shortens troubleshooting time.
grepRaw logs can be noisy. grep helps you focus on the lines you care about.
grep sshd /var/log/auth.log
grep ERROR /var/log/myapp.log
tail -f /var/log/syslog | grep nginxYou can combine tools to narrow large outputs into something meaningful. That is a core Linux troubleshooting skill.
journalctl for systemd LogsOn systemd-based systems, journalctl reads the system journal.
Show recent journal entries:
journalctlFollow logs live:
journalctl -fShow logs for a specific service:
journalctl -u nginx
journalctl -u sshd -fFilter by time:
journalctl --since "1 hour ago"
journalctl --since "2026-07-14 09:00:00" --until "2026-07-14 10:00:00"Filter by priority:
journalctl -p err
journalctl -p warningjournalctl is powerful because it organizes logs by service, time, boot, and priority rather than forcing you to search every file manually.
Note: Some systems use both traditional files in
/var/logand the systemd journal. You should be comfortable with both approaches.
logrotateWithout rotation, log files can grow until they waste disk space or even cause outages.
logrotate solves this by rotating old logs, compressing them, and deleting very old copies according to policy.
Typical configuration concepts include:
rotate for how many archived files to keepcompress for gzip compression of old logsdaily, weekly, or monthly for rotation schedulemissingok so missing logs do not cause failurenotifempty so empty logs are not rotatedA simplified example config might look like:
cat /etc/logrotate.d/nginxAnd you may see directives such as:
/var/log/nginx/*.log {
daily
rotate 14
compress
missingok
notifempty
}This means Nginx logs are rotated daily, 14 old copies are kept, and archived logs are compressed.
Suppose a web app returns errors after deployment. A sensible sequence is:
tail -f /var/log/nginx/error.log
journalctl -u myapp --since "15 minutes ago"
grep 500 /var/log/nginx/access.logThat helps you inspect the reverse proxy, the application service, and request outcomes together.
Linux log management starts with knowing where logs are stored and how to inspect them quickly. Use /var/log for traditional files, tail -f for live updates, grep for filtering, and journalctl for structured systemd logs.
Then use logrotate so logs stay useful instead of becoming a disk space problem.
<MCQExercise
exercise={{
id: "linux-log-management-q1",
title: "Exercise 1: Following new log lines",
description: "Which command is commonly used to watch a log file as new entries are appended?",
options: [
{ id: "a", text: "tail -f /var/log/syslog" },
{ id: "b", text: "chmod +x /var/log/syslog" },
{ id: "c", text: "df -h /var/log/syslog" },
{ id: "d", text: "ssh-keygen /var/log/syslog" },
],
correctId: "a",
explanation: "tail -f follows a file and prints new lines as they are written. It is one of the fastest ways to observe logs during troubleshooting.",
wrongExplanations: {
b: "Changing execute permission is unrelated to monitoring a log file.",
c: "df -h reports filesystem usage, not live log output.",
d: "ssh-keygen creates SSH keys and has nothing to do with logs.",
},
}}
/>
<MCQExercise
exercise={{
id: "linux-log-management-q2",
title: "Exercise 2: Reading logs for one service",
description: "Which command shows journal entries for the nginx systemd unit?",
options: [
{ id: "a", text: "journalctl -u nginx" },
{ id: "b", text: "grep nginx /etc/hosts" },
{ id: "c", text: "logrotate -u nginx" },
{ id: "d", text: "tail -u nginx" },
],
correctId: "a",
explanation: "journalctl -u nginx filters the systemd journal to entries from the nginx unit. This is often easier than searching broad system logs.",
wrongExplanations: {
b: "/etc/hosts is for hostname mapping, not service logs.",
c: "logrotate manages file rotation and does not query service journal entries this way.",
d: "tail does not have a -u unit filter option for systemd services.",
},
}}
/>
<MCQExercise
exercise={{
id: "linux-log-management-q3",
title: "Exercise 3: Purpose of logrotate",
description: "What problem does logrotate primarily help solve?",
options: [
{ id: "a", text: "It schedules SSH logins" },
{ id: "b", text: "It prevents log files from growing without control by rotating, compressing, and retaining old copies" },
{ id: "c", text: "It changes user passwords every week" },
{ id: "d", text: "It compiles the Linux kernel" },
],
correctId: "b",
explanation: "logrotate keeps logs manageable by archiving them on a schedule, compressing older files, and limiting retention. That helps preserve disk space while keeping useful history.",
wrongExplanations: {
a: "SSH logins are unrelated to log rotation.",
c: "Password management is a separate administrative task.",
d: "Kernel compilation has nothing to do with log retention.",
},
}}
/>
journalctl reads systemd's structured binary journal, which lets you filter by unit, priority, boot and time, journalctl -u nginx -p err --since today is one command where grep across plain files would be several. Files under /var/log are plain text written by rsyslog or by applications directly, and are what non-systemd services and most containers produce. Both usually coexist: use journalctl for anything systemd manages and the files for everything else.
tail -f /var/log/syslog, or tail -F which survives the file being rotated out from under you. Worth preferring, since the plain -f silently follows a file nobody writes to any more after rotation. For systemd, journalctl -f, or journalctl -u myapp -f for one service. Combine with grep for a live filter: tail -F /var/log/nginx/access.log | grep " 500 ".
logrotate handles files: a config in /etc/logrotate.d/ sets how often to rotate, how many to keep and whether to compress, and logrotate -d /etc/logrotate.d/myapp does a dry run so you can check it. For the journal, set SystemMaxUse=500M in /etc/systemd/journald.conf, or clear it now with journalctl --vacuum-size=200M. Note that rotating a file a process holds open does not free space until that process reopens it, which is what copytruncate or a postrotate reload signal is for.
Eight syslog severities, from 0 to 7: emerg, alert, crit, err, warning, notice, info, debug. journalctl -p err shows that level and everything more severe, which is the useful default when investigating. Most applications log at info in normal operation and can be turned up to debug temporarily. Worth remembering to turn it back down, since debug logging is a common cause of a disk filling overnight.
Start with journalctl -p err -b, which shows every error-level message from the current boot across all units, usually the fastest way to see what is broken. Then narrow to a unit with -u. For plain files, sudo grep -ri "error" /var/log --include="*.log" | tail -50 casts a wide net, and adding -A 5 gives you the lines after each match, which is often where the actual cause is. Check timestamps against when the problem started rather than reading from the top.
Triage Linux performance in order: CPU, memory and I/O. Learn what load average counts, why free memory looks low and how to read iowait with vmstat.
Learn what Linux is: kernel versus distribution versus shell, which distro to learn for DevOps, and why servers and containers overwhelmingly run Linux.
Learn the Linux directory tree: what /etc, /var and /usr hold, /tmp versus /var/tmp, virtual /proc and /sys, and the places where disks tend to fill up.