Side reading

The first time you run journalctl you get every log line the system has ever produced, oldest first, in a pager. It is not a helpful default and it puts a lot of people off for years.

Almost all of the value is in narrowing it down, and there are only about six ways you need to know.

Narrow by unit #

Nine times out of ten this is what you want:

$ journalctl -u ssh

-u takes a unit name. You can leave off .service. You can pass -u more than once to interleave two services, which is how you watch an application and its database at the same time.

Narrow by boot #

$ journalctl -u ssh -b

-b means "this boot only", and it is the single most useful flag on the tool. Without it you are reading history; with it you are reading the current life of the machine. -b -1 gives you the previous boot, which is how you find out what happened before a crash.

Follow it live #

$ journalctl -u ssh -f

-f follows, like tail -f. Leave it running in one terminal while you cause the problem in another. That is the fastest debugging loop available.

Stop it paging #

$ journalctl -u ssh -b --no-pager | tail -40

--no-pager prints straight to the terminal so you can pipe it. Almost every log-reading command in this book ends with | tail -40, because the end is where the recent problem lives.

Narrow by time #

$ journalctl --since "10 min ago"
$ journalctl --since "yesterday" --until "today"

--since and --until understand both timestamps and plain English like yesterday, today, 1 hour ago. When you know roughly when something broke but not which service caused it, this is how you find out.

Narrow by severity #

$ journalctl -p err -b

-p filters by priority, and err means errors and worse. This is a good five-second health check on a machine you have not looked at in a while. Be aware that plenty of software logs alarming things at warning and genuinely broken things at info, so this narrows rather than decides.

Putting them together #

The combination worth memorising, because it answers "what is wrong with this service right now":

$ systemctl status ssh
$ journalctl -u ssh -b --no-pager | tail -40

systemctl status gives you the current state, whether it is enabled at boot, its main process, and the last few log lines. Then the journal gives you the rest of the story. In that order.

Reading what you find #

A few things that confuse people early on.

Messages can be rate-limited. A suppression notice means some repeated events were dropped. Inspect the service and journald rate-limit settings before treating the visible count as the event count.

The first error is the one that matters. Software tends to fail, then fail again in more visible ways because of the first failure. Scroll up to where it started going wrong rather than reading the loudest line.

Timestamps use the selected output timezone. Use journalctl --utc when correlating systems in different zones, and record the offset with any incident notes.

Not everything is in the journal. Some software writes under /var/log; Docker application output is normally read with docker compose logs and, after chapter 14, copied into Loki. Confirm the configured log driver before deciding that silence means no event occurred.

Keeping it from eating the disk #

The journal is capped, but the cap may be generous. Check what it is using:

$ journalctl --disk-usage

If it is larger than you would like, SystemMaxUse in /etc/systemd/journald.conf sets a limit, and journalctl --vacuum-time=14d clears out anything older than a fortnight. This matters more than it sounds on a machine whose disk you also want to fill with photographs.

Settings

Your values

The book is written with placeholder names so it makes sense to everybody. Put your own in and every chapter, every command and every copy-paste prompt updates to match.

Nothing here is sent anywhere. It is saved in this browser, so it comes back next time. A different browser or a private window gets the placeholders again.

Live preview

$ ssh admin@192.168.1.20
$ sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
$ sudo hostnamectl set-hostname homeserver
$ sudo timedatectl set-timezone Europe/Paris

Real commands from chapters 2, 3 and 4. They change as you type.

The account you log in as. Not root, and not necessarily the same name you use on your laptop.

Introduced in Chapter 2, Meet your server

The book's placeholder is admin

What the machine calls itself. You choose it, and it shows up in your shell prompt and your logs.

Introduced in Chapter 3, A safe front door

The book's placeholder is homeserver

The IP address your server has on your home network, from ip -brief addr.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.20

The address range and prefix shown by ip route or ip -brief addr, written in CIDR form. Copy the real prefix; do not guess /24.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.0/24

The address traffic goes to on its way out of your house, from ip route.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.1

In Region/City form, or Etc/UTC if you would rather read logs in UTC.

Introduced in Chapter 3, A safe front door

The book's placeholder is Europe/Paris

A registered name you control. Chapter 8 uses it for the LAN route; chapter 12 uses a separate private Tailscale name remotely.

Introduced in Chapter 8, One door, many rooms

The book's placeholder is example.com

The email identity allowed to administer the tagged server in your Tailscale policy.

Introduced in Chapter 10, Your own private network

The book's placeholder is you@example.com

The mailbox that should receive actionable home-server alerts.

Introduced in Chapter 14, Knowing it is alive

The book's placeholder is alerts@example.com

Once you save, the prose and the commands read with your names, the copy buttons copy your values, and the copy-paste prompts describe your machine accurately. That last one matters: an assistant told your network is 192.168.1.0/24 when it is not will send you chasing the wrong thing.

Anything you leave empty keeps the book's placeholder.