maehachi08 Anything Blog

2014年03月04日
Munin プロセスごとのスワップサイズを監視するMuninプラグインを作ってみた

今回は、Muninプラグインの書き方について書いていきます。また、自分も1から勉強しているところなので、1つMuninプラグインを書き上げようと思います。

Muninプラグインは誰でも作れる

Muninプラグインはすでにあるものを利用することが多いですが、必要なら誰にでも作れるものです。

Muninプラグインはmunin-nodeに対して特定のフォーマットで(RRDの構成に基づく)グラフ情報とリソース値を返すことが出来ればいいので、perl、ruby、shellのようなスクリプト言語で簡単に作成できます。もちろん、C言語などで書いてコンパイルしたバイナリでも同様の出力が得られるように書けば問題ありません。

Munin公式ページの How to write Munin plugins ではLoad Averageの値を監視するためのプラグインをshellで書く行程を説明しており、実際シンプルなshellスクリプトです。まさにMuninプラグインのHello World!なので一度目を通すだけでも価値はあると思います。

プロセスごとのSwapサイズをグラフ化するMuninプラグインを作ろう

上記の記事で書いたPerlスクリプトを参考にMuninプラグインを書いてみたいと思います。

Muninプラグインの構成

自分はMuninプラグインは大きく2つのプログラムから成ると考えています。

1. リソース値を取得するプログラム

  • 監視対象となる値を取得するプログラム
  • /proc/[PID]/status の VmSwap の値を取得し単位をKBからBytesへ整形します

今回作成するMuninプラグインは、 /usr/share/munin/plugins/proc_swapsize_ として配置し、 /etc/munin/plugins/proc_swapsize_httpd のように末尾に監視したいプロセス名を付加したファイル名で /etc/munin/plugins ディレクトリにシンボリックリンクを作成することで動作します。

したがって、ファイル名末尾のプロセス名を抽出して対象プロセスのスワップサイズを取得します。コードとしては以下のようなものです。

#--------------------------------------------------------------------------
# Data processing section
#--------------------------------------------------------------------------
my $process_name_small     = basename( $0 )=~ s/.*_//r;
my $process_name_camelcase = ucfirst $process_name_small;
my @pids                   = `/usr/bin/pgrep $process_name_small | /bin/sort -n`;

my @process_swaps;
foreach my $pid ( @pids ) {

    chomp $pid;

    if ( ! -f "/proc/$pid/status" ) {
        # file not found! next.
        next;
    }

    my $swap_size_kb = `/bin/grep VmSwap /proc/$pid/status | /bin/awk '{print \$2}'`;
    chomp $swap_size_kb;
    my $swap_size = $swap_size_kb * 1024;
    push( @process_swaps, $swap_size );
}

my $process_count = @process_swaps;

2. munin-nodeに情報を渡すプログラム

  • 取得した監視対象の値をmuninマスタがrrdgraphに引き渡す画像生成オプション群(graph_から始まるオプション)などをmunin-nodeに渡すプログラム
  • 渡すといっても具体的にはprintfなどで標準出力するだけ

コードとしては以下のようなものです。

#--------------------------------------------------------------------------
# Print attributes section
#--------------------------------------------------------------------------
if ( $mode eq 'config' ) {

    # Global attributes
    printf "graph_category swap\n";
    printf "graph_title    $process_name_camelcase processes swap size\n";
    printf "graph_args     --base 1024 --lower-limit 0\n";
    printf "graph_vlabel   Bytes\n";
    printf "graph_vtitle   Swap size\n";
    printf "graph_scale    yes\n";
    printf "graph_info     This graph shows the swap size of $process_name_small processes.\n";
    printf "graph_total    total\n";

}


# Datasource-specific plugin attributes
for ( my $i=1; $i<=$process_count; $i++ ) {
    my $value_name = "$process_name_small" . "_" . "$i";
    my $swap_size_per_proc = shift( @process_swaps );

    if ( $mode eq 'config' ) {
        if ( $i == 1 ) {
            print "$value_name" . "." . "draw " . "AREA" . "\n";
        } else {
            print "$value_name" . "." . "draw " . "STACK" . "\n";
        }

        print "$value_name" . "." . "type "  . "GAUGE"  . "\n";
        print "$value_name" . "." . "label " . "$value_name"  . "\n";
    }

    print "$value_name" . "." . "value " . "$swap_size_per_proc" . "\n";
}

