Customers cannot pay at ten past two
A shop's card payments stop working in the night. Nothing was changed. The owner phones you at breakfast.
You do not guess. You open the log. It says what the machine did, and when.
By the end of this lesson
Note
I can find what went wrong in a log.
Key words
| Word | What it means | Example |
|---|---|---|
| Log | a file where a program writes what it did | |
| Log line | one entry: a time, a source and a message | |
| Timestamp | the date and time written on a log line | |
| Filter | keep only the lines you care about | grep |
| Timeline | events from many logs put in time order | |
| Evidence | a log line that supports what you claim |
The cells students fill in are left blank in this preview.
A log line has parts
Machines write logs in a steady pattern, so a tool can read them. Learn the pattern once and every line is easy.
A login log line gives the date and time, the machine, the program, and a message. The message holds the facts: who tried, from where, and whether it worked.
The evidence in this lab
ls caseShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
How many lines in the login log?
wc -l case/var/log/auth.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The first two lines of the web log
head -n 2 case/var/log/nginx/access.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The last three lines of the web log
tail -n 3 case/var/log/nginx/access.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Worked example: one web log line
| Part | Example | Meaning |
|---|---|---|
| Address | 192.0.2.77 | Who asked |
| Time | [14/Oct/2026:00:01:49 +0000] | When |
| Request | "GET /login HTTP/1.1" | What they asked for |
| Status | 200 | The answer: 200 worked, 404 not found, 403 refused |
| Size | 2557 | Bytes sent back |
The cells students fill in are left blank in this preview.
Filter first, then count
grep keeps the lines that contain some words. grep -c counts them instead of printing them.
To count by a column, cut the column out with awk, sort it, and let uniq -c count the runs. A second sort -rn puts the biggest number first.
Count the failed passwords
grep -c "Failed password" case/var/log/auth.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Count the accepted logins
grep -c "Accepted" case/var/log/auth.logShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Count the web log by status code
awk '{print $9}' case/var/log/nginx/access.log | sort | uniq -cShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A small excerpt to read
Oct 14 02:11:03 web01 sshd[2211]: Invalid user admin from 198.51.100.7 port 4410
Oct 14 02:11:03 web01 sshd[2211]: Failed password for invalid user admin from 198.51.100.7 port 4410 ssh2
Oct 14 02:11:09 web01 sshd[2214]: Failed password for root from 198.51.100.7 port 4418 ssh2
Oct 14 02:14:40 web01 sshd[2230]: Accepted password for alice from 192.0.2.10 port 5120 ssh2
Worked example: counting by address
| Step | What it does | Result for the excerpt |
|---|---|---|
| 1 | Keep the Failed password lines | 2 lines |
| 2 | Cut out the address after "from" | 198.51.100.7 twice |
| 3 | Count each address | 198.51.100.7: 2 |
| 4 | Look for an Accepted line from it | None, so it never got in |
The cells students fill in are left blank in this preview.
A common mistake
Warning
Many people think the address with the most failed logins is the one that got in. Failures and successes are different lines. An address can fail a thousand times and never succeed. Always look for a success line, then check it came from the address you suspect.
A timeline joins the logs together
One log rarely tells the whole story. Put events from several logs in time order. Then look for what happened first.
The first event matters most. Everything after it may be a result of it.
Worked example: a timeline
| Time | Source | Event |
|---|---|---|
| 02:11 | Login log | Many failed passwords from one address |
| 02:14 | Login log | A login accepted for alice from another address |
| 02:16 | Web log | A request for an admin page, answered 200 |
| 02:30 | Cron log | A new job runs for the first time |
The cells students fill in are left blank in this preview.
Follow a log, and read a long one
Type tail -f and a log name to watch new lines arrive. Press Ctrl+C to stop. A Run cannot press Ctrl+C, so type this one yourself.
Type less and a log name to page through a long file. Press / and a word to search, and q to leave.
Going further
In the web log, column 7 is the page that was asked for. Build one pipeline that keeps only the 404 lines, cuts out column 7, and counts each page.
Sort it so the biggest count comes first and keep the top three. Then say in one sentence what kind of visitor asks for pages that do not exist.