最近、大ブームなFluentd+GrowthForecastを試し始めました!
で、サクッと『GrowthForecastで複合グラフ作ったりグラフいじったりするの┌┤´д`├┐ダル〜』となりました。
なんとかサボれないかなーとソースを眺めていたら、JSON APIっぽいものがあるのに気づきました。
GrowthForecast:Web.pm
@tagomorisさんが最近コミットしたようです。
add json api to get/list/edit graph and complex, and to create complex
それっぽいURL叩くとJSONが返ってくる!
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/list/graph
[{"service_name"=>"test","graph_name"=>"percentile_95","section_name"=>"access","id"=>88},{"service_name"=>"test","graph_name"=>"avg","section_name"=>"access","id"=>87},{"service_name"=>"test","graph_name"=>"5xx_count","section_name"=>"access","id"=>86},...
というわけでザクっとひと通り使ってみました。
/json/list/graph:グラフのリストを取得
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/list/graph | ruby -r json -r pp -e 'pp JSON.parse(ARGF.read)'
...
{"service_name"=>"test",
"graph_name"=>"3xx_count",
"section_name"=>"access",
"id"=>80},
{"service_name"=>"test",
"graph_name"=>"2xx_count",
"section_name"=>"access",
"id"=>78},
...
パス情報とIDだけが返ってくるようです。
/json/graph/:グラフの詳細情報を取得
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/graph/78 | ruby -r json -r pp -e 'pp JSON.parse(ARGF.read)'
{"llimit"=>-1000000000,
"number"=>0,
"stype"=>"AREA",
"mode"=>"gauge",
"complex"=>false,
"adjustval"=>"1",
"created_at"=>"2012/12/26 12:05:35",
"color"=>"#99cc33",
"service_name"=>"test",
"gmode"=>"gauge",
"ulimit"=>1000000000,
"section_name"=>"access",
"id"=>78,
"graph_name"=>"2xx_count",
"description"=>"",
"sort"=>0,
"unit"=>"",
"sulimit"=>100000,
"updated_at"=>"2012/12/26 15:16:07",
"adjust"=>"*",
"sllimit"=>-100000,
"type"=>"AREA"}
かなりいろんな情報があります。また今度調べてみよう
このAPIの出力は、/api///とほぼ同じなので、状況によって使い分けるのがよさげですね。
/json/list/complex:複合グラフのリストを取得
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/list/complex | ruby -r json -r pp -e 'pp JSON.parse(ARGF.read)'
...
{"service_name"=>"test",
"graph_name"=>"response_time",
"section_name"=>"access",
"id"=>7},
{"service_name"=>"test",
"graph_name"=>"access_status",
"section_name"=>"access",
"id"=>44},
...
/json/list/graphと同じですね。
/json/complex/:複合グラフの詳細情報を取得
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/complex/44 | ruby -r json -r pp -e 'pp JSON.parse(ARGF.read)'
{"number"=>0,
"complex"=>true,
"created_at"=>"2012/12/30 03:30:55",
"service_name"=>"test",
"section_name"=>"access",
"id"=>44,
"graph_name"=>"access_status",
"data"=>
[{"gmode"=>"gauge", "stack"=>false, "type"=>"AREA", "graph_id"=>78},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>80},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>83},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>86}],
"sumup"=>false,
"description"=>"アクセス数(レスポンスコード)",
"sort"=>10,
"updated_at"=>"2012/12/30 03:30:55"}
こっちはわかりやすいですね。
/json/list/all:全グラフ、複合グラフの詳細情報を取得
[mikeda@fluentd01 api]$ curl -s http://localhost:5125/json/list/all | ruby -r json -r pp -e 'pp JSON.parse(ARGF.read)'
...
{"number"=>0,
"llimit"=>-1000000000,
"mode"=>"gauge",
"stype"=>"AREA",
"complex"=>false,
"adjustval"=>"1",
"service_name"=>"test",
"created_at"=>"2012/12/26 12:05:35",
"gmode"=>"gauge",
"color"=>"#99cc33",
"section_name"=>"access",
"ulimit"=>1000000000,
"id"=>78,
"graph_name"=>"2xx_count",
"description"=>"",
"sort"=>0,
"unit"=>"",
"sulimit"=>100000,
"updated_at"=>"2012/12/26 15:16:07",
"adjust"=>"*",
"type"=>"AREA",
"sllimit"=>-100000},
...
{"number"=>0,
"complex"=>true,
"created_at"=>"2012/12/19 09:43:37",
"service_name"=>"test",
"section_name"=>"dev04",
"id"=>1,
"graph_name"=>"access",
"data"=>
[{"gmode"=>"gauge", "stack"=>false, "type"=>"AREA", "graph_id"=>"2"},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>"3"},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>"4"},
{"gmode"=>"gauge", "stack"=>true, "type"=>"AREA", "graph_id"=>"5"}],
"sumup"=>false,
"description"=>"アクセス数",
"sort"=>19,
"updated_at"=>"2012/12/19 09:43:37"}]
豪快ダンプですね。通常のグラフか複合グラフ化はcomplexフラグで判別するようです。
/json/create/complex:複合グラフを作成
助かった!とばかりに全サービスに特定の複合グラフを作るスクリプトを作りました。
https://gist.github.com/4406576
ちょっと個人的な用途向けすぎなので、もうちょっとベーシックなサンプルを書いてみました。
#!/usr/lib64/fluent/ruby/bin/ruby
require 'net/http'
require 'json'
require 'pp'
GF_HOST = 'localhost'
GF_PORT = 5125
from_graphs= [
{:path => 'test/access/2xx_count', :gmode => 'gauge', :stack => true, :type => 'AREA'},
{:path => 'test/access/3xx_count', :gmode => 'gauge', :stack => true, :type => 'AREA'},
{:path => 'test/access/4xx_count', :gmode => 'gauge', :stack => true, :type => 'AREA'},
{:path => 'test/access/5xx_count', :gmode => 'gauge', :stack => true, :type => 'AREA'},
]
to_complex = {
:path => 'test/access/access_status',
:description => 'アクセス数(レスポンスコード)',
:sort => 10,
}
def api_get(path)
json = ''
Net::HTTP.start(GF_HOST, GF_PORT) do |http|
res = http.get(path)
json = res.body
end
JSON.parse(json)
end
def api_post(path, data)
json = JSON.generate(data)
Net::HTTP.start(GF_HOST, GF_PORT) do |http|
res = http.post(path, json)
pp res.body
end
end
all_graphs = api_get('/json/list/graph')
graph_data = []
from_graphs.each do |from_graph|
service, section, graph = from_graph[:path].split('/')
graph_id = all_graphs.detect{|g|
g['service_name'] == service &&
g['section_name'] == section &&
g['graph_name'] == graph
}['id']
graph_data << {
:gmode => from_graph[:gmode],
:stack => from_graph[:stack],
:type => from_graph[:type],
:graph_id => graph_id
}
end
to_service, to_section, to_graph = to_complex[:path].split('/')
post_params = {
:service_name => to_service,
:section_name => to_section,
:graph_name => to_graph,
:description => to_complex[:description],
:sort => to_complex[:sort],
:data => graph_data
}
pp post_params
api_post('/json/create/complex', post_params)
できた!!!
/json/edit/graph/:グラフの設定を変更
これもサンプルを。
同じグラフなのに、サービスごとに色がバラバラだと見づらいですよね。
作成時に指定しないとランダムになるっぽいです。
...
my @colors = List::Util::shuffle(qw/33 66 99 cc/);
$color ||= '#' . join('', splice(@colors,0,3));
...
とりあえず上のグラフの色を、こんな感じに変更してみましょう!
- 2xx_count:青
- 3xx_count:緑
- 4xx_count:黄色
- 5xx_count:赤
require 'net/http'
require 'json'
require 'pp'
GF_HOST = 'localhost'
GF_PORT = 5125
SERVICE_NAME = 'test'
SECTION_NAME = 'access'
GRAPH_COLORS = {
'2xx_count' => '#1111cc',
'3xx_count' => '#11cc11',
'4xx_count' => '#cccc11',
'5xx_count' => '#cc1111',
}
def api_get(path)
json = ''
Net::HTTP.start(GF_HOST, GF_PORT) do |http|
res = http.get(path)
json = res.body
end
JSON.parse(json)
end
def api_post(path, data)
json = JSON.generate(data)
Net::HTTP.start(GF_HOST, GF_PORT) do |http|
res = http.post(path, json)
pp res.body
end
end
GRAPH_COLORS.each do |graph_name, color|
path = [SERVICE_NAME, SECTION_NAME, graph_name].join("/")
graph_data = api_get("/api/#{path}")
%w[number adjust adjustval meta md5 created_at updated_at data unit mode].each{|key|
graph_data.delete(key)
}
graph_data['color'] = color
pp graph_data
api_post("/json/edit/graph/#{graph_data['id']}", graph_data)
end
でけた!!!
/json/edit/complex/:複合グラフの設定を変更
上と似たようなもんなので割愛!!!
まとめ?
だいぶ手が抜けそうで安心しました!
他にもRRDの設定やデータをダンプするAPIなどなどもあるっぽいです。
また気がついたことあったら追記/修正していきます!