LoginSignup
5
5

More than 5 years have passed since last update.

タイムスタンプ付きのNginxリソース リアルタイムモニタリング

Last updated at Posted at 2016-07-08

Nginxのリソースモニタリング情報を、vmstatなどの結果とマージした資料を作成するのに、5秒ごとにタイムスタンプ付きで吐き出したかった。

元ネタはこちらにある、nginxstatus.py。この出力結果にタイムスタンプを入れたかったのでちょっと修正したもの(いや・・・ほとんどそのまま)。

nginxstatus.py
#!/usr/bin/env python

import re
import sys
import time
import urllib

TIME_SLEEP = 5


def get_data(url):
    data = urllib.urlopen(url)
    data = data.read()
    result = {}

    match1 = re.search(r'Active connections:\s+(\d+)', data)
    match2 = re.search(r'\s*(\d+)\s+(\d+)\s+(\d+)', data)
    match3 = re.search(r'Reading:\s*(\d+)\s*Writing:\s*(\d+)\s*'
        'Waiting:\s*(\d+)', data)
    if not match1 or not match2 or not match3:
        raise Exception('Unable to parse %s' % url)

    result['connections'] = int(match1.group(1))

    result['accepted'] = int(match2.group(1))
    result['handled'] = int(match2.group(2))
    result['requests'] = int(match2.group(3))

    result['reading'] = int(match3.group(1))
    result['writing'] = int(match3.group(2))
    result['waiting'] = int(match3.group(3))

    return result


def main():
    url = sys.argv[1]
    prev = None
    next = time.time() + TIME_SLEEP
    total = None
    count = 0
    try:
        while True:
            data = get_data(url)
            if prev:
                result = print_stat(prev, data)
                if total is None:
                    total = list(result)
                else:
                    for i, v in enumerate(result):
                        total[i] += v
                count += 1
            else:
                print_head()
            prev = data
            time.sleep(next - time.time())
            next += TIME_SLEEP
    except KeyboardInterrupt:
        if total:
            print_foot(total, count)


def print_foot(total, count):
    total = [v / count for v in total]
    print '----------------- ------- ---------- ---------- ----- ----- -----'
    print '***************** %7d %10.2f %10.2f %5d %5d %5d' % tuple(total)


def print_head():
    print '%-17s %-7s %-10s %-10s %-5s %-5s %-5s' % (
        'Datetime', 'Conn', 'Conn/s', 'Request/s', 'Read', 'Write', 'Wait')
    print '----------------- ------- ---------- ---------- ----- ----- -----'


def print_stat(prev, data):
    result = (
        data['connections'],
        float(data['accepted'] - prev['accepted']) / TIME_SLEEP,
        float(data['requests'] - prev['requests']) / TIME_SLEEP,
        data['reading'],
        data['writing'],
        data['waiting'])

    from datetime import datetime as dt
    print dt.now().strftime("%y/%m/%d %H:%M:%S") + '%8d %10.2f %10.2f %5d %5d %5d' % result
    return result


if __name__ == '__main__':
    main()

例えば、linux上で動かす場合は以下のように使う。
事前に、"http://localhost/status" でnginxのステータスが取得できることを確認しておくこと。

$ python nginxstatus.py http://localhost/status

実行結果。

実行結果
$ ./nginxstatus.py http://localhost/status
Datetime          Conn    Conn/s     Request/s  Read  Write Wait
=---------------- ------- ---------- ---------- ----- ----- -----
16/07/08 22:45:19       1       1.00       1.00     0     1     0
16/07/08 22:45:20       1       1.00       1.00     0     1     0
16/07/08 22:45:21       1       1.00       1.00     0     1     0
16/07/08 22:45:22       1       1.00       1.00     0     1     0
16/07/08 22:45:23       1       1.00       1.00     0     1     0
16/07/08 22:45:24       1       1.00       1.00     0     1     0
=---------------- ------- ---------- ---------- ----- ----- -----
*****************      1       1.00       1.00     0     1     0
5
5
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
5
5