Monitoring server performance traditionally requires running heavyweight monitoring agents or running constant background metrics scrapers. However, when troubleshooting an individual daemon or tracking network bandwidth consumption per microservice, aggregate tools lack service-level granularity. In Ubuntu, systemd Resource Accounting and IP Accounting leverage kernel cgroups and BPF filters to track exact CPU cycles, memory high-water marks, disk I/O bytes, and network packet throughput per unit service natively with near-zero overhead.
Understanding systemd Accounting Metrics and Controllers
systemd integrates directly with Linux cgroups v2 resource controllers to measure runtime telemetry:
- CPUAccounting: Measures total CPU execution time consumed by processes in the unit slice.
- MemoryAccounting: Tracks current resident memory, swap consumption, and peak memory usage.
- IOAccounting: Records physical disk read/write throughput and operation counts.
- IPAccounting: Employs eBPF socket filters attached directly to the service cgroup to log exact ingress and egress network bytes and packet volumes per service.
Enabling Global Resource Accounting in system.conf
By default, certain accounting metrics are disabled or enabled selectively to conserve CPU cycles on older hardware. In modern Ubuntu releases, you can activate system-wide accounting:
- Open the systemd manager configuration file in a terminal text editor:
sudo nano /etc/systemd/system.conf - Locate and uncomment the following accounting directives:
[Manager] DefaultCPUAccounting=yes DefaultMemoryAccounting=yes DefaultTasksAccounting=yes DefaultIOAccounting=yes DefaultIPAccounting=yes - Save the file and reload systemd to apply global configuration:
sudo systemctl daemon-reexec
Enabling Per-Service IP and IO Accounting
If you prefer to enable accounting only on targeted production services (such as Nginx, PostgreSQL, or a custom microservice):
Create a systemd unit drop-in configuration using systemctl edit:
sudo systemctl edit nginx.service
Add the accounting directives under the [Service] section:
[Service]
CPUAccounting=yes
MemoryAccounting=yes
IOAccounting=yes
IPAccounting=yes
Restart the service to initialize the cgroup eBPF filters:
sudo systemctl restart nginx.service
Inspecting Live Resource Telemetry with systemctl status
Once accounting is active, running systemctl status immediately displays rich real-time telemetry:
systemctl status nginx.service
Review the detailed metrics block appended to the standard output:
- Memory: Displays current resident set size (e.g.,
45.2M (peak: 78.1M)). - CPU: Displays total cumulative processing time (e.g.,
1min 23.412s). - I/O: Reports exact storage traffic (e.g.,
14.2M read, 2.1M written). - IP: Reports total network ingress and egress (e.g.,
128.4M in, 894.2M out).
Querying Granular Metrics Using systemd-cgtop
To monitor resource consumption dynamically across all systemd services in a top-like terminal dashboard:
systemd-cgtop -m -n 10
The display ranks control groups by active memory, CPU load, and network I/O, allowing administrators to pinpoint runaway processes and network bandwidth consumers instantly.