GeekFactory

int128.hatenablog.com

motionの動体検知イベントをfluentd + Zabbixで監視する

動体検知アプリケーションmotionのログをZabbixで監視してみました。参考になりましたら嬉しいです。

基本的な考え方

motionのイベントが発生するとログファイルにJSONを書き出します。そのログファイルをfluentdで監視し、Zabbixに通知します。具体的には、ログファイルをtailしたものをforwardし、fluentd-plugin-zabbix で通知します。

fluentdを使わなくても、zabbix-senderを実行してZabbixに通知する方法もあります。本稿の方法は以下のメリットがあります。

  • ホスト間の転送やZabbixへの通知はfluentdがやってくれる。複雑なシェルスクリプトを書く必要がない。
  • fluentdが再送処理をやってくれる。ネットワークが不安定な場合やダウンタイムの再送処理を自分で作り込む必要がない。
  • motionが不安定にならない。(イベントハンドラで長時間の外部プロセスを実行したらmotionが不安定になったことがあったため)

前提

下記のホストがあるものとします。

  • ホスト 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の方が読みやすそう。