Kahibaro
Discord Login Register

Systemd logging

Understanding systemd’s Logging Architecture

systemd provides its own logging component called journald (systemd-journald). Unlike traditional logging that writes plain text files in /var/log, journald collects, structures, and indexes log messages from:

Key points specific to systemd logging:

systemd-journald itself is a systemd service, typically defined in systemd-journald.service and systemd-journald.socket.

Journal Storage: Volatile vs Persistent

systemd’s journal can be stored:

By default on many systems:

To enable persistent journaling:

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

After this, journalctl will show logs from previous boots as well, not just the current one.

Using `journalctl` to View Logs

journalctl is the command-line tool for querying the systemd journal. It understands the structured nature of entries and offers many filtering options.

Basic usage

  journalctl
  journalctl -f
  journalctl -b
  journalctl -b -1

The -b option accepts boot IDs or offsets (e.g. -b -2 for two boots ago).

Time-based filters

You can restrict entries by time:

  journalctl --since "2025-01-01 00:00:00"
  journalctl --since "2 hours ago"
  journalctl --since "2025-01-01" --until "2025-01-02 03:00"

Limiting output

To avoid being overwhelmed:

  journalctl -n 100
  journalctl -n 50 -f
  journalctl -r

Formatting output

By default, journalctl prints human-readable lines. You can change the format:

  journalctl -o short
  journalctl -o short-precise
  journalctl -o json
  journalctl -o json-pretty
  journalctl -o json-sse
  journalctl -o verbose -n 1

Filtering by Units, Services, and Processes

Because journald is integrated with systemd, it knows which unit each log line comes from. This allows very precise queries.

By systemd unit

  journalctl -u ssh.service
  journalctl -u nginx.service
  journalctl -u ssh.service -f
  journalctl -u ssh.service -b

You can use systemctl to see unit names:

systemctl list-units --type=service

By process ID (PID)

  journalctl _PID=1234

This is helpful when debugging specific processes that might be short-lived.

By executable or path

  journalctl /usr/bin/sshd

systemd records the path to the executable so this works even across restarts of that service.

Filtering by Fields and Priorities

Each journal entry contains built-in fields (like _PID, _UID, _SYSTEMD_UNIT, PRIORITY, etc.) and user-defined fields from applications.

Priority levels

Systemd uses syslog-style priorities (0 = most severe):

View only warnings and more severe:

journalctl -p warning

Or as a range:

journalctl -p err..alert

Field-based filters

You can specify fields directly on the command line:

  journalctl _UID=1000
  journalctl -u ssh.service -p warning
  journalctl -k

Fields can be combined; journalctl treats multiple field matches on one command line as a logical OR, and separate groups as logical ANDs. For complex queries, shell quoting becomes important.

Example: logs from sshd or nginx since yesterday:

journalctl -u ssh.service -u nginx.service --since "yesterday"

Inspecting Boot and System State with `journalctl`

systemd’s journal is especially useful for investigating boot problems and service failures.

Boot queries

  journalctl --list-boots

This shows for each boot:

You can then query with:

journalctl -b -1              # previous boot
journalctl -b 4d3fd8...       # by boot ID

Investigating service failures

When a service fails, use:

systemctl status nginx.service

This shows recent journal entries for that unit. To see a more complete log:

journalctl -u nginx.service --since "1 hour ago"

If a service fails repeatedly, consider:

Configuring `systemd-journald` (`journald.conf`)

systemd-journald is primarily configured via /etc/systemd/journald.conf. Settings in /usr/lib/systemd/journald.conf (or distribution equivalent) are defaults; /etc/systemd/journald.conf overrides them.

After changes, reload the service:

sudo systemctl restart systemd-journald

Key options you’re likely to tune:

Storage settings

In [Journal] section:

Example to enforce persistent storage:

[Journal]
Storage=persistent

Size and rotation

These control how much disk space the journal can use. Common options:

Example:

[Journal]
SystemMaxUse=1G
SystemKeepFree=500M
MaxRetentionSec=1month

Similar options exist for runtime (volatile) logs (RuntimeMaxUse, etc.).

Rate limiting

To prevent log storms from overwhelming the system:

Example:

[Journal]
RateLimitIntervalSec=30s
RateLimitBurst=1000

This means: if more than 1000 messages arrive within 30 seconds from the same source, further messages will be dropped until the interval passes.

Forwarding to Syslog and Other Destinations

Even when using journald, you might still run a traditional syslog daemon (like rsyslog or syslog-ng) for compatibility, remote log forwarding, or specialized processing.

In journald.conf:

If ForwardToSyslog=yes and a syslog daemon is running, journald sends a copy of messages to it. The syslog daemon then writes them to /var/log/* or forwards them over the network, following its own configuration.

This architecture enables:

Structured Logging with systemd Journal Fields

Every log entry contains fields prefixed by _ (journal-defined) and sometimes without _ (application-defined). Common fields:

You can inspect all fields of a specific entry:

journalctl -n 1 -o verbose

Or filter with arbitrary fields:

journalctl _COMM=sshd
journalctl _SYSTEMD_UNIT=cron.service _PID=1234

Applications that use the systemd journal APIs (or log via sd_journal_print from libsystemd) can also add their own fields (e.g. REQUEST_ID, USER_NAME), enabling very rich filtering.

Restricting Access and Security Considerations

Journal data often contains sensitive information (usernames, IPs, sometimes even commands and arguments). Access is permission-controlled.

Typical access model:

To allow a user to access full system journals, add them to the appropriate group (example Debian/Ubuntu-like):

sudo usermod -aG systemd-journal alice

After group changes, the user must log out and log back in.

For heightened security:

Maintenance: Vacuuming and Cleaning Journals

Even with size limits, you may sometimes need to manually remove old journal entries.

journalctl provides vacuuming options:

  sudo journalctl --vacuum-time=14d
  sudo journalctl --vacuum-size=500M
  sudo journalctl --vacuum-files=5

These commands will delete the oldest data first until the condition is satisfied.

Logging from Services and User Sessions

Services managed by systemd automatically send their standard output and error to the journal, unless configured otherwise.

In a unit file (e.g. /etc/systemd/system/myapp.service), the StandardOutput and StandardError directives control where logs go:

[Service]
ExecStart=/usr/local/bin/myapp
StandardOutput=journal
StandardError=journal

Common values:

User sessions also have their own journals. You can inspect them with:

journalctl --user                           # as that user
journalctl --user -u my-user-service.service

User services are managed by systemd --user and store logs in a per-user journal.

Practical Troubleshooting Patterns with systemd Logging

Some useful workflows relying on systemd logging:

  journalctl -b -1 -p err..alert
  journalctl -u myservice.service -b -p warning
  journalctl -u NetworkManager.service --since "30 min ago"
  journalctl -k -b

Combining systemctl status with targeted journalctl queries provides a tight feedback loop for diagnosing system issues.

Views: 25

Comments

Please login to add a comment.

Don't have an account? Register now!