ealsticsearchにログデータを溜めている場合、そのデータを集計してしきい値超えたらslack通知したいというのは、よくあるユースケースかと思う。
elastalertというツールが流行っていたりすることからも明らかで、自前でツールを作って運用されている方も多いと思う。
自分も、pythonで作ったツールでその機能を実現していたが、elasticsearchのalertingを使って、これまでの処理を置き換えたので、そのメモを残しておく。
Alerting機能とは
elasticsearchに登録するcronのようなもので、indexされているデータに対して、定期的にクエリを実行して通知というような機能を実装する事が出来る
何がうれしいかというと
- cronを実行する為のサーバが不要(サーバレス)
- 簡単なjsonを書くだけで、自前でコードを書きメンテナンスしていく必要がない
※elasticcloudの32GBプラン以下だと無償で使える
※通常は、x-packというelasticsearchの有償プラグインにバンドルされている機能
Alertingを書くにあたり理解すべき構成要素
elasticsearchのalerting機能は下記の4要素を組み合わせて作られる。比較的わかりやすい構造になっている。
input:
elasticsearchに投げるクエリを定義する
triggers:
スケジューラの機能
conditions
inputの出力からactionsを動かす条件を定義
actions
conditionsにマッチした場合のアクション
※slack通知とか何かのクエリを発行するとか
サンプルを動かしてみる
テーマ: 適当に作ったテストINDEXに対してクエリを発行して閾値を超えたらslack通知する
サンプルデータ
id,level,datetimeの3フィールドを持つシンプルなインデックスを作った。
"hits": [
{
"_index": "test_nagai1",
"_type": "test1",
"_id": "AVuKaxAdGdCIUEfpcX22",
"_score": 1,
"_source": {
"id": "nagais",
"level": "INFO",
"datetime": "2017-04-20T16:11:02+09:00"
}
},
{
"_index": "test_nagai1",
"_type": "test1",
"_id": "AVuKaty4GdCIUEfpcX2x",
"_score": 1,
"_source": {
"id": "nagais",
"level": "ERROR",
"datetime": "2017-04-20T17:11:01+09:00"
}
},
{
"_index": "test_nagai1",
"_type": "test1",
"_id": "AVuKaud8GdCIUEfpcX2y",
"_score": 1,
"_source": {
"id": "nagais",
"level": "ERROR",
"datetime": "2017-04-20T17:11:02+09:00"
}
}。。。
サンプルジョブ
仕組み
-
_xpack/watcher/watch/
にJSON形式でジョブを登録する形 - deleteするとジョブは止まる。
DELETE _xpack/watcher/watch/errorlog_notify
PUT _xpack/watcher/watch/errorlog_notify
{
"trigger": { #30秒間隔
"schedule": {
"interval": "30s"
}
},
"input": { #1分以内でlevelフィールドがERRORかFATALのもの
"search": {
"request": {
"indices": [
"test_nagai1"
],
"body": {
"query": {
"bool": {
"must": [
{
"range": {
"datetime": {
"gte": "now-1m",
"lte": "now"
}
}
},
{
"regexp": {
"level": "(ERROR|FATAL)"
}
}
]
}
}
}
}
}
},
"condition": { # 検索結果が1件以上のもの
"compare": {
"ctx.payload.hits.total": {
"gte": 1
}
}
},
"actions": { #slack通知のプロファイル(icon_emojiはサポートされてなかった様子💧)
"notify-slack": {
"slack": {
"message": {
"from": "ESwatcher",
"to": [ #ここでチャンネルを指定
"#elastic_alerting_test"
],
"text": "EScloud error log watcher",
"attachments": [
{
"title": "Loglevel Error",
"text": "loglevel error too many\nerror_count: {{ctx.payload.hits.total}}",
"color": "danger"
}
]
}
}
}
}
}
結果
こんな感じで通知が来ます。
ジョブ履歴を確認
過去1分以内のジョブを確認するみたいなのはこんな感じで!
GET .watcher-history*/_search
{
"query" : {
"bool" : {
"must" : [
{ "range" : { "result.execution_time" : { "from" : "now-1m" }}}
]
}
}
}
参照
所感
動かす環境準備して、pythonでelasticsearchのクライアント使ってデータ引いてきて、加工して、slackクライアントで通知してみたいな処理
↓
JSON書いてelasticsearchに登録して完了
かなり省力化出来るので、使える環境にある人は積極的に使っていった方がいいと思った。