motionの動体検知イベントをfluentd + Zabbixで監視する
動体検知アプリケーションmotionのログをZabbixで監視してみました。参考になりましたら嬉しいです。
基本的な考え方
motionのイベントが発生するとログファイルにJSONを書き出します。そのログファイルをfluentdで監視し、Zabbixに通知します。具体的には、ログファイルをtailしたものをforwardし、fluentd-plugin-zabbix で通知します。
fluentdを使わなくても、zabbix-senderを実行してZabbixに通知する方法もあります。本稿の方法は以下のメリットがあります。
前提
下記のホストがあるものとします。
- ホスト cameraserver1
- motion が動いている。
- fluentd がインストールされている。
- ホスト zabbixserver
- fluentd がインストールされている。
- fluentd-plugin-zabbix がインストールされている。
- zabbix-server が動いている。
motionの構築は 動体検知アプリケーションmotionを構築する - GeekFactory をご覧ください。
fluentdの構築は Quickstart Guide | Fluentd が参考になります。なお、RubyGemsからインストールする場合はsupervisorでデーモンを管理すると便利です。
motion の設定
イベントハンドラでログを書き出します。
# /etc/motion/motion.conf (cameraserver1) on_event_start echo '{"time":"%s","motion.delta.%t":0}' >> /var/log/motionevents on_motion_detected echo '{"time":"%s","motion.delta.%t":%D}' >> /var/log/motionevents on_event_end echo '{"time":"%s","motion.delta.%t":0}' >> /var/log/motionevents on_picture_save echo '{"time":"%s","motion.picture":"%f"}' >> /var/log/motionevents on_camera_lost echo '{"time":"%s","motion.lost":%t}' >> /var/log/motionevents
ここでは以下の方針でログを書いています。
- 動きを検出した場合は motion.delta.1 というキーで変化量を送信する。
- 一連の動きの前後は変化量をゼロクリアする。(gapで指定した時間を一連とみなす)
- ファイルを保存した場合は motion.picture というキーでファイル名を送信する。
- カメラ接続がロストした場合は motion.lost というキーでカメラ番号を送信する。
fluentd の設定
ホスト cameraserver1 では、ログを zabbixserver に転送する設定を書きます。
# /etc/fluentd.conf (cameraserver1)
<source>
type tail
path /var/log/motionevents
pos_file /var/lib/fluentd/motionevents.pos
tag motion.events.cameraserver1
format json
time_key time
time_format %s
</source>
<match motion.events.*>
type forward
<server>
name zabbixserver
host zabbixserver
</server>
</match>
ホスト zabbixserver では、ログをZabbix Serverに通知する設定を書きます。
# /etc/fluentd.conf (zabbixserver)
<source>
type forward
</source>
<match motion.events.cameraserver1>
type zabbix
zabbix_server localhost
host cameraserver1
name_key_pattern ^motion
</match>
Zabbix の設定
Zabbixトラッパーのアイテムを作成します。トラッパーのキーはfluentdのキーと一致するようにしてください。
トリガーはいろんな方法が考えられますが、私は下記のようにしています。直前の1時間が静かな状態で動きを検出するとイベントが上がります。
{My_Motion_Traps:motion.delta.1.max(60)}>{$THRESHOLD} & {My_Motion_Traps:motion.delta.1.max(3600,60)}<{$THRESHOLD}
グラフはこんな感じ。
今後の課題
現状では日時が秒単位になっているが、ミリ秒まで取れるようにしたい。
やや流行を逃した気がしますが、LTSVの方が読みやすそう。