Home / Alt manpages / journalctl(1)

  • journalctl(1)
  • User command
  • linux

Find the Right Logs Fast with journalctl Filters

A service fell over at 2am and journalctl just buried the reason under thousands of lines; a handful of filters digs it back out. You will read one service's logs, narrow them by time, priority and boot, follow new events live and produce output fit for a ticket. Allow about fifteen minutes.

  • Checked against: systemd 255.4-1ubuntu8.17, installed here as the systemd package.
  • You need: a shell and a systemd host with journal data.
  • Access: reading your own journal is ordinarily unprivileged. The system journal may need root or membership of adm, systemd-journal or wheel, depending on the host.
  • What it will not touch: everything below only reads logs, except the clearly marked maintenance commands in step 7.

1. Make the output predictable

Start with a bounded query and switch the pager off. With no options, journalctl shows every entry the calling user can see and pipes it through less when appropriate. Handy at a terminal; in a copied troubleshooting session it looks exactly like a hung command.

$ journalctl --no-pager -n 10 -o short-full
Thu 2026-09-24 16:05:52 BST server.example systemd[1]: Started example.service.
  • -n 10 selects the ten most recent entries.
  • -o short-full gives a complete, locale-independent timestamp with the time zone.
  • -q suppresses informational notices, such as the journal's start point and warnings about inaccessible files.

Your timestamp and message will differ.

Checkpoint

Rerun the command with -n 1. You should get at most one journal entry, and the prompt should come straight back.

2. Filter to one service

Use -u for a systemd unit instead of grepping the displayed text. The unit name is a precise journal match, and it picks up useful messages about the unit, not just lines that happen to mention its name.

$ journalctl --no-pager -u systemd-journald.service -n 20 -o short-full
-- No entries --

That output is valid if the service has no entries visible in the selected journal. Swap in a unit that exists on your host, such as ssh.service or cron.service. Not sure of the name? Check first:

$ systemctl list-units --type=service --all | grep -E 'ssh|cron|journald'
  systemd-journald.service loaded active running Journal Service

That discovery command is separate from journalctl and does not change service state.

Tip

Do not reach for sudo by reflex. If the query says system journals are inaccessible, use a permitted account or ask an administrator to run the read-only query.

3. Add a time window and a priority

When the incident has a known window, use --since and --until. They accept today, yesterday, now and relative values such as -2h. A date with no time means the start of that date.

$ journalctl --no-pager -u example.service \
    --since "2026-09-24 15:00:00" --until "2026-09-24 16:00:00" \
    -p warning..alert -o short-full
  • The range warning..alert includes warning, err, crit, alert and emerg.
  • A single priority such as -p err means that level and every more urgent one.
  • Time zones: -o short-full makes the displayed zone explicit; add --utc for a common incident timeline.

Warning

An empty result is not proof the service did nothing. Check the clock, boot selection, unit name and the account's journal access before widening the query; the service may also log under a different unit or only to another logging system.

4. Compare the current and previous boot

Picking a boot is often faster than guessing timestamps. List them first:

$ journalctl --no-pager --list-boots
IDX BOOT ID                          FIRST ENTRY                 LAST ENTRY
 -1 ca11c983864148f48994654bcdf9431c Mon 2026-09-07 18:39:46 BST Fri 2026-09-11 15:56:05 BST
  0 d2f19c13c81e43bbbf01cedef86bfd83 Fri 2026-09-11 15:59:19 BST Thu 2026-09-24 16:13:35 BST

Your IDs and dates will differ. -b with no argument means the current boot; -b -1 means the one before. Combine that with a unit and a line limit:

$ journalctl --no-pager -b -1 -u example.service -n 50 -o short-full

Checkpoint

Compare -b 0 and -b -1. With only one boot on record, the older query reports no entries, so do not read that as "no failure" until --list-boots confirms the older boot is present.

5. Follow a service while you reproduce

--follow (-f) keeps printing entries as they arrive. Cap the initial backlog so the new lines are not buried:

$ journalctl --no-pager -u example.service -n 20 -f -o short-full

Leave it running, reproduce the problem in another terminal, then press Ctrl+C. This only reads the journal; it does not restart anything.

Tip

For a noisy service, add -p warning or a narrow --since, but remember a priority filter can hide useful context.

To search messages, -g applies a regular expression to the MESSAGE= field:

$ journalctl --no-pager -u example.service --since -30min -g 'timeout|failed' -n 50 -o short-full
  • All-lowercase pattern: case-insensitive by default.
  • Any uppercase letter: case-sensitive, unless you add --case-sensitive=false.
  • Quote the pattern so the shell leaves its punctuation alone.

6. Pick an output format for whoever reads it

  • -o json when another program needs structured records.
  • -o cat when you need only the message text.
  • -o short-full for a human-readable report.
$ journalctl --no-pager -u example.service -n 5 -o json
{"__REALTIME_TIMESTAMP":"...","_SYSTEMD_UNIT":"example.service","MESSAGE":"..."}

A surprise in JSON mode: fields larger than 4096 bytes come out as null by default. --all removes that limit but can allocate very large objects. Values and fields vary by entry, so do not build a parser around a field your application does not guarantee.

Tip

Leave -x out of bug reports. Its catalogue explanations help while investigating, but the manual advises against adding them to bug-report output.

7. Check disk usage before any cleanup

Journal retention is an administrative decision. Look without changing anything:

$ journalctl --disk-usage
Archived and active journals take up 128.0M in the file system.

If you are authorised to remove old archives, confirm the retention requirement first.

  • --vacuum-time=30days, --vacuum-size=500M, --vacuum-files=10 remove archived journal files. They do not remove active files, and may need root.
  • --rotate first makes the limit apply to data written so far, but it changes journal file state.

Warning

Vacuuming destroys retained log history and has no general undo. Preserve anything needed for an incident or compliance archive before running it, and use the smallest approved retention change.

Common traps

  • The pager looks stuck. Add --no-pager, or press q to leave less. A pager is normal behaviour, not a service failure.
  • Only a few entries appear. Check -n, --since, --until and -b. These constraints combine as a logical AND.
  • Logs are missing. Check access, boot availability and whether persistent storage is enabled. journalctl cannot show records that were never retained.
  • Output is hard to compare. Use -o short-full --utc for a stable format and time zone.
  • A command changes state. Normal queries do not. Treat --vacuum-*, --rotate, --flush and --relinquish-var as maintenance operations and review them separately.

Done means

  • Bounded query: you can query a unit with a limited result and no pager.
  • Narrowed incident: you can filter by time, priority and boot.
  • Live follow: you can watch new entries and stop cleanly with Ctrl+C.
  • Right format: you can pick human-readable or JSON output for its actual consumer.
  • Space checked: you looked at journal disk usage before considering destructive retention changes.