Every Linux system generates logs. From boot events and kernel messages to application errors and service crashes, logs are the single most important diagnostic tool available to a system administrator. Before systemd became the dominant init system, logs were scattered across multiple files in /var/log/, managed by syslog daemons like rsyslog or syslog-ng. While those tools still exist, systemd introduced its own logging system called the journal, managed by a component called systemd-journald. In this guide, you will learn how to use journalctl to view, filter, search, and manipulate systemd logs on a Linux server.

Prerequisites

  • A Linux system running systemd (Ubuntu 16.04+, CentOS 7+, Debian 8+, Fedora, Arch, etc.)
  • A user account with sudo privileges or root access

Understanding the systemd Journal

Before diving into commands, it helps to understand what the journal actually is.

systemd-journald is a system service that collects log messages from:

  • The Linux kernel (via /dev/kmsg)
  • Early boot messages
  • Standard output and standard error of system services
  • Syslog messages (from applications using the syslog API)
  • Audit records (from the kernel audit subsystem)
  • Structured log messages from applications using the systemd journal API

Unlike traditional text-based log files, journal data is stored in a binary format in /var/log/journal/ (for persistent storage) or /run/log/journal/ (for volatile, memory-only storage that does not survive reboots).

Basic Usage: Viewing All Logs

The simplest way to use journalctl is to run it with no arguments:

journalctl

This displays all journal entries from oldest to newest, piped through a pager (usually less) so you can scroll through them. The output looks similar to traditional syslog output:

May 18 10:23:01 myserver systemd[1]: Started Daily apt download activities.

May 18 10:23:01 myserver systemd[1]: anacron.service: Succeeded.

May 18 10:25:12 myserver sshd[3421]: Accepted publickey for admin from 192.168.1.10

May 18 10:25:13 myserver sudo[3445]: admin : TTY=pts/0 ; PWD=/home/admin ; USER=root

Each line contains: timestamp, hostname, process name and PID, and the log message.

To view the most recent entries first (reverse chronological order):

journalctl -r

Operation 1: Viewing Logs Without a Pager

By default, journalctl pipes output through less. If you want to print all output directly to the terminal (useful for scripting or piping to other tools), use:

journalctl --no-pager

You can then pipe the output to other tools:

journalctl --no-pager | grep "error"

journalctl --no-pager | wc -l

journalctl --no-pager > all-logs.txt

Operation 2: Following Logs in Real Time

One of the most common tasks is watching logs as they arrive — similar to tail -f on a log file:

journalctl -f

This streams new journal entries as they appear. It is invaluable when you are:

  • Restarting a service and watching for errors
  • Testing an application and monitoring its output
  • Debugging a script that writes to the journal

Press Ctrl+C to stop the stream.

You can combine -f with filters. For example, to follow logs for a specific service in real time:

journalctl -u ssh.service -f

Operation 3: Filtering by Systemd Unit (Service)

Filtering by service unit is one of the most frequently used journalctl features. Use the -u flag followed by the service name:

journalctl -u ssh.service

You can query multiple units at once:

journalctl -u docker.service -u cron.service

This is far more convenient than grepping through /var/log/syslog for a specific process name, especially when a service uses multiple processes or spawns child processes under different names.

To see only the most recent entries for a service:

journalctl -u cron.service -n 50

This shows the last 50 lines for the nginx service.

Operation 4: Viewing a Specific Number of Lines

The -n flag limits output to the last N lines, similar to tail -n:

journalctl -n 100

Shows the last 100 journal entries across all services.

journalctl -n 20 -u ssh.service

Shows the last 20 lines for the SSH daemon.

If you omit the number after -n, it defaults to 10 lines:

journalctl -n

Operation 5: Filtering by Boot Session

The journal tracks which boot session each log entry came from. This is extremely useful for diagnosing issues that happened in a previous boot — a feature that traditional log files do not support natively.

List all available boot sessions:

journalctl --list-boots

Output example:

-3  abc123def456  Thu 2026-05-16 08:10:02 UTC—Thu 2026-05-16 22:45:11 UTC

-2  def789ghi012  Fri 2026-05-17 07:30:15 UTC—Fri 2026-05-17 23:59:58 UTC

