ほわいとぼーど

ぷろぐらまのメモ帳

dstatをちょっとだけ改造する話

以前、『dstatをkibanaで可視化』の話を書いたのですが、 この時の環境で色々不足があって手を加えたり、あるいはその時に気になった部分を後で改良したり、という事があって、 前回の記事『fluentd-plugin-dstat_stdinぽいのを書いた話』も この時の1つです。

今回もその1つで、dstatでの出力内容に不足があったので追加してみた話です。
具体的にはdstat(0.7.2)のCPU関連の出力にstealを追加します。

dstatはpythonで書かれています。
apt-getで入れた場合、本体は /usr/bin/dstat にあります。
また、pluginの場合は/usr/share/dstat配下に個別ファイルで置かれる形です。

/usr/bin/dstat を見てみると、オプション項目毎にclassが切ってあって、 CPU関係の場合、class dstat_cpuになります。

class dstat_cpu(dstat):
    def __init__(self):
        self.nick = ( 'usr', 'sys', 'idl', 'wai', 'hiq', 'siq' )
        self.type = 'p'
        self.width = 3
        self.scale = 34
        self.open('/proc/stat')
        self.cols = 6
...略

class定義の部分から、/proc/statから情報を取得していて、 usr, sys, idl, wai, hiq, siq の6項目であることが想像できます。

/proc/statを見てみます。

cpu  370 0 441 313249 132 0 31 0 0 0
cpu0 370 0 441 313249 132 0 31 0 0 0
...略

この行の各数値を取得して加工して表示しています。
「cpu」がTotalで[cpu0」がcpu1個目、マルチコアなら更に行が増えます。

procのman page で/proc/statを見てみると、

①user
②nice
③system
④idle
⑤lowait
⑥irq
⑦softirq
⑧steal
⑨guest
⑩guest_nice

で、/usr/bin/dstatの実際に取得している部分を見ると

self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), long(l[4]), long(l[5]), long(l[6]), long(l[7]) )

7番目まで使われているので、似たような形で8番目も取得するようにすればstealを表示できそうなことがわかります。

最終的に修正した差分は以下

vagrant@server:/usr/bin$ diff dstat updated__dstat
564c564
<         self.nick = ( 'usr', 'sys', 'idl', 'wai', 'hiq', 'siq' )
---
>         self.nick = ( 'usr', 'sys', 'idl', 'wai', 'hiq', 'siq', 'stl' )
569c569
<         self.cols = 6
---
>         self.cols = 7
574c574
<             if len(l) < 8 or l[0][0:3] != 'cpu': continue
---
>             if len(l) < 9 or l[0][0:3] != 'cpu': continue
609c609
<             if len(l) < 8: continue
---
>             if len(l) < 9: continue
612c612
<                     self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), long(l[4]), long(l[5]), long(l[6]), long(l[7]) )
---
>                     self.set2[name] = ( long(l[1]) + long(l[2]), long(l[3]), long(l[4]), long(l[5]), long(l[6]), long(l[7]), long(l[8]) )
614c614
<             for i in range(6):
---
>             for i in range(7):

こんな感じで比較的簡単に修正することが可能です。
dstatがやっていることは大体が/proc配下のファイルを定期的に見て数値とってるだけなので、 慣れると色々好きな数値をとったりできそうです。 例えば自分は/proc/net/snmpUDPパケットの各値を取得するpluginを書いたりしました。

プルリクすればいいじゃないかと言われそうですが、githubのdstatレポジトリでは結構ソースが変更されていて、 stealの表示も既に入っています。逆にhiq, siqは別optionに追い出されていたり。 しかし0.7.2が出てから2年もたっていていつ更新されるかは不明な状況だったり。 悩ましいです。

あとはfluentd-plugin-mapのconfigurationの話が出来るようになると一通り・・・