Published
- 5 min read
uWSGIの統計情報をfluentd経由でNorikraに格納するまでのメモ
検証背景
uWSGIには、統計情報を取得できるオプション設定がある。
The uWSGI Stats Server
- uwsgitopで人間が見ながらチューニングするのは何だかんだで大変
- uWSGIのJSONはネスト構造で複雑
- Kibana化を見越して、InfluxDBでもよいかなと思ったけど、返ってくるJSONが複雑すぎた。
- Norikraは複雑なJSONでもクエリを投げられるので、そこまで格納できれば監視&可視化に使うのはユーザが自由に行える
想定連携図
各種ミドルウェアの連携は上記のイメージ。
なお、今回は全てローカル環境に構築した。
各ミドルウェアインストール
uwsgiインストール
pip install uwsgi
td-agentインストール
Overview of Streaming Import by Treasure Agent (td-agent)【リンク切れ】を参照のこと。
今回はUbuntuで試したけど、おそらくCentOSなどでも連携可能な筈
Norikraインストール
Norikraのインストールは、JRubyの環境を整えるのが面倒くさかったので、
下記サイトのdockerイメージで準備した(doker環境の準備方法は割愛)
Fluentd と Norikra をもっとカジュアルに使おう
各種設定情報
uWSGI
uWSGI起動方法
uwsgi --ini uwsgi_test.ini
こんな感じでuWSGIは起動できる。iniファイルの中身は以下の通り。
[uwsgi]
http=0.0.0.0:8080
stats=/tmp/stat.sock
chmod-socket=666
max-requests=100
vacuum=true
本番運用時は、リバースプロキシにnginxなどを配置する方がよさげ。
fluentdのin_execでローカルから統計情報を取得するため、stats用の設定を入れてある。
ちなみに、uWSGIの統計情報は、以下の様なJSONで返ってくる。
- uWSGIの統計情報JSON
{
"version": "2.0.11",
"listen_queue": 0,
"listen_queue_errors": 0,
"signal_queue": 0,
"load": 0,
"pid": 4364,
"uid": 0,
"gid": 0,
"cwd": "/root",
"locks": [
{
"user 0": 0
},
{
"signal": 0
},
{
"filemon": 0
},
{
"timer": 0
},
{
"rbtimer": 0
},
{
"cron": 0
},
{
"rpc": 0
},
{
"snmp": 0
}
],
"sockets": [
{
"name": "127.0.0.1:49294",
"proto": "uwsgi",
"queue": 0,
"max_queue": 100,
"shared": 0,
"can_offload": 0
}
],
"workers": [
{
"id": 1,
"pid": 5284,
"accepting": 1,
"requests": 5304,
"delta_requests": 121,
"exceptions": 0,
"harakiri_count": 0,
"signals": 0,
"signal_queue": 0,
"status": "idle",
"rss": 0,
"vsz": 0,
"running_time": 1578271,
"last_spawn": 1438499807,
"respawn_count": 19,
"tx": 551616,
"avg_rt": 266,
"apps": [],
"cores": [
{
"id": 0,
"requests": 5304,
"static_requests": 0,
"routed_requests": 0,
"offloaded_requests": 0,
"write_errors": 0,
"read_errors": 0,
"in_request": 0,
"vars": []
}
]
}
]
}
td-agent
- td-agent.conf
<source>
type exec
format json
command python /etc/td-agent/uwsgi_stat.py
run_interval 1s
tag hoge
</source>
<match hoge>
type norikra
norikra localhost:26571
target_map_tag true
</match>
今回、norikraはローカルに準備したので、この設定になっている。
- in_execで実行するpythonスクリプト
#!/usr/bin/env python
import subprocess
import json
cmd = '/usr/local/bin/uwsgi --connect-and-read /tmp/stat.sock'
try:
result = subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=True)
return_json = result.communicate()[1]
#JSON DATA Validation
json.loads(return_json)
#JSON DATA to fluent
print return_json
except Exception as e:
print '{"uwsgistat_errmsg":"' + str(e) + '"}'
Norikraで投げるクエリ例
これは運用しながら、適宜クエリ内容を見直すことになるかと。
harakiri_countやexceptionsとかも登録しておいた方がよさそう。
- listen_queue状況の確認例
select
avg(listen_queue) as listen_queue_avg,
avg(listen_queue_errors) as listen_queue_errors_avg
from
hoge.win:time_batch(1 min)
- 平均リクエスト時間の確認例
select
avg(workers.$0.avg_rt) as workers_avg_rt
from
hoge.win:time_batch(1 min)
- 物理メモリ消費量の確認例
select
avg(workers.$0.rss) as workers_rss
from
hoge.win:time_batch(1 min)
結果
Norikraに格納された結果は、こんな感じ
今回は、Norikraにデータを格納するまでに絞っているが、
あとはnorikra-clientを使って、ゴニョゴニョすれば色んなところで可視化できるかと。
まとめ
uWSGIの統計情報をfluentd経由でNorikraまで送信して、データを集計させることができた。
統計情報はfluentd経由で送信しているので、今後BigQueryやS3などに入れるといった要件にも対応できる筈