【Kibana】Canvasの表現構文で時刻を操作する

今回は、KibanaのCanvasについてです。

Canvasではグラフや図形などを組み合わせた様々な表現方法でプレゼンテーションができます。

基本的にはElasticsearchのデータをそのまま可視化することが多いかと思いますが、時には少し凝ったロジックを使った表現もしたいと思います。

そんな時によく使うのが、時間を使ったデータの取得ではないでしょうか。

今回は、Canvasの表現構文で時刻の操作方法を紹介してきたいと思います。

表現構文について

canvasではそれぞれのグラフや図といった要素について、直感的に操作できるインタフェースが用意されています。

しかし、その操作だけでは、実現できることが限られてしまいます。

そこで用いるのが表現構文と呼ばれるものです。

表現構文は、画面右下の表現エディタを展開した中に記述します。独自の記述方法ではありますが、ある程度のカスタマイズやデータの加工ができます。これを使うことで、canvasの使い方の可能性が広がります。

マークダウンとして現在時刻を表示する

まずは、マークダウンとして現在時刻を表示してみます。

公式ドキュメントにあるサンプルを実行してみます。

date
| formatdate "LLL"
| markdown {context}
  font={font family="Arial, sans-serif" size=30 align="left"
    color="#000000"
    weight="normal"
    underline=false
    italic=false}
| render
サンプルの実行結果

formatを”LLL”とすると、上記のような形式で現在時刻を取得します。このformatはMoment.jsのフォーマットのようです。

formatを”LLLL”とすると、以下のようになります。

"LLLL"の実行結果

ちなみに、年だけや月だけといったように、好きなように時刻を取り出すことができます。

以下の公式ドキュメントが一番わかりやすいと思います。英語ですが、表なので簡単に理解できるはずです。

https://momentjs.com/docs/#/displaying/

タイムゾーンの問題

Elastic Stackの特徴として、UTCが基本になっているという点があります。

Canvasも例外ではありません。特に指定しなければ、UTCで表示されてしまいます。つまり、日本時間から9時間遅れて表示されるのです。

上記の写真も、日本時間でみると9時間遅れた時間が表示されています。

見た感じ、タイムゾーンを修正する方法はなさそう?なので、どのタイムゾーンの時刻かを表示するくらいしかなさそうです、、

essqlでのタイムゾーン

Canvasではessqlを使えますが、そこでもタイムゾーン問題が生じます。

例えば、時刻を条件にデータを抽出する場合などです。

以下のような構文を考えます。

filters
| essql 
  query="SELECT * FROM \"kibana_sample_data_flights*\" where \"timestamp\" < now()"
| pointseries x="time" y="mean(price)"
| plot defaultStyle={seriesStyle lines=1 fill=1}
| render

このとき、essqlのクエリでは、現在時刻未満のレコードを取得するように指定しています。

しかし、このままではUTCでの現在時刻未満のレコードを取得してしまいます。つまり、ここでも9時間のラグが発生してしまうのです。

essqlのタイムゾーンは指定できる

さすがにクエリでタイムラグが生じると困るので、こちらではタイムゾーンの指定ができます。

以下のようにします。

filters
| essql 
  query="SELECT * FROM \"kibana_sample_data_flights*\" where \"timestamp\" < now()" <span class="red">timezone="UTC+9" </span>
| pointseries x="time" y="mean(price)"
| plot defaultStyle={seriesStyle lines=1 fill=1}
| render

timezoneを”UTC+9″とすることで、SQL中のnow()が日本時間基準になります。

まとめ

Canvasでの時刻の扱い方を見てきました。

私自身、タイムゾーンの扱いには特に悩んだので、同じ悩みを持つ方の参考になれば幸いです。

ではでは👋