Linux and networking
systemd and journald
How systemd runs a service as a unit with restarts and hardening, and how the journal captures its logs so you can query them by service, time and priority.
systemd starts services at boot, restarts them when they crash, captures their output, and orders them against each other. You describe a service in a unit file. Its built-in journal, read with journalctl, keeps each service's stdout and stderr, indexed by unit, time and priority. Together they are how a single VM runs a service without a container platform.
Walking through it
Here is a unit file for a small API. It is a sketch you could adapt. The path and user are examples.
; /etc/systemd/system/orders-api.service
[Unit]
Description=Orders API
After=network-online.target
Wants=network-online.target
[Service]
User=orders
EnvironmentFile=/etc/orders-api/env
ExecStart=/opt/orders-api/bin/server --port 8080
Restart=on-failure
RestartSec=2
TimeoutStopSec=30
LimitNOFILE=65536
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/orders-api
[Install]
WantedBy=multi-user.targetThree lines carry most of the value:
Restart=on-failurebrings the process back after a crash,RestartSec=2waits two seconds between tries.TimeoutStopSec=30is the grace period before SIGKILL, the same idea as in graceful shutdown.LimitNOFILE=65536raises the open file limit. The default soft limit of 1,024 is far too low for a busy server.
The hardening lines run the service as an unprivileged user, stop it gaining privileges, and make most of the filesystem read-only.
Daily commands:
sudo systemctl daemon-reload # after editing a unit file
sudo systemctl enable --now orders-api # start now and at boot
systemctl status orders-api # state, PID, last log lines
systemctl list-units --failed # what is broken on this box?Reading logs:
journalctl -u orders-api -f # follow live
journalctl -u orders-api --since "10 min ago"
journalctl -u orders-api -p err -b # errors since this boot
journalctl -k | grep -i "out of memory" # kernel OOM killsLogs for every host should ship to a central system, so you rarely need journalctl in normal operation. It becomes essential when the shipper itself is broken.
Common mistakes
- Editing a unit file and forgetting
daemon-reload. systemd keeps using the old settings until you reload. - Running the service as root to avoid permission problems. Fix the permission, or grant one capability. See permissions and capabilities.
- Trusting
statusalone. Its last few lines are short. Usejournalctl -ufor the full story.
Check yourself
- You changed the unit file and restarted the service, but the old limit is still active. What did you skip?
systemctl daemon-reload, which makes systemd read the edited file. - Which command shows only errors for
orders-apisince the last boot?journalctl -u orders-api -p err -b.
Key takeaways
- A unit file defines the command, the user, the restart policy and the stop timeout.
- Reload after every edit, then restart the service.
journalctl -u <unit>is the first place to look when a service fails, filtered by time, priority or boot.
Further learning
For the systemd walkthrough, this video shows systemctl and journalctl on a real machine.
Next, see how to tell whether a connectivity problem is the network or the service, in debugging connectivity.
Related
Linux for engineers
The parts of Linux you touch in production, from shell pipelines and systemd services to permissions, disks, network debugging commands and safe remote access.
Processes and signals
What a process is, how to read its state, and how signals and exit codes tell you why it stopped. Exit 137 and 143 come up constantly.
Observability: logs and traces
Structured logs, distributed tracing and OpenTelemetry, so you can ask new questions of a running system instead of guessing which dashboard to open.