4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Webページの更新チェッカー on Zabbix@Docker

Last updated at Posted at 2019-08-13

#概要
※初Qiita投稿です。至らない点があれば、コメントにて教えていただけると幸いです。

ボカロ好きな私が、ニコニコ動画上で特定のタグに更新があった場合に、Zabbixからお知らせ出来ないかと思い、試行錯誤してみました。

参考にさせて頂いたページ「Zabbixで更新チェッカーを作ってみる

#現在の状態
Ubuntu上にDocker-composerを利用してZabbixサーバーを構築しています。

docker-compose.yml_抜粋
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

参考にしたページを元につくってみる

##スクリプトの用意

./script/urlcheck.sh
#!/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に下記を追記します。

docker-compose.yml
  zabbix_server:
    volumes:
      - ./scripts:/usr/lib/zabbix/externalscripts

docker内に入り、スクリプトをテストします。

# /usr/lib/zabbix/externalscripts/urlcheck.sh http://google.com/
0

正常終了なら、0が戻ります。
ページが更新された場合、1が戻る仕様になっているので、これをZabbixで監視します。

##Zabbixにアイテム登録

ss1-2.png

上記の通り登録します。

  • 名前:URL定期更新テスト
  • タイプ:外部チェック
  • キー:urlcheck.sh["https://google.com/"]
  • 更新間隔:60m

##Zabbixにアクション登録

ss2.png

上記通り登録します。

  • 名前:定期更新アクション
  • 条件式:{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に追記します。

cocker-compose.yml
  zabbix_server:
    #image: zabbix/zabbix-server-mysql:alpine-4.2-latest
    build:
      context: ./zabbix_server
      dockerfile: Dockerfile

シェルスクリプトの追加

rsscheck.sh
#!/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"]
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?