インフラ担当の池田(@mikeda)です。
最近、Kibanaでアクセスログの可視化をやってみてるのですが、手でダッシュボードいじるのがダルいです。
例えばうちの場合はサーバクラスタ、顧客アカウントごとのアクセスを見たい場合が多く、その条件を毎回指定するのがめんどくさい。
ここを動的に生成できないかな、と思って調べてみました。
イメージとしては、
内部管理画面にクラスタ/顧客アカウントの一覧があるのでそこにKibanaのリンクを設置して、
クリックすると適切に設定されたKibanaに飛ぶ、
という感じです。
Kibanaのソースコードやドキュメントはぜんぜん読んでないのですが(すませんw)、UIをポチポチ触ってるととりあえず以下の2つの方法でなんとかできそうでした。
- Kibanaサーバに設定ファイル配置
- ElasticSearchに設定突っ込んでリダイレクト
Kibanaサーバに設定ファイル配置
KibanaのconfigはJSONとしてダウンロードしたり、読み込んだりすることができます。
- Save → Export schemaでファイルでダウンロード
- Load → Local Fileで読み込み
このJSONをKibanaサーバ上の
app/dashboards/XXX.json
に配置すれば、
こういうURLでアクセスして読み込むことができそうです。
http://kibana.example.jp/index.html#/dashboard/file/XXX.json
バッチ処理でJSONファイルをまとめて作成すれば、今回の要件は比較的簡単に満たせそうです。
ElasticSearchに設定突っ込んでリダイレクト
KibanaのUI上から『Save』を使って設定を保存すると、固定URLを指定してアクセスできるようになります。
http://kibana.example.jp/index.html#/dashboard/elasticsearch/XXX
※『Load』で指定して読み込むこともできます。
このデータはどこにあるかというと、ElasticSearchのkibana-intというIndexに保存されています。
※『Share』を使って設定を一時URLで共有する場合も基本的に同じ仕組です
JSON形式のコンフィグが入っているdashboardの他、いくつかのフィールドがあります。
というわけで、同じような設定を動的生成してElasticSearchに突っ込んでから、それを指定したKibanaのURLにリダイレクトしてやれば今回の要件は満たせそうです。
例えばRailsだとこんな感じでできます。
class KibanaTestController < ApplicationController
## Kibanaにリダイレクトテスト
def redirect_to_kibana
kibana_config = Kibana::KibanaConfig.new(
'cluster_mikeda.jp',
[
{ "field" => "cluster", "query" => '"mikeda.jp"' }
],
[
{ "alias" => "aaa", "color" => "#7EB26D", "query" => 'access_type:"aaa"' },
{ "alias" => "bbb", "color" => "#EAB839", "query" => 'access_type:"bbb"' },
{ "alias" => "ccc", "color" => "#6ED0E0", "query" => 'access_type:"ccc"' },
{ "alias" => "ddd", "color" => "#E24D42", "query" => 'access_type:"ddd"' },
]
)
kibana_config.save
redirect_to kibana_config.url
end
end
module Kibana
class KibanaConfig
KIBANA_URL = 'http://192.168.1.100/kibana/index.html'
QUERY_DEFAULT = {
"alias" => "",
"pin" => false,
"type" => "lucene"
}
FILTER_DEFAULT = {
"type" => "field",
"mandate" => "must",
"active" => true,
"alias" => "",
}
TIMESAMP_FILTER = {
"type" => "time",
"field" => "@timestamp",
"from" => "now-24h",
"to" => "now",
}
def initialize(title, filters, queries)
@config = default_config
@title = title
set_title(@title)
set_filters([ TIMESAMP_FILTER ] + filters)
set_queries(queries)
end
def set_title(title)
@config['title'] = title
end
def set_filters(filters)
filters.each.with_index do |filter, i|
@config['services']['filter']['list'][i.to_s] = FILTER_DEFAULT.merge(filter)
@config['services']['filter']['ids'] << i
end
end
def set_queries(queries)
queries.each.with_index do |query, i|
@config['services']['query']['list'][i.to_s] = QUERY_DEFAULT.merge(query)
@config['services']['query']['ids'] << i
end
end
def save
es = Elasticsearch::Client.new hosts: Settings.elasticsearch_logstash.hosts
es.index index: 'kibana-int',
type: 'dashboard',
id: @title,
body: {
title: @title,
user: 'guest',
group: 'guest',
dashboard: @config.to_json
}
end
def url
"#{KIBANA_URL}#/dashboard/elasticsearch/#{URI.encode(@title)}"
end
def default_config
JSON.parse(File.read('lib/kibana/cluster_default.json'))
end
end
end
コンフィグはいったん手動でいじって『Export schema』でダウンロード、そこから不要なものを削除したものをデフォルトとしてRails側で調整しています。
// lib/kibana/cluster_default.json
{
"services": {
"query": {
"idQueue": [],
"list": {},
"ids": []
},
"filter": {
"idQueue": [],
"list": {},
"ids": []
}
},
"rows": [
{
"title": "Graph",
"height": "350px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "histogram",
"mode": "count",
"time_field": "@timestamp",
...
"refresh": false
}
ちょっと大げさな感じですが、ファイル生成よりは完全なリアルタイムでコンフィグ生成がやりやすそう。
まとめ
Kibanaのconfigを動的に生成できないかな、と2つの方法を試してみました。
- Kibanaサーバに設定ファイル配置
- ElasticSearchに設定突っ込んでリダイレクト
今のところ『ElasticSearchに突っ込んでリダイレクト』でいこうと思っています。
もっと簡単な方法あればぜひ教えて下さい!