maetesのブログ

個人用Memoです

Zabbix 2.4 でログデータからint情報の登録

Zabbix 2.4 の環境で、ログデータから情報を登録する必要があったのでそのご紹介です

問題点

  • Zabbix 2.4 環境ではログデータはstring型のみであり、数値情報として扱えない
    • つまりZabbix Agent のログ処理系の関数は使えない
  • Agent側のUserParameter で定義した場合、監視間隔で実行され、実際にログが出力されたタイムスタンプで登録ができない

解決策

詳細

  1. 10分ごとのcron でログデータを確認
  2. 合致した場合ログデータを整形して別ファイルとして出力しておく
  3. Zabbix sender で当該ファイルを読み込んで出力

source code

今回はPythonで書きました

import re
import datetime
import time
import glob
import subprocess
import sys
import os

# Run every 10 min
# 08:00run --> 07:50 data check
# logExample)
#   INFO   | jvm 1    | 2017/11/14 15:00:00 |  16000000K->10000000K(40900000K), 10.0000 secs]


def main():
    # time variables
    now = datetime.datetime.now()
    base_time = (now - datetime.timedelta(minutes=10)).strftime("%Y/%m/%d %H:%M")[:-1]
    time_key = base_time[-1]

    # define variables
    inputfile = glob.glob('/tmp/testdata/server.log')
    output_filename = "/tmp/zabbix_senddata_output_" + time_key + ".txt"
    zabbix_server = "192.168.10.58"

    pattern = '\| (\d{4})/(\d{2})/(\d{2})\s(\d{2}):(\d{2}):(\d{2}).+\d+K->(\d+)K\(\d+K\)'
    msg = ""

    # getting information
    for file in inputfile:
        rfile = open(file, 'r')
        for line in rfile:
            r = re.search(pattern, line)
            if r:
                date = datetime.datetime(int(r.group(1)), int(r.group(2)), int(r.group(3)), int(r.group(4)),
                                         int(r.group(5)), int(r.group(6)))
                msg = msg + os.uname()[1] + " w_memory " + str(int(time.mktime(date.timetuple()))) \
                    + " " + r.group(7) + "\n"
        rfile.close()
    if msg == "":
        sys.exit()
    else:
        with open(output_filename, 'w')as wfile:
            wfile.write(msg)

    # sending info to zabbix
    command = ["/usr/bin/zabbix_sender", "-z", zabbix_server, "-p", "10051", "-T", "-i", output_filename]
    res = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
    subprocess.call(['/usr/bin/logger', __file__, res])


if __name__ == '__main__':
    main()

なお、環境が古くPython2.6系しかなかったので、subprocess コマンドは少し古めで書いてあります。。。