2012年10月20日

munin の plugin 作成メモ

概要

Munin」の plugin 作成の手順とサンプルをメモしておく。

ドキュメント

公式ドキュメントは結構ちらばっていてやや読みずらいが、plugin を作成したいならちゃんと読んだ方が良い。

plugin サンプル

とりあえず、サンプルを見て作成するのが速い。

参考に nginx の稼動を記録する plugin を作成してみる。nginx の status を利用して監視をするので、 status は有効にしておく。
nginx の稼動確認 plugin は公式の munin plugin としてすでに存在しているが、存在している plugin を作成することで、自作の plugin が既存の plugin と同じ動作をすることが確認できるので、最初に作成する plugin はすでに存在している plugin を作成してみるのが良い。

  • /usr/share/munin/plugins/nginx_request
  • /usr/share/munin/plugins/nginx_status

munin 標準の nginx plugin は Perl で作成されており、「LWP::UserAgent」が必要な plugin になっている。動作させる場合は、「/etc/munin/plugins」に「ln -s」する。動作させて nginx を監視したグラフを生成しておく。

munin の plugin はプログラム言語を問わないので、とりあえず自分は Python で実装してみたのが以下。「nginx_request.py」の名前で作成した。
以下の plugin は正規表現を「https://github.com/samuel/python-munin/blob/master/munin/nginx.py」の物を利用して、実質30から40分程度で作成したので、あまり最適化してないし、エラー処理もいいかげん。またバグがあるかもしれないので、ちゃんと検証してから利用すること。一応 Python 2.6 と 2.7 で動作するはず。
自作の plugin も動作させる場合は、「/etc/munin/plugins」に「ln -s」すれば良い。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import sys
import urllib


def get_env():
    """
    get env
    """
    url = os.environ.get('url')
    if url is None:
        url = 'http://localhost/nginx_status'
    return url


def get_fields():
    """
    fields
    """
    return ('request',)


def get_server_status():
    """
    server status
    """
    # https://github.com/samuel/python-munin/blob/master/munin/nginx.py
    status_re = re.compile(
        r'Active connections:¥s+(?P<active>¥d+)¥s+'
        r'server accepts handled requests¥s+'
        r'(?P<accepted>¥d+)¥s+(?P<handled>¥d+)¥s+(?P<requests>¥d+)¥s+'
        r'Reading: (?P<reading>¥d+) Writing: (?P<writing>¥d+) Waiting: (?P<waiting>¥d+)')
    try:
        status = status_re.search(urllib.urlopen(get_env()).read()).groupdict()
    except Exception, e:
        status = None
    return status


def do_data():
    """
    data
    """
    request = get_server_status()['requests']
    fields = get_fields()
    for field in fields:
        print '{0}.value {1}'.format(field, request)


def do_autoconfig():
    """
    autoconfig
    """
    if get_server_status() is None:
        print 'no (no nginx status on {0})'.format(get_env())
    else:
        print 'yes'


def do_config():
    """
    config
    """
    print 'graph_title nginx Requests'
    print 'graph_args --base 1000 -l 0'
    print 'graph_vlabel Requests per second'
    print 'graph_category nginx'

    fields = get_fields()
    for field in fields:
        print '{0}.label requests'.format(field)
        print '{0}.min 0'.format(field)
        print '{0}.type DERIVE'.format(field)
        print '{0}.draw LINE2'.format(field)


if __name__ == '__main__':
    if len(sys.argv) > 1:
        if sys.argv[1] == 'config':
            do_config()
            sys.exit(0)
        if sys.argv[1] == 'autoconfig':
            do_autoconfig()
            sys.exit(0)
    else:
        do_data()

上記の plugin は 外部設定に対応している。「/etc/munin/plugin-conf.d」に「nginx」みたいな名前で以下のようなファイルを作成すると、監視 URL を変更できる。

[nginx_*]
env.url http://domain/nginx_status

plugin のデバッグ

基本的には「munin-run」を利用するとデバッグがしやすい。
上記の plugin をデバッグする場合は、以下のようにする。

sudo munin-run nginx_request autoconfig
sudo munin-run nginx_request config
sudo munin-run nginx_request

今後の課題

munin の plugin 作成の設定値を全部認識しているわけではないので、徐々に確認していく。

blog comments powered by Disqus