Reading Linux Logs: journalctl, auth.log & syslog
Every login, every sudo, every service that starts or crashes, Linux writes it all down. Logs are the system's diary, and reading them is a core skill for two jobs at once: an admin debugging what broke, and a security person reconstructing who did what, and when. In this lesson you'll build a 24-hour timeline from the logs: who logged in, what they ran with sudo, and which services restarted.
Two logging worlds
Modern Linux keeps logs in two places, and you'll meet both:
- Plain-text files under
/var/log/, the traditional way. Read them with the tools you already know:cat,less,grep,tail. - The systemd journal , a structured, binary log read only with
journalctl. It's the modern default and often has more detail.
Most systems have both, so learn to move between them.
The key files in /var/log/
| File (Debian/Ubuntu) | On RHEL/CentOS | What's in it |
|---|---|---|
/var/log/auth.log | /var/log/secure | logins, sudo, failed passwords, sessions |
/var/log/syslog | /var/log/messages | general system + services (start/stop), cron |
/var/log/kern.log | (in messages) | kernel messages |
/var/log/dpkg.log | /var/log/yum.log | package installs |
On a real box these files are readable only by root or the
admgroup, so you'd prefix the commands below withsudo. In this sandbox they're open so you can practise directly.
journalctl and its filters
journalctl on its own dumps the whole journal (oldest first, in a pager). Its power is in the filters, and you'll use these constantly:
journalctl -u ssh # only the ssh service's logs
journalctl -u nginx --since today # one service, since midnight
journalctl --since "24 hours ago" # everything in the last day
journalctl --since "2026-07-05 00:00:00" --until "2026-07-05 23:59:59"
journalctl -f # follow live (like tail -f)
journalctl -b # only this boot (--list-boots to see them)
journalctl -p err # only errors and worse
journalctl -k # kernel messages
journalctl _COMM=sudo # every invocation of the sudo binary
journalctl -n 50 -r # the last 50 lines, newest first
-u (unit), --since/--until (time), and -p (priority) are the three you'll reach for most.
Building the 24-hour timeline
Now put it together to answer the three questions.
Who logged in (and who tried)?
grep "Accepted" /var/log/auth.log # successful logins
grep "Failed password" /var/log/auth.log # failed attempts (brute force!)
journalctl -u ssh --since "24 hours ago" # the same, from the journal
last # login history (from wtmp)
lastb # FAILED logins (from btmp)
who / w # who is logged in right now
A successful login line reads: Accepted publickey for learner from 10.0.0.5 .... A wall of Failed password for root from 203.0.113.9 is a brute-force attempt, a real detection you'll make from these logs.
What did they run with sudo?
grep sudo /var/log/auth.log
journalctl _COMM=sudo --since "24 hours ago"
Each sudo line names the user, the target user, and the exact command:
sudo: learner : TTY=pts/0 ; PWD=/home/learner ; USER=root ; COMMAND=/usr/bin/apt update
That single line tells you learner ran apt update as root at that moment, a complete audit trail.
Which services restarted?
journalctl -u nginx --since "24 hours ago"
journalctl --since "24 hours ago" | grep -iE "Started|Stopped|Reloading"
grep systemd /var/log/syslog
systemd logs a Stopping... then Started ... pair around every restart, so a service that keeps restarting (a crash loop) or one that restarted at an odd hour jumps right out.
Reading a log line
Every syslog-style line has the same shape:
Jul 5 11:48:03 web-01 sudo: deploy : USER=root ; COMMAND=/usr/bin/systemctl reload nginx
└── timestamp ──┘ └host┘ └proc┘ └────────────── message ──────────────────┘
Timestamp, hostname, the process (and often its PID in [...]), then the message. Once you see that pattern, every log file reads the same way.
The bits beginners miss
- Log rotation. Logs don't grow forever,
logrotaterenames and compresses old ones:auth.log->auth.log.1->auth.log.2.gz. To search history including the compressed files, use theztools:zgrep "Failed password" /var/log/auth.log.*,zcat,zless. Config lives in/etc/logrotate.conf. - The login-record commands.
last(successful logins),lastb(failed),lastlog(last time each user logged in), andwho/w(who's on right now) come from separate binary files (wtmp,btmp), not the text logs, use them alongside. dmesgshows the kernel ring buffer (hardware, drivers, out-of-memory kills).tail -f logfilewatches a log live;less logfilethen/patternsearches interactively.- Journal persistence. By default the journal may be wiped on reboot unless
/var/log/journal/exists (Storage=persistent), so don't assume yesterday's journal is still there. - Logs can be tampered with. Attackers clear
auth.logor wipe journal entries to hide their tracks, which is why important systems ship logs to a separate central server the attacker can't reach. (You'll see the attacker's side of this in "covering tracks" later.)
Try it (terminal)
grep "Failed password" /var/log/auth.log, spot the brute-force source IP.grep sudo /var/log/auth.log, every sudo command that was run.journalctl -u ssh, the ssh service's own timeline.last, the login history, thengrep systemd /var/log/syslogfor service start/stop events.
Why this matters
When something breaks, or someone breaks in, the logs are where the answer lives. Being able to move between auth.log, syslog, and journalctl, and to filter them by time, service, and user, turns a wall of text into a clear timeline of who did what. It's the everyday skill of the sysadmin and the first tool of the incident responder.