Systemd のCPU使用率を取りたい。


CPU Accountingの有効化

UnitファイルのCPUAccounting=yesとしていること。

systemctl status

抜粋すると、CPU時間が出るようになる。
起動時間もあるので、一応CPU時間 / (現在時刻-起動時間)とすれば使用率は出せる。
文字列の抽出が面倒。

Active: active (running) since Thu 2020-10-08 23:42:39 JST; 2 days ago
Main PID: 1530117 (java)
Tasks: 64 (limit: 38405)
Memory: 207.1M
CPU: 2min 53.531s

systemd-cgtopコマンド

マニュアル

コマンド例

systemd-cgtop system.slice/XYZ.service -n2

nは2回採取する。

実行結果

Control Group                                                                                                                                                               Tasks   %CPU   Memory  Input/s Output/s
system.slice/XYZ.service                                                                                                                                                64    0.1   207.1M        -        -

awkによる抜き出し

systemd-cgtop system.slice/XYZ.service -n2| awk 'NR==3{print $3}'

実行結果

0.1

単位:%

CPU Accountingのレポートを利用する

こちらのドキュメントによれば、レポートが自動生成されるらしい。
3.3. CPUACCT

参考ブログ様

構成

以下のようなディレクトリ配下にレポートが出力されている。
/sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/

root@machine:/tmp# ls -l /sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/
合計 0
-rw-r--r-- 1 root root 0 10月 11 19:32 cgroup.clone_children
-rw-r--r-- 1 root root 0 10月  8 23:42 cgroup.procs
-rw-r--r-- 1 root root 0 10月  8 23:42 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 10月  8 23:42 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 10月  8 23:42 cpu.shares
-r--r--r-- 1 root root 0 10月 11 19:32 cpu.stat
-rw-r--r-- 1 root root 0 10月 11 19:32 cpu.uclamp.max
-rw-r--r-- 1 root root 0 10月 11 19:32 cpu.uclamp.min
-r--r--r-- 1 root root 0 10月 11 11:33 cpuacct.stat
-rw-r--r-- 1 root root 0 10月  8 23:42 cpuacct.usage
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_all
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_percpu
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_percpu_sys
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_percpu_user
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_sys
-r--r--r-- 1 root root 0 10月 11 19:05 cpuacct.usage_user
-rw-r--r-- 1 root root 0 10月 11 19:32 notify_on_release
-rw-r--r-- 1 root root 0 10月 11 19:32 tasks

root@machine:/tmp# cat /sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/cpuacct.usage
240726534073

root@machine:/tmp# cat /sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/cpuacct.stat
user 13265
system 8527

root@machine:/tmp# cat /sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/cpuacct.usage_percpu
6265750403 6467202126 6742989606 6518540640 9549836717 9220640327 8962311388 9387660050 8239269084 7955274914 7827762679 7904506143 6900885175 6475328926 6465072623 6542519174 6743433197 6565617004 6407925582 7040172728 8635895303 8580596739 9087908230 8170453459 7839371754 7827615876 7643637771 7548591762 6520557930 7248185284 6860816966 6714771167

CPU時間は取れそうだが、肝心の稼働時間を簡易に取る方法がわからない。

UnitファイルのExecStartPreで起動時刻をメモる。

  1. UnitファイルのExecStartPre=date +%s%N > fileして起動時刻(ナノ秒)を出力。
  2. 前述したusageファイルのCPUタイム(ナノ秒)を得る。
  3. 2 / (現在時刻 - 1) = CPU使用率を求める。

zabbix-agent2の「systemd.unit.info」アイテムを使う。

systemd.unit.info[mysqld.service、ActiveEnterTimestamp]これで、起動時刻をナノタイムで取れる。これはどうやらDbus-APIなるもので取得している模様。

結論

いろいろ調査した結果(リンクは調査記事:D-BusでSystemdプロセスの開始時刻を取る)、以下のコマンドを得た。
手順はリンクを参照いただきたい。

bc -l <<<  "`cat /sys/fs/cgroup/cpu,cpuacct/system.slice/XYZ.service/cpuacct.usage` \
/ (`date +%s%N` -  `dbus-send --print-reply --system --dest=org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/XYZ_2eservice --type=method_call \
org.freedesktop.DBus.Properties.Get \
string:org.freedesktop.systemd1.Service string:ExecMainStartTimestamp \
 | awk 'NR==2{print $3}' `* 1000)"

こんな感じ