#概要
※初Qiita投稿です。至らない点があれば、コメントにて教えていただけると幸いです。
ボカロ好きな私が、ニコニコ動画上で特定のタグに更新があった場合に、Zabbixからお知らせ出来ないかと思い、試行錯誤してみました。
参考にさせて頂いたページ「Zabbixで更新チェッカーを作ってみる」
#現在の状態
Ubuntu上にDocker-composerを利用してZabbixサーバーを構築しています。
version: '2'
services:
zabbix_db:
container_name: zabbix_db
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
restart: always
image: mysql:5.7
volumes:
- "./data/db:/var/lib/mysql"
environment:
zabbix_server:
container_name: zabbix_server
image: zabbix/zabbix-server-mysql:alpine-4.2-latest
depends_on:
- zabbix_db
links:
- zabbix_db
volumes:
- ./scripts:/usr/lib/zabbix/externalscripts
- ./data/zabbix:/var/lib/zabbix
ports:
- "30051:10051"
- "30050:10050"
environment:
DB_SERVER_HOST: zabbix_db
zabbix_web:
container_name: zabbix_web
#image: zabbix/zabbix-web-nginx-mysql:alpine-4.2-latest
build:
context: ./
dockerfile: zabbix_web
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
links:
- zabbix_db
ports:
- "7998:80"
environment:
DB_SERVER_HOST: zabbix_db
ZBX_SERVER_HOST: zabbix_server
PHP_TZ: Asia/Tokyo
depends_on:
- zabbix_db
- zabbix_server
zabbix_agent:
container_name: zabbix_agent
image: zabbix/zabbix-agent:alpine-latest
restart: always
environment:
ZBX_SERVER_HOST: zabbix_server
ZBX_ENABLEREMOTECOMMANDS: 1
links:
- zabbix_server
depends_on:
- zabbix_server
参考にしたページを元につくってみる
##スクリプトの用意
#!/bin/bash
URL="$1"
# URLに含まれる文字でファイル名に使えない"/"は置換する
URL_PATH=${URL//\//-}
STORE_PATH="/tmp/urlcheck/url_${URL_PATH}"
mkdir -p /tmp/urlcheck
if [ -e "${STORE_PATH}_after" ]; then
# afterが存在すればbeforeとしてコピー
cp -f "${STORE_PATH}_after" "${STORE_PATH}_before"
else
# afterが存在しなければbeforeとしてコンテンツ取得
curl -s -g "$URL" -o "${STORE_PATH}_before"
fi
# コンテンツ取得
curl -s -g "$URL" -o "${STORE_PATH}_after"
# 差分確認
diff "${STORE_PATH}_before" "${STORE_PATH}_after" >/dev/null
echo $?
元のページのままだと取得時にエラーが出ることがあったため、一部改変しています。
実行権限を付与し、docker-composeに下記を追記します。
zabbix_server:
volumes:
- ./scripts:/usr/lib/zabbix/externalscripts
docker内に入り、スクリプトをテストします。
# /usr/lib/zabbix/externalscripts/urlcheck.sh http://google.com/
0
正常終了なら、0が戻ります。
ページが更新された場合、1が戻る仕様になっているので、これをZabbixで監視します。
##Zabbixにアイテム登録
上記の通り登録します。
- 名前:URL定期更新テスト
- タイプ:外部チェック
- キー:urlcheck.sh["https://google.com/"]
- 更新間隔:60m
##Zabbixにアクション登録
上記通り登録します。
- 名前:定期更新アクション
- 条件式:{localhost:urlcheck.sh["https://google.com/"].last()}<>0
- 説明:{ACTION.NAME} is changed.
問題点:単一ページでは動くが、RSSなどの動的ページでは想定通りに動作しない
##原因を調べてみる
上記のニコニコ動画のRSSをよーく眺めてみると、/rss/channel/lastBuildDateのところに更新日時が入ってしまっている。
この文字列が毎回変更されるため、取得しに行くたびに変更した扱いになるため、想定の動作しませんでした。
なので、XMLを簡易解析し、/rss/channel/item[n]/titleをテキスト出力し、それを比較することにします。
##Dockerfileの作成とdocker-composeの修正
現在の設定ではZabbixServer内でXMLの解析が行えないため、Dockerイメージを作り直すことにしました。
FROM zabbix/zabbix-server-mysql:alpine-4.2-latest
RUN apk add --update curl xmlstarlet && \
rm -rf /var/cache/apk/*
- curl
- xmlstarlet
を有効にしたDockerfileを作成し、docker-composeに追記します。
zabbix_server:
#image: zabbix/zabbix-server-mysql:alpine-4.2-latest
build:
context: ./zabbix_server
dockerfile: Dockerfile
シェルスクリプトの追加
#!/bin/bash
URL="$1"
# URLに含まれる文字でファイル名に使えない"/"は置換する
URL_PATH=${URL//\//-}
STORE_PATH="/tmp/urlcheck/rss_${URL_PATH}"
mkdir -p /tmp/urlcheck
if [ -e "${STORE_PATH}_after" ]; then
# afterが存在すればbeforeとしてコピー
cp -f "${STORE_PATH}_after" "${STORE_PATH}_before"
else
# afterが存在しなければbeforeとしてコンテンツ取得
curl -s -g "$URL" | xmlstarlet sel -t -m "/rss/channel/item" -v "title " -o " / " -v "pubDate" -n > "${STORE_PATH}_before"
fi
# コンテンツ取得
curl -s -g "$URL" | xmlstarlet sel -t -m "/rss/channel/item" -v "title " -o " / " -v "pubDate" -n > "${STORE_PATH}_after"
# 差分確認
diff "${STORE_PATH}_before" "${STORE_PATH}_after" >/dev/null
echo $?
RSS用のシェルスクリプトを作成し、同様に実行権限を付与し、テストします。
やってることは単純で、CURLで取得したデータをXmlstarletを通して、下記の通り整形しています。
- タイトル / 動画の更新日
- タイトル / 動画の更新日
- ・・・
# /usr/lib/zabbix/externalscripts/rsscheck.sh https://www.nicovideo.jp/tag/%E9%9A%A0%E3%82%8C%E3%81%9F%E3%83%9C%E3%82%AB%E3%83%AD%E5%90%8D%E6%9B%B2?rss=2.0
0
あとは、既に記載したように、Zabbixにアイテム登録すれば動きます。
お盆休みで田舎に帰って暇だったので、思いつきで作ってみました。
2019/08/14 追記
RSSチェックが、時々更新判定を失敗しているので、よくよく確認してたところ、オプションフラグをつけないと毎回最新順にソートされているとは限らないようでした。
現在は下記の通りの設定でうごいています。
- キー:rsscheck.sh["https://www.nicovideo.jp/tag/%E6%A9%9F%E5%8B%95%E6%AD%8C%E5%A7%AB%E3%83%B4%E3%82%A9%E3%83%BC%E3%82%AB%E3%83%AA%E3%82%AA%E3%83%B3?sort=f&order=d&rss=2.0"]