Lesson  in  Linux for SRE / DevOps - Beginner Level

Is the Service Even Running?

on Linux
An intro to systemd, systemctl status/start/stop/restart, and a first look at journalctl - bringing a stopped service back up and confirming it's healthy.

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.