at_yasu's blog

ロード的なことを

PythonでMuninのプラグイン作成

Muninというソフトを「サーバ監視、何使ってる? | スラド Slashdotに聞け」で知ったので、インストールしてみました。インストールはportsで、sysutils/munin-main, sysutils/munin-nodeをがしょがしょと。

それで、Apacheの転送量をアクセスログから拾うプラグインが無かったので、さくさくと書きました。VartualHostを作りまくってると、apache_accessesでは物足りないのよね。どのホストがどれだけ食っているのかわからないし。


まず、Muninのプラグインの仕組み。

設定とプラグインディレクトリーは、etc/munin/plugin-conf.d/plugins.conf というファイルがプラグインの設定ファイル、etc/munin/plugins/ がプラグインディレクトリーになります。plugins/の下には、全てシンボリックリンクがはられており、muninがそれぞれを呼び出します。


Muninがプラグインに渡す物リスト

第一引数 config
Muninが設定情報を知りたい時に問い合わせるっぽい。
plugins.conf
中身にenvと書かれた物は環境変数として渡します。下記のスクリプトだと、env.logfileにログファイル一覧をスペース区切りで書きます。


プラグインがMuninへ情報を渡す方法は、単純にstdoutへ出力させてやればいいだけです。

graph_title
グラフのタイトル
graph_args
グラフ作成時の引数。--baseに1024だと、1024=1kとなります。1000だと1000=1kに。-lとかもあるそうな。*1
graph_vlabel
縦軸の単位。${graph_period}で、勝手にsecondなどの文字を入れます。
graph_categry
graphのカテゴリーを指定します。これはApachenの物なので、apacheと。
access*.label
グラフの線の意味付けを。
access*.type
グラフのタイプを指定。ここに詳しく書いてます
access*.max
グラフの最大値
access*.min
グラフの最小値


下のスクリプトは、Apacheのログファイルから、転送量を返す物です。

設定例

env.logfile /path/to/logfile1 /path/to/logfile2
#!/usr/bin/env python2.5
# -*- encoding: utf8 -*-
#
# Parameters supported:
# 
# config
# autoconf
#
# Magic makers:
#%# family=auto
#%# capabilities=autoconf

import sys,os,re

_GRAPH = [('title',    'Apache traffic bytes.'),
		  ('args',     '--base 1024'),
		  ('vlabel',   'byte / ${graph_period}'),
		  ('category', 'apache')
]

logs = ['/var/log/httpd/access_log']
try:
	if os.environ['logfile']:
		logs = re.split(r'\s+', os.environ['logfile'])
except:
	pass

# drop the none file
_logs = [e for e in logs if os.path.exists(e)]

# show config
if len(sys.argv) > 1 and sys.argv[1] and sys.argv[1] == 'config':
	for g in _GRAPH:
		print "graph_%s %s" % g
	
	cnt = 0
	for p in _logs:
		name = os.path.basename(p)
		print 'accesses%s.label Path %s' % (cnt, p)
		print 'accesses%s.type DERIVE' % (cnt)
		print 'accesses%s.max 1048576' % (cnt)
		print 'accesses%s.min 0' % (cnt)
		cnt += 1
	sys.exit(0)

cnt = 0
for p in _logs:
	buff = 0
	for line in open(p,'r'):
		w = re.split(r'\s+', line)
		try :
			if re.match(r'\d+', w[9]):
				buff += int(w[9])
		except e:
			print e
	print "accesses%s.value %d" % (cnt, buff)
	cnt += 1


参考サイト: http://munin.projects.linpro.no/wiki/HowToWritePlugins

*1:参考先を参照