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

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

元ネタは[こちら](http://qiita.com/yoshiaki_0245/items/7470320a74fb20b331e0)にある、nginxstatus.py。この出力結果にタイムスタンプを入れたかったのでちょっと修正したもの（いや・・・ほとんどそのまま）。

```python: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
```

実行結果。

```text:実行結果
$ ./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
```