Linux Logs: journalctl and /var/log Complete Guide

Tested on: Ubuntu 26.04 LTS · Debian 12 · Fedora 44 · Arch Linux · openSUSE Tumbleweed — Last updated: June 2026

Linux logs are the first place to look when something breaks. On modern systemd-based systems, journalctl is the primary interface for reading structured log data — covering services, the kernel, boot sequences, and every unit systemd manages. This guide covers journalctl thoroughly, explains the traditional /var/log files that still matter, and walks through real debugging workflows you'll use regularly.

Contents
  1. Prerequisites
  2. The Two Log Systems on Modern Linux
  3. Persistent vs. Volatile Journal Storage
  4. journalctl: Essential Commands
    1. View All Logs
    2. Filter by Time
    3. Filter by Service (Unit)
    4. Filter by Priority (Severity)
    5. Filter by Process, PID, or User
    6. Kernel Messages
    7. Boot Log History
  5. Output Formats
  6. Searching Log Content
  7. Journal Disk Usage and Maintenance
    1. Configure Persistent Retention in journald.conf
  8. Traditional Log Files in /var/log
    1. Further Reading

Prerequisites

  • A systemd-based Linux distribution (Ubuntu, Debian, Fedora, Arch, openSUSE, RHEL/Rocky, etc.)
  • A user account with sudo access — some journal queries require root to see logs from all users and system services
  • Basic terminal familiarity: piping, grep, less

To confirm systemd is running on your system:

systemctl --version
systemd 255 (255.4-1ubuntu8)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT ...

The Two Log Systems on Modern Linux

Most Linux systems in 2026 run two parallel log systems. Understanding why both exist prevents confusion when logs appear in one place but not the other.

