雑記

インフラのことだったりプログラムのことだったりどうでもいいこと書いたり。要は雑記。

zabbixでnginxの接続状態を確認する

nginxにはstub_statusというnginxへの接続状態を提供する機能があります。

http://wiki.nginx.org/HttpStubStatusModule#stub_status

Apacheでいうserver-statusですね。

せっかくなのでこのstub_statusの値をzabbixから取得できるようにしてみました。

nginx側の設定

そもそもの前提として

nginxでHttpStubStatusModuleが有効化されている必要があります。
コンパイル時に以下を指定します。

--with-http_stub_status_module

もうインストールしちゃったよーという人は以下でコンパイルオプションを確認できます。

nginx -V

stub_statusを設定する

  • では設定します。以下設定例です。
server {
    listen 8080;

    location /_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

listenとかlocationとかログとかの設定は適宜変えて下さい。
要は「stub_status on;」さえ設定されていればよいです。

アクセスするとこんな画面が表示されると思います。

Active connections: 1 
server accepts handled requests
1321 1321 10437 
Reading: 0 Writing: 1 Waiting: 0 

以下、それぞれのおおまかな意味です。

Active connections
現在の接続数
server accepts handled requests
左から「許可した接続」「捌いた接続」「捌いたリクエスト」
reading
読み込んだリクエストヘッダーの数
writing
読み込んだリクエストボディーの数もしくはリクエストを処理しクライアントへ返した数
waiting
keep-aliveの接続数

zabbixに取り込む

stub_statusで取得したデータを取り込みます。
以下、取得するためのスクリプトです。

#!/bin/env python
#-*-coding:utf-8-*-
#
# Zabbix for Nginx
#
# nginxのステータスを取得します
#
# usage:
# 1) cronに登録して下さい
# */1 * * * * root python /path/to/zabbix_nginxstats.py
#
# 2) zabbix_agentd.confに以下を設定して下さい。
# UserParameter=nginx.active_connections,cat /home/zabbix/nginx/active_connections
# UserParameter=nginx.total_connections,cat /home/zabbix/nginx/total_connections
# UserParameter=nginx.handle_connections,cat /home/zabbix/nginx/handle_connections
# UserParameter=nginx.total_requests,cat /home/zabbix/nginx/total_requests
# UserParameter=nginx.reading_count,cat /home/zabbix/nginx/reading_count
# UserParameter=nginx.writing_count,cat /home/zabbix/nginx/writing_count
# UserParameter=nginx.waiting_count,cat /home/zabbix/nginx/waiting_count
#
# 3) zabbixテンプレートの設定をしてください。
#
#
# 動作確認環境:
# nginx-1.4.1
# zabbix-agent-1.8.16
# python-2.6.6
# 


import re
import urllib2

## stub_statusのURL
nginx_status_url = 'http://localhost:8080/_status'

## レスポンス結果の作成ディレクトリ
result_dir = '/home/zabbix/nginx'

#
# リクエストの送信
#
def request_data(url):
    request = urllib2.Request(nginx_status_url)
    try:
        response = urllib2.urlopen(request)
        return response.read()
    except:
        return False

#
# ファイルの作成
#
def put_file(file_path, data):
    handle = open(file_path, 'w')
    handle.write(str(data))
    handle.close()

def main():
    result = request_data(nginx_status_url)

    if (result):
        active_connections = re.search('Active\sconnections:\s(\d+)', result)
        handled_requests = re.search('\s+(\d+)\s+(\d+)\s+(\d+)\s', result)
        reading_count = re.search('Reading:\s(\d)', result)
        writing_count = re.search('Writing:\s(\d)', result)
        waiting_count = re.search('Waiting:\s(\d)', result)

        put_file(result_dir + '/active_connections', active_connections.group(1))
        put_file(result_dir + '/total_connections', handled_requests.group(1))
        put_file(result_dir + '/handle_connections', handled_requests.group(2))
        put_file(result_dir + '/total_requests', handled_requests.group(3))
        put_file(result_dir + '/reading_count', reading_count.group(1))
        put_file(result_dir + '/writing_count', writing_count.group(1))
        put_file(result_dir + '/waiting_count', waiting_count.group(1))
    else:
        put_file(result_dir + '/active_connections', '0')


if __name__ == '__main__':
    main()

設定方法はスクリプト内で書いてますので参考にしてください。

スクリプトを見れば分かりますが、この方法はリアルタイムで取得する方法ではありません。

  1. 定期的に接続情報をファイルに書き出し
  2. zabbixがそのファイルの内容を読み込み
  3. zabbixに登録

という流れです。
リアルタイムで取得したかったら引数を処理するようにして、指定された値を返すようにすればよいかと思います。

※ちなみになんでリアルタイムにしなかったかというと、引数で処理する場合は全ての値を取得するにはnginxに7回アクセスする必要があるからです。うまくやる方法ありそうですけど。。