-1  jkl345mno678  Sat 2026-05-18 09:00:05 UTC—Sat 2026-05-18 18:30:00 UTC

 0  pqr901stu234  Sun 2026-05-19 07:45:00 UTC—present

The leftmost column is the boot offset: 0 is the current boot, -1 is the previous boot, -2 is two boots ago, and so on.

View logs from the current boot:

journalctl -b

View logs from the previous boot:

journalctl -b -1

View logs from two boots ago:

journalctl -b -2

View logs from a specific boot by ID:

journalctl -b 29eefdcbb1c344c8b405ea5980cedbaa

This is particularly powerful when a server crashed or rebooted unexpectedly — you can pull up the logs from the last boot session and see exactly what happened before the crash.

Operation 6: Filtering by Time and Date

You can filter journal entries by time ranges using --since and --until. These accept flexible date/time formats:

View logs since a specific date and time:

journalctl --since "2026-05-18 10:00:00"

View logs until a specific time:

journalctl --until "2026-05-18 12:00:00"

View logs in a specific time window:

journalctl --since "2026-05-18 09:00:00" --until "2026-05-20 11:00:00"

Using relative time expressions:

journalctl --since "1 hour ago"

journalctl --since "2 days ago"

journalctl --since yesterday

journalctl --since today

journalctl --since "1 hour ago" --until "30 minutes ago"

These human-readable expressions make it easy to zero in on a specific window without calculating exact timestamps. Combine time filters with unit filters for precise queries:

journalctl -u mysql.service --since "2026-05-18 00:00:00" --until "2026-05-18 06:00:00"

Operation 7: Filtering by Process, User, or Group

You can filter journal entries by the PID, UID, or GID of the process that generated them.

Filter by PID:

journalctl _PID=317

Filter by UID (user ID):

journalctl _UID=1000

Filter by GID (group ID):

journalctl _GID=1000

Find your UID:

id -u youruser

View all logs generated by the www-data user (common for web servers):

journalctl _UID=$(id -u www-data)

Operation 8: Filtering by Kernel Messages

To view only kernel messages (equivalent to dmesg):

journalctl -k

This is useful for hardware issues, driver errors, OOM (out of memory) kills, and filesystem errors.

Kernel messages from the previous boot:

journalctl -k -b -1

Kernel messages since the last hour:

journalctl -k --since "1 hour ago"

Operation 9: Output Formats

By default, journalctl outputs in a human-readable format. However, the journal stores rich structured data, and you can request different output formats using the -o flag.

Short format (default):

journalctl -o short

Verbose format — shows all metadata fields:

journalctl -o verbose

Output includes fields like _HOSTNAME, _TRANSPORT, _SYSTEMD_UNIT, _COMM, PRIORITY, and many more.

JSON format — one JSON object per line:

journalctl -o json

Pretty-printed JSON:

journalctl -o json-pretty

JSON output is invaluable for log ingestion pipelines. You can pipe it to jq for further processing:

journalctl -o json | jq '.MESSAGE'

journalctl -u nginx.service -o json | jq '{time: .__REALTIME_TIMESTAMP, msg: .MESSAGE}'

Cat format — message text only:

journalctl -o cat

Useful when you only want the raw message text without timestamps or hostnames.

Export format — for backup/transfer:

journalctl -o export > journal-backup.export

Operation 10: Searching Logs with grep

Since journalctl --no-pager outputs plain text, you can combine it with grep for pattern matching:

journalctl --no-pager | grep "Failed password"

journalctl --no-pager -u sshd | grep "Invalid user"

journalctl --no-pager --since today | grep -i "error"

For case-insensitive matching:

journalctl --no-pager | grep -i "oom"

For multiple patterns:

journalctl --no-pager | grep -E "error|warning|critical"

Conclusion

journalctl is one of the most powerful and versatile log management tools available on modern Linux systems. Unlike scattered text log files, the systemd journal gives you a single, structured, indexed source of truth for everything that happens on your server, from the very first kernel message at boot to every line written by your applications.

Помог ли вам данный ответ? 0 Пользователи нашли это полезным (0 голосов)