なんなの
統計間隔を指定できるコマンド、top, vmstat, iostat, lnstat には1回目の結果値が、指定した統計間隔での統計値にならないという罠があるので気を付けたい。
ダメな例
例えば、
top -b -d10 -n1
は、-d[N]
オプションが統計秒数、-n[M]
オプションが測定回数なのだが、1回目は -d[N]
で指定した秒数を待たずにすぐさま表示がなされ、全然設定した N 秒平均の値になっていない。
また、非常に短い統計秒数での値が表示されるため、表示値のぶれも大きい。
top -b -d10 > log
のようなコードでログを取るなら、1つ目の結果だけを無視すればいいのだが、
#!/bin/bash
echo "" > log
while true
do
top -b -d10 -n1 >> log
sleep 0.1
done
などで1回1回独自で値を取ろうとすると毎回どれも全然指定した 10 秒間の統計にならない。(やってみるとめちゃめちゃ高速に何回も実行されます)
どうすればいいのか
-n1
を使わず -n2
で2つの結果を出すようにして、
1回目の結果を tail
などで捨てて、2回目の結果だけを拾えばよい。
#!/bin/bash
echo "" > log
while true
do
top -b -d10 -n2 | tail -14 >> log
sleep 0.1
done
辛い
※ top -b -d10 > log でいい、というのは、それでいいときはそれはそう。top, vmstat, pidstat を統合して同期した結果を得たいときの話
※ /proc/stat をパースして全部自分でやれ、それはそう
同じ感じのコマンドはいないか
統計間隔指定オプションのある似たコマンドを全部調べました
パッケージ | 調べたバージョン | コマンド | 1つ目の結果 | こうすればいいよ |
---|---|---|---|---|
procps | procps-ng 3.3.16 | top -b -d[N] -n1 | × 謎の時間の平均 | top -b -d[N] -n2 | tail -14 |
procps | procps-ng 3.3.16 | vmstat [N] 1 | × 起動時からの長時間平均 | vmstat [N] 2 | tail -1 |
sysstat | sysstat 12.2.0 | iostat [N] 1 | × 非常に大きい謎の値 | iostat [N] 2 | tail -9 |
sysstat | sysstat 12.2.0 | mpstat [N] 1 | 〇 N 秒の平均 | |
sysstat | sysstat 12.2.0 | pidstat [N] 1 | 〇 N 秒の平均 | |
iproute2 | lnstat 0.02 | lnstat -i[N] -c1 | × 非常に大きい謎の値 | lnstat -i[N] -c2 | tail -1 |
mpstat, pidstat は素直でした
教訓
10秒指定とかしたときに10秒かからずに1つ目の値が返ってくるコマンド、1つ目の値だけ飛んだ値がくるコマンドは要注意です。
その他
top は指定した統計秒数にプロセスが生きていても、統計終了時点でそのプロセスが生きていないとプロセスのランキングに出てこず、なかったことになるので注意。
たとえば、top -d100 で 100 秒の統計を取っているとき、n 回目の表示が終わったときを時刻 0 秒目として、時刻1秒目にプロセス mycmd が負荷100%で動き出し、98秒間動いて時刻99秒目でプロセスが終了し、100秒目で n+1 回目の top 表示がなされたときには mycmd は負荷 98% と表示してほしいものだが、100秒目には mycmd はもういなかったのでランキングに出てきません。
ただ、user time と idle time の計算には入っているみたいです。(user time は 98% と表示される。)