웹 페이지 업데이트 검사기 on Zabbix@Docker

개요



※첫 Qiita 투고입니다. 이르지 않는 점이 있으면, 코멘트에서 가르쳐 주실 수 있으면 다행입니다.

보카로 좋아하는 내가, 니코니코 동영상상에서 특정의 태그에 갱신이 있었을 경우에, Zabbix로부터 알림 할 수 없을까 생각해, 시행착오해 보았습니다.

참고로 한 페이지 "Zabbix로 업데이트 체커 만들기"

현재 상태



우분투에 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에 아이템 등록





위와 같이 등록합니다.
  • 이름: URL 정기 업데이트 테스트
  • 유형: 외부 점검
  • 키: urlcheck.sh["htps : //오오 gぇ. 이 m/” ]
  • 갱신 간격: 60m

  • Zabbix에 액션 등록





    위와 같이 등록합니다.
  • 이름: 정기 갱신 액션
  • 조건식: {localhost:urlcheck.sh["htps : //오오 gぇ. 이 m/””. 아 st() }<>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["htps //w w. 니코 ゔ에서. jp/타g/%에6%아9%9F%에5%8B%95%에6%아D%8C%에5%아7%아B%에3%83%B4%에3%82% 오 9% 에 3% 83% BC% 에 3% 82% 아 B% 에 3% 83% 아 % 에 3% 82% 아 % 에 3% 83% B3? rt = f & r에서 r = d & r s = 2.0 " ]
  • 좋은 웹페이지 즐겨찾기