SystemToolStorageWhat it covers
systemd journaljournalctl/run/log/journal or /var/log/journalAll systemd units, kernel, boot
syslog (rsyslog / syslog-ng)tail, less, grep/var/log/*.logTraditional text log files

Both systems coexist on most distros. The journal captures everything systemd manages; rsyslog may forward a subset of those messages to /var/log/syslog (Debian/Ubuntu) or /var/log/messages (Fedora/RHEL) for compatibility. On minimal or container-optimized installs, only the journal may be present. Application-specific logs — Nginx, PostgreSQL, MySQL — write directly to their own files under /var/log/ regardless of which daemon is running.

Persistent vs. Volatile Journal Storage

Before querying logs across reboots, you need to know whether your journal is persistent. By default, some distributions store the journal in RAM (/run/log/journal), which means it disappears on reboot. Others write to disk immediately.

# Check where the journal is currently stored
journalctl --disk-usage
Archived and active journals take up 1.2G in the file system.

If the path shown is /run/log/journal, logs are volatile. To make them persistent:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

# Confirm
ls /var/log/journal/

Once persistent storage is active, logs survive reboots and you can query previous boots with -b -1, -b -2, etc.

journalctl: Essential Commands

View All Logs

# All logs, oldest first — opens in less (q to quit, Space to page, G to jump to end)
journalctl

# All logs, newest first
journalctl -r

# Follow live output (like tail -f)
journalctl -f

# Show the last N lines
journalctl -n 100

Filter by Time

Time filtering is one of journalctl's strongest features. Natural language expressions work alongside ISO timestamps.

# Logs since last boot
journalctl -b

# Logs since today midnight
journalctl --since today

# Logs from a specific timestamp
journalctl --since "2026-06-09 10:00:00"

# Logs between two times
journalctl --since "09:00" --until "10:30"

# Relative time expressions
journalctl --since "1 hour ago"
journalctl --since "30 min ago"
journalctl --since yesterday

Filter by Service (Unit)

The -u flag is the most common filter in day-to-day use. You can combine multiple units in a single command.

# Logs for a specific service
journalctl -u nginx
journalctl -u sshd
journalctl -u docker

# Follow a service live
journalctl -u nginx -f

# Multiple services at once — output is interleaved with timestamps
journalctl -u nginx -u php8.3-fpm

# Service logs since last boot only
journalctl -u nginx -b

# Last 50 lines for a service
journalctl -u postgresql -n 50

Filter by Priority (Severity)

Syslog-compatible priority levels run from 0 (emergency) to 7 (debug). Specifying a level shows that level and all levels more severe.

# Priority levels:
# 0 emerg   — system is unusable
# 1 alert   — action must be taken immediately
# 2 crit    — critical conditions
# 3 err     — error conditions
# 4 warning — warning conditions
# 5 notice  — normal but significant
# 6 info    — informational
# 7 debug   — debug-level messages

# Show errors and above (err, crit, alert, emerg)
journalctl -p err

# Warnings and above across all services since boot
journalctl -p warning -b

# Critical messages only, current boot
journalctl -p crit -b

# Errors from a specific service today
journalctl -u nginx -p err --since today

Filter by Process, PID, or User

# By executable path — shows all log entries from that binary
journalctl /usr/sbin/nginx
journalctl /usr/bin/python3

# By specific PID
journalctl _PID=4821

# By user ID (UID 1000 = first non-root user on most systems)
journalctl _UID=1000

# By system user (e.g., www-data, postgres)
journalctl _UID=$(id -u www-data)

Kernel Messages

# Only kernel messages — equivalent to dmesg but with journal filtering
journalctl -k

# Kernel messages since last boot
journalctl -k -b

# Follow kernel messages live (useful during hardware troubleshooting)
journalctl -k -f

# Kernel errors since boot
journalctl -k -b -p err

Boot Log History

When the journal is persistent, you can query any previous boot — invaluable after a crash or unexpected reboot.

# List all recorded boots with timestamps
journalctl --list-boots
-3 a1f2e3d4... Mon 2026-06-06 08:12:01 UTC—Mon 2026-06-06 18:44:22 UTC
-2 b5c6d7e8... Tue 2026-06-07 09:00:05 UTC—Tue 2026-06-07 17:55:10 UTC
-1 f9a0b1c2... Wed 2026-06-08 08:30:00 UTC—Wed 2026-06-08 22:14:33 UTC
 0 d3e4f5a6... Thu 2026-06-09 07:45:11 UTC—present
# Current boot
journalctl -b 0

# Previous boot (the one before current)
journalctl -b -1

# Two boots ago
journalctl -b -2

# Errors from previous boot — essential after a crash
journalctl -b -1 -p err

# Precise timestamps (useful for correlating with application logs)
journalctl -b -o short-precise

Output Formats

journalctl supports several output modes. JSON output is particularly useful when feeding logs into aggregation tools like Elasticsearch, Loki, or a custom parser.

# Default output (short format)
journalctl -u sshd -n 5

# One line per entry, minimal metadata
journalctl -u sshd -o short

# Message text only — no timestamps, no hostname
journalctl -u sshd -o cat

# JSON, one object per line (machine-readable)
journalctl -u sshd -o json -n 5

# Pretty-printed JSON (human-readable, useful for inspection)
journalctl -u sshd -o json-pretty -n 2

# Verbose — shows all journal fields for each entry
journalctl -u sshd -o verbose -n 3

Example JSON output for a single entry:

journalctl -u sshd -o json-pretty -n 1
{
  "__REALTIME_TIMESTAMP" : "1749456311000000",
  "_HOSTNAME" : "webserver01",
  "SYSLOG_IDENTIFIER" : "sshd",
  "_PID" : "1842",
  "MESSAGE" : "Accepted publickey for deploy from 203.0.113.45 port 52341",
  "PRIORITY" : "6",
  "_SYSTEMD_UNIT" : "sshd.service"
}

Searching Log Content

journalctl has no built-in text search — pipe to grep. For large journals, combine time and unit filters first to reduce the data volume before searching.

# Search nginx logs for 404s today
journalctl -u nginx --since today | grep " 404 "

# Case-insensitive error search across all logs since boot
journalctl -b | grep -i "error"

# Search with context lines (2 lines before and after each match)
journalctl -b | grep -i "fail" -B 2 -A 2

# Count occurrences
journalctl -u sshd --since today | grep "Failed password" | wc -l

# Search for multiple patterns
journalctl -b -p err | grep -E "nginx|php|mysql"

Journal Disk Usage and Maintenance

Left unconfigured, a busy server's journal can consume several gigabytes. The vacuum commands clean old data without restarting the journal daemon.

# Check current disk usage
journalctl --disk-usage

# Delete journal files older than 2 weeks
sudo journalctl --vacuum-time=2weeks

# Keep only the most recent 500 MB of logs
sudo journalctl --vacuum-size=500M

# Keep only the last 5 boots worth of journal files
sudo journalctl --vacuum-files=5

Configure Persistent Retention in journald.conf

For long-term control, edit the journal configuration file. Changes require a daemon restart to take effect.

sudo vim /etc/systemd/journald.conf
[Journal]
# Store logs persistently on disk (auto = persistent if /var/log/journal exists)
Storage=persistent

# Maximum disk space the journal may use
SystemMaxUse=1G

# Minimum free disk space to leave on the filesystem
SystemKeepFree=2G

# Maximum age of log entries
MaxRetentionSec=4week

# Maximum size of a single journal file before rotation
SystemMaxFileSize=100M

# Compress journal data
Compress=yes

# Forward logs to syslog (set to no if you don't use rsyslog)
ForwardToSyslog=yes
# Apply changes
sudo systemctl restart systemd-journald

Traditional Log Files in /var/log

The /var/log directory remains relevant even on fully systemd-managed systems. Application daemons write here directly, and rsyslog forwards journal messages to text files for tools that expect them.

Go up

This site uses cookies for analytics and advertising (Google AdSense). By continuing to browse, you accept our use of cookies. Learn more

FileContentsDistros
/var/log/syslogGeneral system messagesDebian, Ubuntu
/var/log/messagesGeneral system messagesFedora, RHEL, Arch
/var/log/auth.logAuthentication, sudo, SSHDebian, Ubuntu
/var/log/secureAuthentication eventsFedora, RHEL
/var/log/kern.logKernel messagesDebian, Ubuntu
/var/log/dpkg.logPackage install/remove historyDebian, Ubuntu
/var/log/dnf.logPackage historyFedora, RHEL
/var/log/nginx/Access and error logsAll (when Nginx installed)
/var/log/apache2/Access and error logsDebian/Ubuntu (Apache)
/var/log/postgresql/Database logsAll (when PostgreSQL installed)
/var/log/mysql/MySQL error logAll (when MySQL installed)