journalctl

dos2unix

Well-Known Member
Joined
May 3, 2019
Messages
4,408
Reaction score
4,601
Credits
41,638
Journalctl is a part of systemd (systemctl). It's great way t view status, and logs.
You know, systemd seems to be a touchy subject for some, but it's light years ahead of sysVinit and rc.unit.
You can do things sysVinit never dreamed of. I've given a few examples of this over the last few days.

But also, sysVinit is almost gone, only a handful of distro's still use it. As the borg would say "Prepare to be assimulated".


If you're running a systemd-based Linux distribution (which is most of them these days), you're using journalctl whether you realize it or not. It's the primary tool for viewing and querying logs from systemd's journal, and while many admins stick to the basics, journalctl has a lot more power under the hood than most people use.

The most common usage you'll see is checking on a specific service when something goes wrong:

Code:
journalctl -xeu servicename.service

Let's break down what those flags do. The -x flag adds explanatory help text from the systemd catalog when available - basically inline documentation for common errors. The -e flag jumps to the end of the log, which is usually where you want to be when troubleshooting. The -u flag filters to a specific systemd unit (service, timer, socket, etc.).

This combination is great for quick service troubleshooting, but journalctl can do much more.

One of the most useful features is time-based filtering. Instead of scrolling through thousands of log entries trying to find when something broke, you can narrow it down:

Code:
journalctl --since "2 hours ago"
journalctl --since "2025-01-29 14:00" --until "2025-01-29 15:00"
journalctl --since today
journalctl --since yesterday

You can combine this with service filtering:

Code:
journalctl -u nginx.service --since "10 minutes ago"

For watching logs in real-time, similar to tail -f on traditional log files:

Code:
journalctl -f

Or for a specific service:

Code:
journalctl -u nginx.service -f

When you're dealing with critical issues, priority filtering helps cut through the noise. Systemd uses the standard syslog priority levels:

Code:
journalctl -p err              # errors only
journalctl -p warning          # warnings and higher
journalctl -p 0..3             # emergency through error

The numeric priorities are: 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug.

You can combine priority with service and time filters:

Code:
journalctl -u mariadb.service -p err --since today

One feature that saves a lot of headaches is boot-specific log viewing. When a system crashes or hangs, you need to see what happened during that boot, not the current one:

Code:
journalctl --list-boots

This shows all recorded boots with their boot IDs, timestamps, and offsets. Then you can view logs from a specific boot:

Code:
journalctl -b              # current boot only
journalctl -b -1            # previous boot
journalctl -b -2            # two boots ago

Or use the specific boot ID:

Code:
journalctl -b 3e4f5a6b2c1d

This is invaluable for troubleshooting "the server crashed overnight" scenarios.

For kernel-specific messages, replacing the old dmesg command:

Code:
journalctl -k              # kernel messages, current boot
journalctl -k -b -1         # kernel messages from previous boot

The output format can be changed depending on what you're doing with the logs:

Code:
journalctl -o json-pretty         # JSON format, readable
journalctl -o json                 # JSON format, one line per entry
journalctl -o verbose              # show all available fields
journalctl -o cat                  # just the message text, no metadata

The json-pretty format is particularly useful when you need to parse logs programmatically or send them to log analysis tools. The cat format is great for piping to grep or other text processing tools.

You can filter on specific fields beyond just the service name:

Code:
journalctl _PID=1234
journalctl _UID=1000
journalctl SYSLOG_IDENTIFIER=sshd
journalctl _COMM=nginx

To see what fields are available, use the verbose output format and look at the field names.

The journal can consume a lot of disk space over time. To see how much space it's using:

Code:
journalctl --disk-usage

To clean up old logs:

Code:
journalctl --vacuum-time=2weeks     # keep only last 2 weeks
journalctl --vacuum-size=500M        # limit total size to 500MB
journalctl --vacuum-files=5          # keep only 5 archived journal files

You can also configure persistent limits in /etc/systemd/journald.conf:

Code:
SystemMaxUse=500M
SystemKeepFree=1G
SystemMaxFileSize=100M

For following multiple services simultaneously, you can specify multiple -u flags:

Code:
journalctl -f -u nginx.service -u mariadb.service -u php-fpm.service

When you're troubleshooting issues that span multiple services (like a web application stack), this lets you see the interactions in real-time.

