Zabbixで更新チェッカーを作ってみる

# 概要
Zabbix Advent Calendar 2017 5日目の記事です。

不定期に更新があって、かつRSSなどの発信をしてないようなWebページの更新チェッカーを、Zabbix絡めて作ってみたいな～と思い作ってみました。
ここでは「不定期更新ページ」の一例として、[さくら水産のランチメニュー](https://www.sakusui.jp/menu/lunch/)を取り上げます。

※運用し始めて気づいたんですが、さくら水産のランチメニューページ、毎週月曜のAM9:00に更新されるじゃないですか！(不定期じゃない…！)

# つくってみる

## シェルの作成
コンテンツの差分をチェックするシェルを用意します。
といっても中身は単にcurlコマンド叩いて比較してるだけ…。
コンテンツの差分がない時は0が返され、差分がある時は1が返されます。

```urlcheck.sh
#!/bin/sh

URL="$1"
# URLに含まれる文字でファイル名に使えない"/"は置換する
URL_PATH=${URL//\//-}
STORE_PATH="/tmp/urlcheck/${URL_PATH}"

if [ -e "${STORE_PATH}_after" ]; then
  # afterが存在すればbeforeとしてコピー
  cp -f "${STORE_PATH}_after" "${STORE_PATH}_before"
else
  # afterが存在しなければbeforeとしてコンテンツ取得
  curl -s $URL -o "${STORE_PATH}_before"
fi

# コンテンツ取得
curl -s $URL -o "${STORE_PATH}_after"

# 差分確認
diff "${STORE_PATH}_before" "${STORE_PATH}_after" >/dev/null
echo $?
```

curlコマンドでページのコンテンツサイズだけを取得して比較する方法も考えていましたが、コンテンツサイズが全く同じ場合に検知出来ないと思い、コンテンツの内容を取得する方法にしてみました。
また、ページのLast-Modifiedをみて更新を検知する方法も考えましたが、Last-Modifiedを付与しないページもあるようなのでこの方法もボツ。

## シェルの配置
/usr/lib/zabbix/externalscripts/ 配下に urlcheck.sh を置きます。
配置後、オーナー・パーミッションの設定と、取得コンテンツの格納フォルダの作成を行います。

```
chown zabbix:zabbix /usr/lib/zabbix/externalscripts/urlcheck.sh
chmod +x /usr/lib/zabbix/externalscripts/urlcheck.sh
mkdir /tmp/urlcheck
chown zabbix:zabbix /tmp/urlcheck
```

試しに手動で動かしてみます。

> /usr/lib/zabbix/externalscripts/urlcheck.sh "https://www.sakusui.jp/menu/lunch/"

シェルを動かすと、/tmp/urlcheck/配下にコンテンツが置かれていきます。

```
[root@xxx ~]# ll /tmp/urlcheck/
total 32
-rw-rw-r-- 1 zabbix zabbix 13237 Dec  4 16:01 https:--www.sakusui.jp-menu-lunch-_after
-rw-rw-r-- 1 zabbix zabbix 13237 Dec  4 16:01 https:--www.sakusui.jp-menu-lunch-_before
```

## Zabbixでホスト作成
Zabbixに今回用のホストを新規作成します。

- ホスト名: www.sakusui.jp (任意)
- 表示名: さくら水産 (任意) 

※デフォルト値ママの項目は省略しています。
※(任意)となっている値は自由に設定してください。

## Zabbixでアイテム登録
urlcheck.shから、https://www.sakusui.jp/menu/lunch/ をチェックするので以下内容で登録。

- 名前: urlcheck (任意)
- タイプ: 外部チェック
- キー: urlcheck.sh["https://www.sakusui.jp/menu/lunch/"]
- データ型: 数値(整数)
- 更新間隔: 600s (任意)
- アプリケーション: "externalscripts"を作成して登録。 (任意)

![アイテム.jpg](https://qiita-image-store.s3.amazonaws.com/0/128331/998d33ed-75ae-0c9f-78cf-6efafdf10dca.jpeg)

*※設定するURLがリダイレクトされている場合は、リダイレクト後のURL(curlコマンドでチェックしたいコンテンツの中身が取れるURL)である必要があります。*

## Zabbixでトリガー作成
以下の設定でトリガーを作成。

- 名前: urlcheck (任意)
- 深刻度: 情報 (任意)
- 条件式: {www.sakusui.jp:urlcheck.sh["https://www.sakusui.jp/menu/lunch/"].last()}=1

条件式ビルダー使う場合は以下のように指定します。

- アイテム: {さきほど登録したアイテム}
- 関数: 最新(T秒前/T個前)の値 = N
- N: 1

![トリガー.jpg](https://qiita-image-store.s3.amazonaws.com/0/128331/2ea79da8-1d2c-7eaa-81f9-67cb3d391549.jpeg)

## Zabbixでアクション作成
さらにアクションを設定します。

**「アクション」タブ**

- 名前: さくら水産ランチメニュー更新通知 (任意)
- 実行条件: トリガー = さくら水産: urlcheck を追加します。

![アクション1.jpg](https://qiita-image-store.s3.amazonaws.com/0/128331/722579df-5b45-dcb8-6b12-e58c729de53d.jpeg)

**「実行内容」タブ**

- "デフォルトの件名"、"デフォルトのメッセージ"を通常のアラート通知と区別するため柔らかく、そしてスッキリした内容に変更しました。
- "実行内容"にメッセージ送信などの設定を行います。

![アクション2.jpg](https://qiita-image-store.s3.amazonaws.com/0/128331/3ebb6ed7-b60b-9e36-be47-d9321d61f418.jpeg)

# 更新通知が届く
ページが更新されると、アクションにて指定した手段で更新が通知されます。
メールが飛ぶようにしておいたら、メールが飛んで来ました。

![mail.jpg](https://qiita-image-store.s3.amazonaws.com/0/128331/a29575e2-17d6-a097-d0f2-4ce45eded054.jpeg)

# 最後に
勢いに任せて(笑)とりあえず作ってみたZabbix更新チェッカーですが、似たようなことを他のやり方で実践されている方がいらっしゃいましたら教えていただきたいです～。

あと、さくら水産ランチ生たまご食べ放題で嬉しいんですけど、私は1個が限界っす…🐣