ようへいの日々精進XP

よかろうもん

fluent-plugin-haproxy_stats というプラグインを作ってみた

HAProxy は自身の状態を Web ブラウザ又は UNIX ドメインソケット経由で確認することが出来る stats という機能を備えているが、UNIX ソケットドメイン経由で出力される状態を収集する fluentd の input プラグインを勉強がてら作ってみた。

github.com

まだ、テストが書けていないのでハンパもんです。

HAProxy の stats とは

コマンドラインから確認出来る

$ echo "show stat" | sudo socat stdio /tmp/haproxy_stats

以下のように HAProxy の状態が細かく出力される。

# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,
app1,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,,0,0,0,0,,,,,,,,
app1,web1,0,0,0,0,,0,0,0,,0,,0,0,0,0,no check,1,1,0,,,,,,1,3,1,,0,,2,0,,0,,,,0,0,0,0,0,0,0,,,,0,0,,,,,-1,,,0,0,0,0,
app1,web2,0,0,0,0,,0,0,0,,0,,0,0,0,0,no check,1,1,0,,,,,,1,3,2,,0,,2,0,,0,,,,0,0,0,0,0,0,0,,,,0,0,,,,,-1,,,0,0,0,0,
app1,BACKEND,0,0,0,0,200,0,0,0,0,0,,0,0,0,0,UP,2,2,0,,0,415,0,,1,3,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,0,0,0,0,-1,,,0,0,0,0,
stats,FRONTEND,,,0,4,2000,8,3326,36816,0,0,2,,,,,OPEN,,,,,,,,,1,4,0,,,,0,0,0,4,,,,0,2,0,2,4,0,,0,2,8,,,0,0,0,0,,,,,,,,
stats,BACKEND,0,0,0,1,200,4,3326,36816,0,0,,4,0,0,0,UP,0,0,0,,0,415,0,,1,4,0,,0,,1,0,,2,,,,0,0,0,0,4,0,,,,,0,0,0,0,0,0,311,,,0,0,0,1,

Web ブラウザでも見ることが出来る

f:id:inokara:20150627162907p:plain


fluentd で収集してみる

詳しくは

README.md を見ていただくとして...

HAProxy の設定

ポイントは global セクションの stats オプションで td-agent ユーザーでも読めるように権限は 666 にしておく。

global
    stats socket /tmp/haproxy_stats mode 666 level user

defaults
  mode    http
  maxconn 2000
  timeout connect 5000ms
  timeout client 60000ms
  timeout server 60000ms


frontend app1
  bind 0.0.0.0:10011
  default_backend app1

backend app1
  balance roundrobin
  server web1 127.0.0.1:10006
  server web2 127.0.0.1:10007

listen stats :19190
  mode http
  stats enable
  stats uri /haproxy?stat

せっかくなのでシンプルな Web サーバーを起動しておく。

mkdir /tmp/web
cd /tmp/web
touch index.html
python -m SimpleHTTPServer 10006 &
python -m SimpleHTTPServer 10007 &

インストールと設定

今回は td-agent を利用するので、インストールは以下のように。

sudo /opt/td-agent/embedded/bin/gem install fluent-plugin-haproxy_stats --no-ri --no-rdoc -V
sudo /opt/td-agent/embedded/bin/gem install haproxy --no-ri --no-rdoc -V

設定は以下のように。

<source>
  type haproxy_stats
  stats_file /tmp/haproxy_stats
  px_name app1
  sv_name FRONTEND
  tag haproxy.input
</source>

<match haproxy.input.**>
  type stdout
</match>

上記の設定では app1 という名前の FRONTEND に該当するディレクティブ、先ほどの Web ページでは以下の部分に該当する状態が td-agent.log に出力される。

f:id:inokara:20150627202035p:plain

以下のように td-agent.log に出力される。

2015-06-27 11:18:14 +0000 haproxy.input.app1.FRONTEND: {"pxname":"app1","svname":"FRONTEND","qcur":"","qmax":"","scur":"0","smax":"1","slim":"2000","stot":"18","bin":"3240","bout":"3294","dreq":"0","dresp":"0","ereq":"0","econ":"","eresp":"","wretr":"","wredis":"","status":"OPEN","weight":"","act":"","bck":"","chkfail":"","chkdown":"","lastchg":"","downtime":"","qlimit":"","pid":"1","iid":"2","sid":"0","throttle":"","lbtot":"","tracked":"","type":"0","rate":"1","rate_lim":"0","rate_max":"1","check_status":"","check_code":"","check_duration":"","hrsp_1xx":"0","hrsp_2xx":"18","hrsp_3xx":"0","hrsp_4xx":"0","hrsp_5xx":"0","hrsp_other":"0","hanafail":"","req_rate":"1","req_rate_max":"1","req_tot":"18","cli_abrt":"","srv_abrt":"","":"0","extra":["0","0","0"]}
2015-06-27 11:19:24 +0000 haproxy.input.app1.FRONTEND: {"pxname":"app1","svname":"FRONTEND","qcur":"","qmax":"","scur":"0","smax":"1","slim":"2000","stot":"53","bin":"9540","bout":"9699","dreq":"0","dresp":"0","ereq":"0","econ":"","eresp":"","wretr":"","wredis":"","status":"OPEN","weight":"","act":"","bck":"","chkfail":"","chkdown":"","lastchg":"","downtime":"","qlimit":"","pid":"1","iid":"2","sid":"0","throttle":"","lbtot":"","tracked":"","type":"0","rate":"1","rate_lim":"0","rate_max":"1","check_status":"","check_code":"","check_duration":"","hrsp_1xx":"0","hrsp_2xx":"53","hrsp_3xx":"0","hrsp_4xx":"0","hrsp_5xx":"0","hrsp_other":"0","hanafail":"","req_rate":"1","req_rate_max":"1","req_tot":"53","cli_abrt":"","srv_abrt":"","":"0","extra":["0","0","0"]}
2015-06-27 11:20:34 +0000 haproxy.input.app1.FRONTEND: {"pxname":"app1","svname":"FRONTEND","qcur":"","qmax":"","scur":"0","smax":"1","slim":"2000","stot":"88","bin":"15840","bout":"16104","dreq":"0","dresp":"0","ereq":"0","econ":"","eresp":"","wretr":"","wredis":"","status":"OPEN","weight":"","act":"","bck":"","chkfail":"","chkdown":"","lastchg":"","downtime":"","qlimit":"","pid":"1","iid":"2","sid":"0","throttle":"","lbtot":"","tracked":"","type":"0","rate":"1","rate_lim":"0","rate_max":"1","check_status":"","check_code":"","check_duration":"","hrsp_1xx":"0","hrsp_2xx":"88","hrsp_3xx":"0","hrsp_4xx":"0","hrsp_5xx":"0","hrsp_other":"0","hanafail":"","req_rate":"1","req_rate_max":"1","req_tot":"88","cli_abrt":"","srv_abrt":"","":"0","extra":["0","0","0"]}

とりあえず、ここまでくれば他のプラグインの力を拝借して可視化等も出来るのではないかと密かに考えている。


ということで...

また未熟なプラグインを世に放ってしまった...。 精進します。