Introduction
A process is a running program. A service is a long-running system function managed according to a definition and lifecycle policy. On Ubuntu, systemd reads unit definitions, starts and stops services, tracks their states, and records their output in the system journal.
In this lab, you will use an isolated labex-heartbeat practice service. You will inspect its unit, control its runtime state, configure boot-time enablement, query journal and traditional text logs, follow live output, diagnose a controlled failure, and restore healthy operation. You will not edit unit files or touch the SSH service.
Recognize systemd and Service Units
In this step, you will confirm that systemd is available and distinguish running units from installed unit files.
Enter the lab workspace:
cd /home/labex/project/service-lab
Display the systemd version. The first line is enough for identification:
systemctl --version | head -n 1
Ask systemd for its overall state:
systemctl is-system-running || true
running means all required units are healthy. A training VM can report degraded because an unrelated optional unit failed; the command still proves that systemd is responding.
List a sample of services that are currently running:
systemctl list-units --type=service --state=running --no-pager | head -n 12
A unit is an object managed by systemd. Service units end in .service. Unit files describe what can be managed, even when it is not currently running:
systemctl list-unit-files --type=service --no-pager | head -n 12
Save a compact systemd summary. Command substitution $(...) inserts command output into the text written by printf:
printf 'systemd=%s\nstate=%s\n' "$(systemctl --version | head -n 1)" "$(systemctl is-system-running)" > systemd-summary.txt
cat systemd-summary.txt
Inspect a Service Definition and State
In this step, you will inspect the prepared practice service before starting it.
systemctl status combines the loaded unit path, enablement, runtime state, process information, and recent log lines:
cd /home/labex/project/service-lab
systemctl status labex-heartbeat.service --no-pager
The service should be inactive (dead) and disabled. Inactive means it is not currently running; disabled means it is not configured to start through its install target at boot. These are separate properties.
Display the unit definition:
systemctl cat labex-heartbeat.service
The [Unit] section describes identity and ordering, [Service] defines the process, and [Install] describes enablement. You only inspect this prepared unit; you do not need to write one.
Use systemctl show for machine-readable properties:
systemctl show labex-heartbeat.service -p LoadState -p ActiveState -p SubState -p UnitFileState
Save those properties for verification:
systemctl show labex-heartbeat.service -p LoadState -p ActiveState -p SubState -p UnitFileState > service-properties.txt
cat service-properties.txt
Start, Stop, and Restart a Service
In this step, you will change the runtime state of the practice service and confirm each result.
Starting and stopping system services requires elevated privileges. Start the service:
sudo systemctl start labex-heartbeat.service
Check the concise active state:
systemctl is-active labex-heartbeat.service
The expected output is active. View the fuller status:
systemctl status labex-heartbeat.service --no-pager
The status now includes a main PID. Stop the service and inspect the result:
sudo systemctl stop labex-heartbeat.service
systemctl is-active labex-heartbeat.service || true
The expected state is inactive. Start it again, then use restart to replace the running process in one operation:
sudo systemctl start labex-heartbeat.service
sudo systemctl restart labex-heartbeat.service
systemctl show labex-heartbeat.service -p ActiveState -p SubState -p MainPID
The service should finish this step with ActiveState=active and SubState=running.
Configure Boot-Time Enablement
In this step, you will distinguish a service's current runtime state from whether it is enabled for future boots.
The service is active from the previous step, but setup left its unit file disabled. Check enablement:
systemctl is-enabled labex-heartbeat.service || true
Enable the service:
sudo systemctl enable labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service
Enablement creates links that connect the service to a boot target. It does not need to restart an already running service.
Practice removing those boot links:
sudo systemctl disable labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service || true
The service can remain active even though the output is now disabled. Re-enable it for the final lab state:
sudo systemctl enable labex-heartbeat.service
Confirm both independent properties:
systemctl is-active labex-heartbeat.service
systemctl is-enabled labex-heartbeat.service
Query Service Logs with journalctl
In this step, you will read recent service output from the systemd journal and save a focused snapshot.
Services managed by systemd normally send standard output and standard error to the journal. Query only the practice unit:
sudo journalctl -u labex-heartbeat.service -n 10 --no-pager
The -u option selects a unit, -n 10 keeps the ten most recent records, and --no-pager prints them directly. You should see the service startup message and heartbeat records.
Limit results to a recent time window:
sudo journalctl -u labex-heartbeat.service --since "5 minutes ago" --no-pager
Filter by warning-or-higher priority. No output is a healthy and valid result when the service has not logged a warning:
sudo journalctl -u labex-heartbeat.service -p warning --since "5 minutes ago" --no-pager
Save a recent unit-specific snapshot in the project workspace:
cd /home/labex/project/service-lab
sudo journalctl -u labex-heartbeat.service -n 20 --no-pager > service-journal.txt
tail -n 5 service-journal.txt
Follow a Traditional Text Log
In this step, you will inspect /var/log and follow a text log as new records arrive.
The /var/log hierarchy stores many traditional system and application logs. List a small sample:
ls -lh /var/log | head -n 12
Read the latest practice-service records:
tail -n 5 /var/log/labex-heartbeat.log
The -f option follows a file and displays new lines as another process appends them:
tail -f /var/log/labex-heartbeat.log
Wait until you see at least two new heartbeat lines, then press Ctrl+C. This interrupts tail; it does not stop the service that is writing the log.
Filter heartbeat lines and view the most recent three:
grep '^heartbeat ' /var/log/labex-heartbeat.log | tail -n 3
Save a five-line sample in the project workspace:
cd /home/labex/project/service-lab
tail -n 5 /var/log/labex-heartbeat.log > traditional-log-sample.txt
cat traditional-log-sample.txt
Diagnose and Recover a Failed Service
In this step, you will create a controlled configuration failure, use service state and logs to identify it, and restore healthy operation.
Stop the practice service and back up its simple configuration:
sudo systemctl stop labex-heartbeat.service
sudo cp /etc/labex-heartbeat.conf /etc/labex-heartbeat.conf.bak
Replace the numeric interval with an invalid value. This intentionally breaks only the practice service:
sudo sed -i 's/^INTERVAL=2$/INTERVAL=invalid/' /etc/labex-heartbeat.conf
Attempt to start the service. A failure message is expected:
sudo systemctl start labex-heartbeat.service || true
Inspect the failed state:
systemctl status labex-heartbeat.service --no-pager || true
systemctl is-failed labex-heartbeat.service
The status tells you that the process exited, but the journal gives the application-specific reason:
sudo journalctl -u labex-heartbeat.service -n 10 --no-pager
Look for configuration error: INTERVAL must be a positive integer. Restore the known-good configuration, clear the recorded failed state, and start the service again:
sudo mv /etc/labex-heartbeat.conf.bak /etc/labex-heartbeat.conf
sudo systemctl reset-failed labex-heartbeat.service
sudo systemctl start labex-heartbeat.service
Confirm the recovery:
systemctl is-active labex-heartbeat.service
cat /etc/labex-heartbeat.conf
The service should be active, and the configuration should again contain INTERVAL=2.
Summary
You distinguished processes, services, active state, and boot-time enablement. You inspected a systemd unit, controlled a safe practice service with systemctl, and queried its records with journalctl.
You also inspected /var/log, followed live text output with tail -f, used status and logs together to explain a controlled failure, and restored the service. This state-first, logs-second workflow is a practical foundation for beginner service troubleshooting.



