Kibanaのダッシュボード設定を動的生成してみる

投稿者: | 2014年2月21日

インフラ担当の池田(@mikeda)です。

最近、Kibanaでアクセスログの可視化をやってみてるのですが、手でダッシュボードいじるのがダルいです。
例えばうちの場合はサーバクラスタ、顧客アカウントごとのアクセスを見たい場合が多く、その条件を毎回指定するのがめんどくさい。
ここを動的に生成できないかな、と思って調べてみました。

イメージとしては、
内部管理画面にクラスタ/顧客アカウントの一覧があるのでそこにKibanaのリンクを設置して、
kibana_config_01

クリックすると適切に設定されたKibanaに飛ぶ、
kibana_config_02
という感じです。

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で共有する場合も基本的に同じ仕組です
kibana_config_03

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

Kibanaのダッシュボード設定を動的生成してみる」への1件のフィードバック

  1. 通りすがりの運用者

    基本共通のdashboardを使っていて、いくつかのfilter等の設定値を動的に変えたいだけであれば、kibanaのdashborad(json)はARGS.hogeで、URL(GET)のqueryを取得できるので、1つのdashboardファイル(json)またはelasticsearch(kibana-int)レコードだけで済みますよ。
    たとえばterms filterならこんな感じ(抜粋)

    “type”: “terms”,
    “field”: “cluster”,
    “value”: [“{{ARGS.cluster_name || ‘default.jp’}}”],

    #テンプレートとなるdashboardは書かれている手法でexportしてください。

    呼び出しURLに ?cluster_name=mikeda.jp とすればその値が入り、なにもついてない場合はdefault.jpが設定されます。

    私はこの方法で表示したいログの種別やサーバの切り替えを行ってます。

    #流し読みなのでやりたいこと間違っていたらゴメンナサイ

コメントは停止中です。