share facebook facebook2 twitter menu hatena pocket slack

2015.01.23 FRI

Ruby で csv to json(HAProxy の CSV で提供される statistics な情報を JSON で取得したいな)

川原 洋平

WRITTEN BY川原 洋平

ども。cloudpackかっぱ (@inokara) です。

追記(Sinatra と haproxy-ruby を使えば瞬殺だった)

haproxy-ruby

sudo gem install haproxy --no-ri --no-rdoc -V

Sinatra アプリ

require 'sinatra'
require 'sinatra/reloader'
require 'haproxy'
require 'json'

haproxy = HAProxy.read_stats '/var/run/haproxy.sock'
info =  haproxy.info
statistics =  haproxy.stats

get '/info' do
  info.to_json
end

get '/stats' do
  statistics.to_json
end

上記で Sinatra を任意のポート番号で起動することで statistics な情報が JSON で取れるようになる。こりゃ、たまらん。

はじめに

HAProxy の statistics な情報が JSON で返ってきたら汎用性が上がって嬉しいですよねって話していたのでちょっと作って(真似て)みた。

HAProxy の stats で取得出来る csv を JSON で返す

以下の stats ページ

Ruby で csv to json(HAProxy の CSV で提供される statistics な情報を JSON で取得したいな): HAProxy stats の画面

上図の CSV export をクリックすると以下のように csv でも見ることも出来る。
Ruby で csv to json(HAProxy の CSV で提供される statistics な情報を JSON で取得したいな): HAProxy で CSV エクスポート

実際に

上記の CSV を解析して JSON で返せるようにしたのが…こちらを頼りに弄ってみたのが以下のスクリプト。

#!/usr/bin/ruby

require 'open-uri'
require 'csv'
require 'json'

uri = "http://#{URL}/haproxy?stats;csv"

open(uri) do |f|
  row = []
  f.each do |line|

    # # で始まる行をヘッダとする条件
    if line =~ /^# /
      # 行の 2 バイト目から最後までをカンマ区切りで変数(配列)格納
      HEADER = line[2..-1].split(',')
      # # 以外の行はつぎのループに => CSV のパース処理に
      next
    elsif ! defined? HEADER
      puts "ERROR: CSV header is missing"
    end

    # CSV をパースしてハッシュ化して配列に突っ込む(ここの処理についてはもう少し勉強せにゃあかん)
    row << HEADER.zip(CSV.parse(line)[0]).reduce({}) { |hash, val| hash.merge({val[0] => val[1]}) }

  end
  puts JSON.generate(row)
end

以下のように実行すると…

ruby check_haproxy_json.rb | python -m json.tool

一応、JSON で statistics な情報が返却される。

 [
    {
        "n": null,
        "act": null,
        "bck": null,
        "bin": "78",
        "bout": "250726",
        "check_code": null,
        "check_duration": null,
        "check_status": null,
        "chkdown": null,
        "chkfail": null,
        "cli_abrt": null,
        "comp_byp": "0",
        "comp_in": "0",
        "comp_out": "0",
        "comp_rsp": "0",
        "ctime": null,
        "downtime": null,
        "dreq": "0",
        "dresp": "0",
        "econ": null,
        "ereq": "1340",
        "eresp": null,
        "hanafail": null,
        "hrsp_1xx": "0",
        "hrsp_2xx": "1",
        "hrsp_3xx": "0",
        "hrsp_4xx": "1340",
        "hrsp_5xx": "0",
        "hrsp_other": "0",
        "iid": "2",
        "last_agt": null,
        "last_chk": null,
        "lastchg": null,
        "lastsess": null,
        "lbtot": null,
        "pid": "1",
        "pxname": "balancer-test01",
        "qcur": null,
        "qlimit": null,
        "qmax": null,
        "qtime": null,
        "rate": "0",
        "rate_lim": "0",
        "rate_max": "1",
        "req_rate": "0",
        "req_rate_max": "1",
        "req_tot": "1341",
        "rtime": null,
        "scur": "2",
        "sid": "0",
        "slim": "2000",
        "smax": "3",
        "srv_abrt": null,
        "status": "OPEN",
        "stot": "1343",
        "svname": "FRONTEND",
        "throttle": null,
        "tracked": null,
        "ttime": null,
        "type": "0",
        "weight": null,
        "wredis": null,
        "wretr": null
    },
    {
        "n": null,
        "act": null,
        "bck": null,
        "bin": "81",
        "bout": "146",
        "check_code": null,
        "check_duration": null,
        "check_status": null,
        "chkdown": null,
        "chkfail": null,
        "cli_abrt": null,
        "comp_byp": "0",
        "comp_in": "0",
        "comp_out": "0",
        "comp_rsp": "0",
        "ctime": null,

(snip)

        "throttle": null,
        "tracked": null,
        "ttime": "15",
        "type": "1",
        "weight": "0",
        "wredis": "0",
        "wretr": "0"
    }
]

おお。

ということで

誰得か判りませんが、そもそも HAProxy で CSV だけでなく JSON で提供してくれると嬉しいのですが…。

元記事はこちらです。
Ruby で csv to json(HAProxy の CSV で提供される statistics な情報を JSON で取得したいな)