Python でmunin plugin を
書いてみる
          2013-04-13 Shizuoka.py
自己紹介
● となか(@ftnk)
● インフラエンジニア
 ○ Solaris / Puppet / Nagios / munin / GrowthForecast /
   serverspec etc.
 ○ Python はまれに運用・監視用のスクリプトを書く
   ■ shell script だと面倒で Ruby がない環境の時
   ■ まれにしか書かないので、覚えない
● 開発?
 ○ 最近、serverspec に Solairs 用の matcher 追加
   の pull request を送ったりしてます
agenda
1. 今回の目的
2. munin ?
3. munin plugin ?
4. munin plugin の構成
5. python-munin
6. cpu 使用率の plugin を書く
   (ただし、Solaris)
7. まとめ
今回の目的
● Python がよくわかっていなくても、簡単に
  munin plugin が書けることを知ってもらう
munin ?
● munin はリソース監視ツール
 ○ リソースの値を取得してグラフ化
● 類似のツール
 ○ mrtg / cacti / CloudForecast / GrowthForecast etc.
munin plugin?
● リソースの値の取得とグラフに関する情報を扱
  う
● リソースの値の取得
 ○ なんらかのコマンドを実行するなどして値を取得
● グラフに関する情報
 ○ グラフの形式 (draw)
   ■ LINE / AREA / STACK
 ○ 値のあつかい (type)
   ■ GAUGE / DERIVE / COUNTER
munin plugin の構成
● 必要な機能
 ○ グラフに関する情報の出力
   ■ plugin にオプションとして "config" を渡すと出力され
     る
 ○ リソースの値の取得と出力
   ■ plugin にオプションを渡さなければ、リソースの値が
     出力される
グラフに関する情報の出力
● グラフ全体に関する情報
 ○   graph_title: グラフのタイトル
 ○   graph_category: グラフのカテゴリー
 ○   graph_vlabel: 縦軸のタイトル
 ○   graph_scale: 値に合わせてグラフをスケールさせる
     か?
グラフに関する情報の出力
● リソースごとのグラフに関する情報
 ○ system.label: system というグラフのラベル
 ○ system.draw: system というグラフの形式
 ○ system.type: system というグラフの値のあつかい
リソースの値の取得と出力
● 値の取得
 ○ 好きなようにとってください
● 出力
 ○ 出力は以下のフォーマットでおこなう
   ■ system.value (値)
python-munin
● 今回は python-munin というライブラリを使って
  plugin を書いてみます。
● http://samuelks.com/python-munin/
● インストール
  ○ git や tarball でソースを入手
  ○ python setup.py build
  ○ sudo python setup.py install
python-munin
python-munin を使うと、以下のような感じで plugin が書けます。

from munin import MuninPlugin


class CPUPlugin(MuninPlugin):
  # グラフ全体の情報
  title = "cpu usage (test)"


  @property
  def fields(self):
    # 各グラフの情報の出力
    return fuga


  def execute(self):
    # 値の取得と出力
    return hoge


if __name__ == "__main__":
  CPUPlugin().run()
CPU 使用率の plugin を書く
● 今回は munin 本体に含まれ、shell script で書
  かれている CPU 使用率の plugin を python-
  munin を使って書いてみます。
大枠の用意
import command
from munin import MuninPlugin
                                ●   プラグイン内部でコマンドを実行するので、"import
class CPUPlugin(MuninPlugin):       command" が必要
  # グラフ全体の情報
  title = "cpu usage (test)"


  @property
  def fields(self):
    # 各グラフの情報の出力
    return fuga


  def execute(self):
    # 値の取得と出力
    return hoge


if __name__ == "__main__":
  CPUPlugin().run()
グラフ全体の情報
class CPUPlugin(MuninPlugin)
   title = "cpu usage (test)"
   args = "--base 1000 -l 0"
   vlabel = "cpu usage"
   scale = False
   category = system
個々のグラフの情報
def fields(self):
  retun [                       ●   個々のグラフの情報をリストでまとめて返しま
      ("kernel", dict(              す
            label = "system",
            draw = "AREA",
                                ●   各グラフの情報は辞書にまとめます
            min = "0",
        type = "DERIVE",
                                ●   グラフの描画に前回取得した値との差を使う
                                    ので、type が "DERIVE" です
      )),
      ("user", dict(
            label = "system",
                                ●   グラフは塗り潰しで積み重ねるので、 1 つ目
                                    のグラフの draw を "AREA"、2 つ目以降の
            draw = "STACK",         グラフの draw を "STACK" にします
            min = "0",
        type = "DERIVE",
      )),
      (省略)
  ]
config をつけて実行
% python cpu-test.py config
graph_title cpu usage (test)   ●   config をつけて実行すると、左のよ
graph_category system
graph_args --base 1000 -l 0
                                   うにグラフの情報が出力されること