printするオプションにはどのようなものがあるかを次項でリストにしました。

Muninプラグインからmunin-nodeに渡す情報

1) Global attributes

Global attributesはプラグイン全体に影響する設定群です。

attributes name description code example
graph_title グラフタイトルを指定する。デフォルトはプラグインの名前が使われる。引数については、http://munin-monitoring.org/wiki/graph_title を参照。 graph_title $process_name_camelcase processes swap size
create_args muninマスタによって発行される"rrdtool create"コマンドの引数を指定できる。RRDファイル(/var/lib/munin/ [ hostname ] /*.rrd)のファイル名を指定する場合はここで指定できる。引数については、http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html を参照。 create_args step=300
graph_args muninマスタによって発行される"rrdtool graph"コマンドの引数を指定できる。。引数については、http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html を参照。 graph_args --base 1024 --lower-limit 0
graph_category systemやnetworkのようなグラフが属するカテゴリーを指定できる。カテゴリー名の命名ルール等については、http://munin-monitoring.org/wiki/graph_category を参照。 graph_category swap
graph_info グラフについての概要などを記述する。各グラフ上でクリックし遷移したページの下部に表示される。Data source attributes単位の概要については{fieldname}.infoで記述できる。 graph_info This graph shows the swap size of $process_name_small processes.
graph_order グラフ生成時のData sourceの描画順序を指定できる。typeがSTACKの場合などに便利なattributesです。引数については、http://munin-monitoring.org/wiki/graph_order を参照。 graph_order system user nice idle
graph_vlabel グラフのX軸に対するラベルを定義できる。 graph_vlabel Bytes
graph_total 全てのData sourcesの値を足した合計値を取得できる。プラグインの中でわざわざ算術演算子を使って合計値を算出する必要がなく、便利。 graph_total total
graph_scale Data sourcesの値の単位を人間の分かり易い単位に変換してグラフ描画できる。BytesをKB変換などが代表的なもの。デフォルトは有効(yes) graph_scale yes
graph グラフ描画をおこなうかどうかを指定できる。デフォルトはグラフ描画する(yes) graph yes
host_name Munin プラグインをリモート実行したい場合などにホスト名を明示することができる。詳細は、http://munin-monitoring.org/wiki/host_name を参照。 host_name $host_name
update グラフ描画のためにData sourcesから値を取得すべきかどうかを指定できる。ほとんどの場合、munin.confで指定する。詳細は、http://munin-monitoring.org/wiki/update を参照。 update yes
graph_period RRDのデータソースタイプがDERIVE、もしくはCOUNTERの場合に平均変化率を算出するためのタイムユニット値を指定できる。詳細は、http://munin-monitoring.org/wiki/graph_period を参照。 graph_period second
graph_vtitle グラフのX軸に対するラベルを定義できる。graph_vlabelと重複したattributes。 graph_vtitle Swap size
service_order FIXME...
graph_width グラフ幅の指定(PNGの横幅ではない)。グラフの時間軸の幅を広くすることができる。詳細は、http://munin-monitoring.org/wiki/graph_width を参照。 graph_width 400
graph_height グラフ高さの指定(PNGの高さではない)。グラフの値軸の高さを広くすることができる。詳細は、http://munin-monitoring.org/wiki/graph_height を参照。 graph_height 200
graph_printf format ... graph_printf %3.0lf

2) Datasource-specific plugin attributes

個別のデータソースに対して影響する設定群です。attributesの設定は、各attributes名をデータソース名( fieldname )とドットで連結して指定します。

attributes name description code example
{fieldname}.label データソース名の指定。詳細は、http://munin-monitoring.org/wiki/fieldname.label を参照。 system.label system
{fieldname}.cdef 逆ポーランド記法の数式。COMPUTEの時のみ利用可能。詳細は、http://munin-monitoring.org/wiki/fieldname.cdef を参照。 system.cdef system,$NCPU
{fieldname}.draw データソースから取得した値の描画方法を指定する。指定できる描画方法は、AREA, LINE1, LINE2, LINE3, STACKであり、Munin2系のデフォルトはLINE2である。詳細は、http://munin-monitoring.org/wiki/fieldname.draw を参照。 running.draw STACK
{fieldname}.graph データソースをグラフにするかどうかを指定する。デフォルトはyes。 swap_in.graph no
{fieldname}.info データソースの値に対する説明を記述できる。 runnable.info The number of runnable processes (on the run queue).
{fieldname}.extinfo 閾値監視している場合のアラートメッセージに含む文字を指定できる。Munin1.4以降ではHTMLページにも表示される。 posts.extinfo Can't find any log files
{fieldname}.type データソースのタイプを指定する。指定できるタイプは、COUNTER, ABSOLUTE, DERIVE, GAUGEであり、デフォルトはGAUGEです。詳細は、http://munin-monitoring.org/wiki/fieldname.type を参照。
{fieldname}.warning 閾値監視のWarning値を定義できる。詳細は、http://munin-monitoring.org/wiki/fieldname.warning と http://munin-monitoring.org/wiki/HowToContact を参照。 avgrdwait.warning 0:3
{fieldname}.critical 閾値監視のCritical値を定義できる。詳細は、http://munin-monitoring.org/wiki/fieldname.critical と http://munin-monitoring.org/wiki/HowToContact を参照。 load.critical 120
{fieldname}.colour データソースの値を描画する色を指定できる。 ip_conntrack_count.colour 4444ff
{fieldname}.sum グラフのサマリーを作成できる。 {fieldname}.sum
{fieldname}.stack 詳細は、http://munin-monitoring.org/wiki/MuninConfigurationMasterExampleStack を参照。 total_entropy.total_received.stack
{fieldname}.line 詳細は、http://munin-monitoring.org/wiki/fieldname.line を参照。 pending.line 5:00ff00:Limit
{fieldname}.oldname データソース名を変更した場合に前のデータソース名を明示します。このattributesが存在したら一度だけoldnameの名前をhistoryに登録します。 hoge.oldname hoge-old
{fieldname}.value データソースのデータ値。Integerか0,1,2,3,…9までのdecimal numberの必要があります。 cpu.value 30

以上がMuninプラグインにおけるmunin-nodeに渡すことができるオプションです。

プラグインのドキュメントフォーマット(perl)

Muninプラグインを書く中で、使い方や環境変数オプション等についてドキュメントを作成しておいた方が便利でしょうし、公開することを想定するならドキュメントは作成するべきです。

今回は、http://munin-monitoring.org/browser/munin-contrib/plugins/system/dar_memusage を参考にしました。

perlドキュメントの書き方については、 http://perldoc.jp/docs/perl/5.6.1/perlpod.pod などを参考にします。

以下で、どのような項目をドキュメントとして作成すべきなのか、纏めてみました。

item description
NAME プラグインの名前と概要
APPLICABLE SYSTEMS OSやプラグインが動作する言語バージョンなどの対象システムを記述する
CONFIGURATION プラグインの置き方(命名ルール)や環境変数の設定方法などを記述する
INTERPRETATION プラグイン動作や仕組みに関して記述する
MAGIC MARKERS Munin付属のプラグイン補助ツールであるmunin-node-configureに通知するために必要な項目。詳細は、http://munin-monitoring.org/wiki/PluginConcise#Magicmarkers を参照。
VERSION プラグインバージョン
AUTHOR プラグイン開発者
LICENSE プラグイン配布ライセンス

MAGIC MARKERSの補足

MAGIC MARKERS の設定をしておくことで、munin-node-configure コマンドでプラグインを管理することが出来ます。munin-node-configureコマンドは、Muninプラグイン設定補助ツールです。

単体で使用できる(非ワイルドカードプラグイン)では以下のように設定します。

 #%# family=auto
 #%# capabilities=autoconf

今回のようにワイルドカードプラグインの場合は以下のように設定します。こうすることで、munin-node-configureは、suggest引数付きでワイルドカードプラグインを実行します。

#%# family=auto
#%# capabilities=autoconf suggest

ということでプラグイン作成しました

https://github.com/maehachi08/munin-plugins-proc_swapsize_

proc_swapsize_ という名前の、ワイルドカードプラグインを作成しました。

ワイルドカードプラグインとはファイル名末尾がアンダースコア( _ )で終わっていてるプラグインのことで、アンダースコアの後にキーワードを付加することでそのキーワードに対応した動作をする必要があります。ワイルドカードプラグインについては、 http://munin-monitoring.org/wiki/PluginWildcard を参照してください。

注意点としては、Perl バージョン 5.14.0以降が必須である ことでしょうか。

これは、正規表現置換において、非破壊置換オプション( /r option )を利用しているためです。

該当部分を書き直せば、Perl バージョン 5.14.0より古いバージョンでも使用できるかと思います。(検証はしていませんが)