やりたいこと
前回の話
GrafanaのOverride rerative time機能でelasticsearchのデータを常時表示するためには、
elasticsearchのデータのタイムスタンプを、全データ更新するシェルが必要になる。
ということで今回はその作成記事。
elasticsearchで一括置換するクエリ
下記を参考に一括更新のクエリを調べる。
https://qiita.com/nakazii-co-jp/items/d8dca15e5eab6406ffdb
サイトにあったクエリを少し変えて、Hogeのとこを日時にすればいけると想定。
curl -XPOST 'http://localhost:9200/hoge_index/_update_by_query?conflicts=proceed&pretty' -d '{
"query": {
"match_all": { }
},
"script": {
"inline": "ctx._source.field_01 = \"Hoge\";"
}
}'
curlに変数をどうやって入れるのか?
$DATEとか作ってdateコマンドの結果を入れるも、jsonのエラーとか出てうまくいかない。
変数がうまく展開されない。
下記を参考にシングルクォートが問題と判明。ヒアドキュメントを使うことにした。
これはいい方法だと思った。
https://qiita.com/tekitoh/items/8acccb313d6e7a14c2ec
https://dev.classmethod.jp/server-side/os/how-to-inject-variable-to-json-on-bash/
ヒアドキュメント使ってもなんかフォーマットエラーが出る。
elasticsearchの日時(date)のフォーマットではまる
細部は違うけど、下記と同じフォーマットエラーが出る。
https://stackoverflow.com/questions/48916830/elasticsearch-date-format-parsing-error
上記から引用したエラー
"type": "mapper_parsing_exception",
"reason": "failed to parse [afield.startDate]",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Invalid format: \"2018-01-10T07:07:07+01:00\" is malformed at \"+01:00\""
}
調べた結果、どうも下記のdateのフォーマットが
elasticsearchの対応パターンになかったためらしい。
下記のフォーマットでlogstashでelasticsearchに問題なく取り込んでいたから中々気づけなかった
date -d "+%Y-%m-%d %H:MM:ss"
公式へのリンク
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html
完成したシェル
いろいろ試行錯誤した結果、下記でうまく@timestampを全データ指定の時間に更新できました。
これをcronで動かして@timestampが直近の1時間になるようにしています。
※'9 hours ago'はelasticsearchのtimezoneを合わせてないので、その分ずらしているため
# !/bin/sh
DATE=`date -d '9 hours ago' "+%Y-%m-%dT%H:00:00.000Z"`
curl -XPOST "localhost:9200/hoge_index/_update_by_query?conflicts=proceed&pretty" -d @- <<EOS
{
"query": { "match_all": {}},
"script": { "inline": "ctx._source['@timestamp'] = ['$DATE'];" }
}
EOS