インフラ担当の池田(@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に突っ込んでリダイレクト』でいこうと思っています。
もっと簡単な方法あればぜひ教えて下さい!