One thing that catches people off guard: by default, journal logs might not persist across reboots on some distributions. To ensure persistence, make sure /var/log/journal exists:

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

Or set Storage=persistent in /etc/systemd/journald.conf.

A particularly useful combination for debugging services that fail to start:

Code:
journalctl -xeu servicename.service -n 100

The -n 100 flag shows the last 100 lines, which is often enough context to see what led up to the failure without drowning in earlier unrelated messages.

For identifying patterns of repeated errors:

Code:
journalctl -p err --since today | grep "specific error message" | wc -l

Or to see the frequency:

Code:
journalctl -p err --since "1 hour ago" -o cat | sort | uniq -c | sort -rn

This pipeline strips the metadata, sorts the messages, counts duplicates, and shows the most frequent errors first.

When you're correlating issues across multiple systems, the --output-fields option combined with json format can be helpful:

Code:
journalctl -o json --output-fields=MESSAGE,PRIORITY,_HOSTNAME

The journal also captures stdout and stderr from services, which is different from traditional syslog. If a service writes to stdout or stderr, those messages appear in the journal automatically. This means you don't need separate log file configurations for many services.

For debugging systemd itself:

Code:
journalctl -u systemd-journald.service
journalctl -u systemd-logind.service

If you're seeing "journal corruption" messages or missing logs, these are the places to start.

One final tip: if you're grep-ing through journal output and want to preserve the useful metadata like timestamps, use the short-precise output format:

Code:
journalctl -o short-precise | grep "error"

This keeps the timestamp with microsecond precision, which is helpful for correlating events.

The journal's biggest advantage over traditional log files is its structured data. Every log entry has metadata fields that you can query and filter on. Once you get comfortable with field-based filtering and time ranges, you'll find it much faster than grep-ing through text files. The learning curve is a bit steeper than tail and grep, but the payoff in troubleshooting speed is worth it.
 


Might as well throw another log on the systemd fire here
:) .

So I made the statement above everyone uses systemd these days, well it's not 100% true.
Making the rounds, I see...

Still using sysVinit or alternatives:

Devuan
- This is the most prominent one. It's literally a Debian fork created specifically to avoid systemd. They use sysVinit by default (with OpenRC as an option). The entire reason Devuan exists is the systemd controversy.

Void Linux - Uses runit as its init system. It's a rolling release distro that's popular with people who want something lightweight and different.

Gentoo - Technically supports both, but OpenRC is the default and preferred by most Gentoo users. You can use systemd on Gentoo if you want, but the community generally leans away from it.

Alpine Linux - Uses OpenRC. This is huge in the container world because of how lightweight it is. You'll see Alpine as the base for a lot of Docker images.

Slackware - One of the oldest distros still around, and Patrick Volkerding has stuck with sysVinit. Slackware's philosophy is "keep it simple" and avoid major changes.

Artix Linux - Another Arch fork (like Devuan is to Debian) that specifically removes systemd. They offer OpenRC, runit, or s6 as alternatives.

AntiX and MX Linux - Debian-based distros aimed at older hardware, using sysVinit to keep things lightweight.

Some BSD variants - Not Linux, but worth mentioning. FreeBSD, OpenBSD, NetBSD all use their own init systems (rc.d based), not systemd.

The only one of these I use these days is alpine, and I knew about slack, but the rest.. a little surprising.
 
@dos2unix :-

You forgot "Puppy", Ray. She's another that's firmly wedded to SysVinit; in our case, with Puppy's 'frugal' install method, along with many custom routines to offer the usual Puppy experience, systemd just isn't realistic.....because it expects everything to work in a 'standardised' way.

Our Pup's always been out on a limb in this respect. No sudo; minimal Bash command vocabulary; uniquely unusual ways of doing things.....it's a wonder we get any new users at all. Yet we DO; they keep turning up, and more & more of them stick around.

Astonishing, really.

(shrug...)


Mike. ;)
 
On

AntiX and MX Linux - Debian-based distros aimed at older hardware, using sysVinit to keep things lightweight.

MX have returned to the option to have both, with 25.1 . You choose at the Live level which one to install by default, and after install completes and is booted into, you can opt to use the other one in Advanced Options.

Cheers

Wiz
 


Follow Linux.org

Members online


Top