graph_vlabel cpu usage             を確認できます
graph_scale no
kernel.draw AREA
kernel.min 0
kernel.type DERIVE
kernel.label system
user.draw STACK
user.min 0
user.type DERIVE
user.label user
wait.draw STACK
wait.min 0
wait.type DERIVE
wait.label wait
idle.draw STACK
idle.min 0
idle.type DERIVE
idle.label idle
値の取得と出力
● 以下のコマンドの出力を集計します
% kstat -p -c misc -m cpu_stat -s '/^(user|kernel|wait|idle)$/'
cpu_stat:0:cpu_stat0:idle 701652
cpu_stat:0:cpu_stat0:kernel         135979
cpu_stat:0:cpu_stat0:user           34858
cpu_stat:0:cpu_stat0:wait           0
cpu_stat:1:cpu_stat1:idle 609950
cpu_stat:1:cpu_stat1:kernel         221631
cpu_stat:1:cpu_stat1:user           40414
cpu_stat:1:cpu_stat1:wait           0
cpu_stat:2:cpu_stat2:idle 702211
cpu_stat:2:cpu_stat2:kernel         132556
cpu_stat:2:cpu_stat2:user           37226
cpu_stat:2:cpu_stat2:wait           0
cpu_stat:3:cpu_stat3:idle 633591
cpu_stat:3:cpu_stat3:kernel         198948
cpu_stat:3:cpu_stat3:user           39449
cpu_stat:3:cpu_stat3:wait           0
値の取得
def execute(self):
  stats = commands.getoutput(
                                                          ● commands.getoutput で
"kstat -p -c misc -m cpu_stat -s '/^                        コマンドの実行結果を取
(user|kernel|wait|idle)$?/'" )
                                                            得
  values = { 'idle':0, 'kernel':0, 'wait':0, 'idle':0 }   ● 値は辞書で返す
  for i in stats.splitlines():
                                                          ● 集計のため 0 で初期化
     key, value = i.split(':')[-1].split('t')            ● コマンドの実行結果を行ご
     values[key] += int(value)
                                                            とに処理して集計
  return values
実行
% python cpu-test.py
kernel.value 546745
idle.value 2077219
user.value 124432
wait.value 0
グラフ
以下のようなグラフができる
まとめ
● Python をよくわかっていなくても python-munin
  を使うことで、munin-plugin が書ける

Python で munin plugin を書いてみる

  • 1.
    Python でmunin pluginを 書いてみる 2013-04-13 Shizuoka.py
  • 2.
    自己紹介 ● となか(@ftnk) ● インフラエンジニア ○ Solaris / Puppet / Nagios / munin / GrowthForecast / serverspec etc. ○ Python はまれに運用・監視用のスクリプトを書く ■ shell script だと面倒で Ruby がない環境の時 ■ まれにしか書かないので、覚えない ● 開発? ○ 最近、serverspec に Solairs 用の matcher 追加 の pull request を送ったりしてます
  • 3.
    agenda 1. 今回の目的 2. munin? 3. munin plugin ? 4. munin plugin の構成 5. python-munin 6. cpu 使用率の plugin を書く (ただし、Solaris) 7. まとめ
  • 4.
    今回の目的 ● Python がよくわかっていなくても、簡単に munin plugin が書けることを知ってもらう
  • 5.
    munin ? ● muninはリソース監視ツール ○ リソースの値を取得してグラフ化 ● 類似のツール ○ mrtg / cacti / CloudForecast / GrowthForecast etc.
  • 6.
    munin plugin? ● リソースの値の取得とグラフに関する情報を扱 う ● リソースの値の取得 ○ なんらかのコマンドを実行するなどして値を取得 ● グラフに関する情報 ○ グラフの形式 (draw) ■ LINE / AREA / STACK ○ 値のあつかい (type) ■ GAUGE / DERIVE / COUNTER
  • 7.
    munin plugin の構成 ●必要な機能 ○ グラフに関する情報の出力 ■ plugin にオプションとして "config" を渡すと出力され る ○ リソースの値の取得と出力 ■ plugin にオプションを渡さなければ、リソースの値が 出力される
  • 8.
    グラフに関する情報の出力 ● グラフ全体に関する情報 ○ graph_title: グラフのタイトル ○ graph_category: グラフのカテゴリー ○ graph_vlabel: 縦軸のタイトル ○ graph_scale: 値に合わせてグラフをスケールさせる か?
  • 9.
    グラフに関する情報の出力 ● リソースごとのグラフに関する情報 ○system.label: system というグラフのラベル ○ system.draw: system というグラフの形式 ○ system.type: system というグラフの値のあつかい
  • 10.
    リソースの値の取得と出力 ● 値の取得 ○好きなようにとってください ● 出力 ○ 出力は以下のフォーマットでおこなう ■ system.value (値)
  • 11.
    python-munin ● 今回は python-muninというライブラリを使って plugin を書いてみます。 ● http://samuelks.com/python-munin/ ● インストール ○ git や tarball でソースを入手 ○ python setup.py build ○ sudo python setup.py install
  • 12.
    python-munin python-munin を使うと、以下のような感じで pluginが書けます。 from munin import MuninPlugin class CPUPlugin(MuninPlugin): # グラフ全体の情報 title = "cpu usage (test)" @property def fields(self): # 各グラフの情報の出力 return fuga def execute(self): # 値の取得と出力 return hoge if __name__ == "__main__": CPUPlugin().run()
  • 13.
    CPU 使用率の pluginを書く ● 今回は munin 本体に含まれ、shell script で書 かれている CPU 使用率の plugin を python- munin を使って書いてみます。
  • 14.
    大枠の用意 import command from muninimport MuninPlugin ● プラグイン内部でコマンドを実行するので、"import class CPUPlugin(MuninPlugin): command" が必要 # グラフ全体の情報 title = "cpu usage (test)" @property def fields(self): # 各グラフの情報の出力 return fuga def execute(self): # 値の取得と出力 return hoge if __name__ == "__main__": CPUPlugin().run()
  • 15.
    グラフ全体の情報 class CPUPlugin(MuninPlugin) title = "cpu usage (test)" args = "--base 1000 -l 0" vlabel = "cpu usage" scale = False category = system
  • 16.
    個々のグラフの情報 def fields(self): retun [ ● 個々のグラフの情報をリストでまとめて返しま ("kernel", dict( す label = "system", draw = "AREA", ● 各グラフの情報は辞書にまとめます min = "0", type = "DERIVE", ● グラフの描画に前回取得した値との差を使う ので、type が "DERIVE" です )), ("user", dict( label = "system", ● グラフは塗り潰しで積み重ねるので、 1 つ目 のグラフの draw を "AREA"、2 つ目以降の draw = "STACK", グラフの draw を "STACK" にします min = "0", type = "DERIVE", )), (省略) ]
  • 17.
    config をつけて実行 % pythoncpu-test.py config graph_title cpu usage (test) ● config をつけて実行すると、左のよ graph_category system graph_args --base 1000 -l 0 うにグラフの情報が出力されること graph_vlabel cpu usage を確認できます graph_scale no kernel.draw AREA kernel.min 0 kernel.type DERIVE kernel.label system user.draw STACK user.min 0 user.type DERIVE user.label user wait.draw STACK wait.min 0 wait.type DERIVE wait.label wait idle.draw STACK idle.min 0 idle.type DERIVE idle.label idle
  • 18.
    値の取得と出力 ● 以下のコマンドの出力を集計します % kstat-p -c misc -m cpu_stat -s '/^(user|kernel|wait|idle)$/' cpu_stat:0:cpu_stat0:idle 701652 cpu_stat:0:cpu_stat0:kernel 135979 cpu_stat:0:cpu_stat0:user 34858 cpu_stat:0:cpu_stat0:wait 0 cpu_stat:1:cpu_stat1:idle 609950 cpu_stat:1:cpu_stat1:kernel 221631 cpu_stat:1:cpu_stat1:user 40414 cpu_stat:1:cpu_stat1:wait 0 cpu_stat:2:cpu_stat2:idle 702211 cpu_stat:2:cpu_stat2:kernel 132556 cpu_stat:2:cpu_stat2:user 37226 cpu_stat:2:cpu_stat2:wait 0 cpu_stat:3:cpu_stat3:idle 633591 cpu_stat:3:cpu_stat3:kernel 198948 cpu_stat:3:cpu_stat3:user 39449 cpu_stat:3:cpu_stat3:wait 0
  • 19.
    値の取得 def execute(self): stats = commands.getoutput( ● commands.getoutput で "kstat -p -c misc -m cpu_stat -s '/^ コマンドの実行結果を取 (user|kernel|wait|idle)$?/'" ) 得 values = { 'idle':0, 'kernel':0, 'wait':0, 'idle':0 } ● 値は辞書で返す for i in stats.splitlines(): ● 集計のため 0 で初期化 key, value = i.split(':')[-1].split('t') ● コマンドの実行結果を行ご values[key] += int(value) とに処理して集計 return values
  • 20.
    実行 % python cpu-test.py kernel.value546745 idle.value 2077219 user.value 124432 wait.value 0
  • 21.
  • 22.
    まとめ ● Python をよくわかっていなくてもpython-munin を使うことで、munin-plugin が書ける