Is the Service Even Running?
Before you look at code, config, or logs for a deeper cause, ask the boring question first: is the thing even running?
systemd and systemctl
systemd manages every long-running service on the box - starting them at
boot, restarting them if they crash, keeping track of whether they're actually
alive. systemctl is how you talk to it:
systemctl status name.service # is it running, and its last few log lines
systemctl start name.service # start it now
systemctl stop name.service # stop it now
systemctl restart name.service # stop, then start
systemctl enable name.service # start automatically on future boots
systemctl is-active name.service # just "active" or "inactive", for scripting
systemctl is-enabled name.service # just "enabled" or "disabled"
A service called heartbeat exists on this box but was never started. Check
its state first:
systemctl status heartbeat.service
○ heartbeat.service - Heartbeat service
Loaded: loaded (/etc/systemd/system/heartbeat.service; disabled; preset: enabled)
Active: inactive (dead)
Three lines, three separate facts. Loaded means systemd found and
parsed the unit file - disabled means it won't start automatically on the
next boot. Active: inactive (dead) means it's not running right now,
and never crashed either - it's simply never been started. The hollow circle
○ at the very start is systemd's own shorthand for exactly this "inactive"
state.
start affects only right now. enable affects every boot from now on. A
service can be running but not enabled - it'll vanish on the next reboot and
nobody will know why until it's needed.
journalctl - the log for every service
sudo journalctl -u name.service # every log line that service has produced
sudo journalctl -u name.service -f # follow it live, like tail -f
sudo journalctl -u name.service --since "10 min ago" # only the last 10 minutes
sudo journalctl -u name.service --no-pager # print everything at once, don't open the scrolling viewer
By default, journalctl opens its output in a scrolling viewer (arrow keys to
move, q to quit) - the same kind of viewer less uses. That's fine when
you're reading it yourself, but not when you want the output to just print
straight to the screen, for example if you're piping it into grep or copying
it somewhere. --no-pager turns that viewer off and prints everything
directly instead.
Plain journalctl, with no sudo, silently shows only what your own user is
allowed to see - which for a regular account can mean nothing at all for a
root-run service, no error, just an empty result. Reading the system journal is
a root-level operation on most distros unless your user was explicitly added to
the adm or systemd-journal group - so get in the habit of reaching for
sudo here by default.
Bring it back up
Start it, enable it so it survives a reboot, and confirm it's actually doing its job by checking its logs:
sudo systemctl start heartbeat.service
sudo systemctl enable heartbeat.service
systemctl status heartbeat.service
● heartbeat.service - Heartbeat service
Loaded: loaded (/etc/systemd/system/heartbeat.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-09-22 03:44:36 UTC; 6s ago
Main PID: 1345 (bash)
Tasks: 2 (limit: 2367)
Memory: 552.0K (peak: 1.5M)
CPU: 5ms
CGroup: /system.slice/heartbeat.service
├─1345 /bin/bash -c "while true; do echo \"heartbeat ok\"; sleep 5; done"
└─1374 sleep 5
Compare this against the "inactive" version above, line by line: Loaded
now says enabled instead of disabled - enable worked. Active now
says active (running), with a timestamp for exactly when it started, and
the solid ● replaced the hollow ○. Main PID names the actual process
systemd is tracking and will restart if it dies. CGroup lists every process
that belongs to this service - here, the main bash loop and the sleep
it's currently waiting on.
status proves it's running. It doesn't prove it's doing its job - for that,
check what it's actually producing:
sudo journalctl -u heartbeat.service --no-pager
Sep 22 03:44:36 ubuntu-vm systemd[1]: Started heartbeat.service - Heartbeat service.
Sep 22 03:44:36 ubuntu-vm bash[1345]: heartbeat ok
Sep 22 03:44:41 ubuntu-vm bash[1345]: heartbeat ok
The first line is systemd's own record of starting the service. Every line
after that is the service's own output - heartbeat ok, printed every 5
seconds, exactly as its script promised. That's the difference between
"systemd thinks it's running" and "it's actually producing what it should" -
two separate facts, and the second one only comes from the logs.
systemctl start/enable says permission denied
Managing system services needs root - prefix both commands with sudo.
- Previous lesson
- Boot, Shutdown, and Targets - Doing It Safely