RSS のアップデートを Zabbix で監視する仕組みを簡単に作ってみました。Zabbix 単体の機能では実装できないため。Zabbix の外部チェックを使用し実装してみました。
RSS をテキストに出力し、前回との差分を取得するという形でも良かったのですが、Zabbix サーバに障害が発生し、別のサーバで稼働させるとなったときに、チェック用のファイルをわざわざ移すのは面倒だし、絶対に忘れると思い、外部チェックを選択しました。
環境
- CentOS 8.0 (インターネットへアクセスできること)
- Python 3.6
- Zabbix 5.0
実現したこと
- Python を使って RSS を取得する
- 前回からのアップデート分を取得し、Zabbix のアイテムへ格納する
ここではお話しないこと
- Python の初期設定方法
- Zabbix のインストール方法
- Zabbix の一般的な機能説明
Pythonで実現したこと
Python では、RSS をインターネット経由で取得し、タイトル、更新日を取得し、1行に書き出すという処理を行いました。最終的に Zabbix へ転送させるため、出力はテキストです。
(API を使えば、JSON 形式でも行けるかもしれませんが、今回はやっていません。)
なお、Zabbix に重複したデータを送りたくないため、全件取得ではなく、前回の取得時間からの間に更新された記事のデータを取得する方式にしました。
出力については、Zabbix の外部チェックは標準出力の結果をアイテムに格納するため、print で出力を行っています。
コードは以下の通りです。
#!/bin/env python3
import feedparser
from datetime import datetime, timedelta, timezone
# 前回の期間を設定 (今回は1時間前の時間を指定)
lasttime = (datetime.utcnow() - timedelta(hours=1))
# RSSの取得
RSS_URL = "(URLを指定)"
feed = feedparser.parse(RSS_URL)
# 前回の時間以降にアップデートされた記事を取得
def f(entry):
return datetime(*entry.updated_parsed[:6]) >= lasttime
# フィルタ関数を使用しデータを選定
rdflists = filter(f, feed.entries)
# 何もない時は処理を終わる
if not rdflists:
sys.exit()
# データがあるときは、出力を行う
for entry in rdflists:
title = entry.title
link = entry.link
time = entry.updated
print (title, link, time)
Zabbixサーバへのコードの配置
Zabbix の外部チェック機能を使用する場合は、zabbix_server.conf の ExternalScripts のパスにスクリプトファイルを配置する必要があります。デフォルトは以下のフォルダが指定されています。
ExternalScripts=/usr/lib/zabbix/externalscripts
また、Zabbix ユーザが実行できるように、実行権限と所有者設定もお忘れなく。
# cd /usr/lib/zabbix/externalscripts
# chmod 744 RSS_Checker.py
# chown zabbix:zabbix RSS_Checker.py
# ls -l
-rwxr--r-- 1 zabbix zabbix 1200 Jan 01 01:23 RSS_Checker.py
Zabbixで設定したこと
Zabbix では、専用の Item を作成します。
タイプは「外部チェック」を選択。データ型はテキストを選択しています。なお、ホストインターフェースは、Zabbix サーバで実行するため、「127.0.0.1:10051」を指定します。
監視間隔については、コードで指定した差分時間と合わせる必要がありますので、適宜変更が必要です。コードの間隔が長いと、データが重複して格納される可能性があり、Item の監視間隔が長いと、取得漏れが発生する可能性があります。
うまくいかなかったこと
この構成で、Zabbix の Item にデータが格納されましたが、2つ問題が発生しました。
- 出力された更新情報が複数ある場合でも、Zabbix では1レコードとして格納されてしまう
- 更新情報が無い場合でも、空のレコードが作られてしまう。
Trigger で文字列を拾って通知を行う場合は特に問題はないのですが、どうも美しくないなぁ…と。少し調べては見たのですが、外部チェックのテキスト格納の動きについて、調べることができませんでした。Item のデータ型を「ログ」や「文字列」にしても同じ結果でした。
この事象に対する解決方法は見つけられませんでしたが、取り込むことができたので、一旦完成としました。
うーん、でもやはり美しくない。。
(続く)