Stop Scattered Logs: Centralize Linux Journald with systemd-journal-remote
If you manage more than a couple of Linux servers, you have probably experienced the pain of SSHing into each one to chase a single event across journalctl outputs. Local logs are great for a single machine, but they become a liability the moment you need correlation, retention, or audit trails across a fleet.
systemd ships with two small, purpose-built tools that solve this without pulling in a full ELK stack: systemd-journal-upload on clients and systemd-journal-remote on the receiver. The beauty is that they preserve the structured binary journal format, support TLS, and handle reconnection state automatically.
Why native journal remote beats most alternatives
- No parsing or loss of structured fields (
_SYSTEMD_UNIT,PRIORITY,MESSAGE, custom fields, etc.) - Resumable uploads via a simple state file
- Socket-activated receiver (low idle resource use)
- Works over plain HTTP for trusted networks or HTTPS with certificate auth
- Querying on the server feels exactly like local
journalctl
This is not a replacement for long-term search or alerting platforms, but it is the simplest way to get centralized, queryable logs with almost zero operational overhead.
Server setup (the receiver)
On your central log host (Debian 12 / Ubuntu 24.04 or newer):
sudo apt update
sudo apt install systemd-journal-remote
Create the storage directory and set ownership:
sudo mkdir -p /var/log/journal/remote
sudo chown systemd-journal-remote:systemd-journal-remote /var/log/journal/remote
Enable the socket (recommended over the service for on-demand behavior):
sudo systemctl enable --now systemd-journal-remote.socket
For production, add a drop-in to control listening mode and output path:
sudo systemctl edit systemd-journal-remote.service
Add:
[Service]
ExecStart=
ExecStart=/lib/systemd/systemd-journal-remote \
--listen-http=-3 \
--output=/var/log/journal/remote
If you want HTTPS (strongly recommended across untrusted networks), switch to --listen-https and supply certificate paths owned by the systemd-journal-remote user.
Firewall example (UFW):
sudo ufw allow 19532/tcp comment "systemd-journal-remote"
Received journals appear as remote-<hostname>.journal files. Query them with:
journalctl --directory=/var/log/journal/remote --since "1 hour ago"
journalctl --file=/var/log/journal/remote/remote-web-01.journal -u nginx
Client setup (the uploader)
On every machine you want to forward logs:
sudo apt install systemd-journal-remote
Edit the upload configuration:
sudo systemctl edit systemd-journal-upload.service --full --force
Or simply edit /etc/systemd/journal-upload.conf:
[Upload]
URL=https://logs.example.com:19532
# For TLS client certificate auth (recommended)
# ServerKeyFile=/etc/ssl/journal/client.key
# ServerCertificateFile=/etc/ssl/journal/client.crt
# TrustedCertificateFile=/etc/ssl/journal/ca.crt
Enable and start:
sudo systemctl enable --now systemd-journal-upload.service
The service maintains /var/lib/systemd/journal-upload/state. If you ever need a full resend, delete that file.
TLS best practices
- Use a proper CA (step-ca, smallstep, or Let's Encrypt for the server cert)
- Generate per-client certificates when possible
- Set
chmod 600on private keys and correct ownership - On the server side, use
--trustto point at your CA bundle
Self-signed certs work fine for homelabs; just distribute the CA and client certs securely (Ansible, scp with strict modes, or even systemd-creds).
Retention and maintenance
On the receiver, you can set limits in /etc/systemd/journal-remote.conf:
[Remote]
MaxUse=100G
KeepFree=20G
MaxFileSec=30day
Or run periodic vacuuming via a systemd timer:
journalctl --directory=/var/log/journal/remote --vacuum-time=90d --vacuum-size=80G
Verification and troubleshooting
On a client:
journalctl -u systemd-journal-upload -f
On the server, watch incoming connections and check that new journal files appear with the expected hostname.
Common gotchas:
- Certificate permission errors (the journal-remote user must read the key)
- Firewall blocking 19532
- Time skew between client and server (journal entries have monotonic timestamps, but wall-clock correlation still matters)
When to layer something else on top
This setup gives you centralized, structured logs you can query with the same tools you already know. For full-text search, alerting, or long-term retention beyond a few months, point a lightweight shipper (Vector, Fluent Bit) at the remote journal directory or use the HTTP gateway (journal-gatewayd) to feed a proper backend.
The native tools keep the operational surface tiny and the data format lossless. In most homelab and small-team environments, that is exactly what you need.
References
-
systemd-journal-remote.service(8)andjournal-remote.conf(5)man pages - DigitalOcean: "How To Centralize Logs With Journald on Ubuntu 20.04"
- systemd source and issue tracker discussions on resume behavior and TLS handling
Written with the goal of keeping Linux operations boringโin the best possible way.
Top comments (0)