2025年9月21日日曜日

ElastAlert2 を使ってみる

ElastAlert2 を使ってみる

概要

前回ES9をdockerで構築しました
今回は ElastAlert2 を組み合わせて特定のログがES9に格納されたらアラートされる仕組みを作成してみます

環境

  • macOS 15.6.1
  • docker 28.4.0
    • ElasticSearch 9.0.7
    • Kibana 9.0.7
    • fluentd 1.19-1
    • ElastAlert 2.26.0

elastalert.yaml

EalstAlert2 共通の設定を作成します
接続する ElasticSearch9 の設定やルールを管理するディレクトリを指定します

  • vim elastalert.yaml
rules_folder: /opt/elastalert/rules

run_every:
  seconds: 10

buffer_time:
  minutes: 15

es_host: 192.168.1.152
es_port: 9200
use_ssl: true
verify_certs: false
es_username: elastic
es_password: xxx

writeback_index: elastalert_status

alert_time_limit:
  days: 2

rules/test_alert.yaml

とりあえずテスト用のアラートファイルを作成します
今回は必ずアラートが上がるように @timestmp フィールドを監視し5分間の間に2回レコードが格納された場合にアラートが上がるようにします

  • mkdir rules
  • rules/test_alert.yaml
name: "test_alert"
type: "frequency"
index: "fluentd*"
is_enabled: true
num_events: 2
realert:
  minutes: 5
terms_size: 50
timeframe:
  minutes: 5
timestamp_field: "@timestamp"
timestamp_type: "iso"
use_strftime_index: false
alert_subject: "Test {} 123 aa☃"
alert_subject_args:
  - "log"
alert_text: "Test {}  123 bb☃"
alert_text_args:
  - "source"
filter:
  - query:
      query_string:
        query: "@timestamp:*"
alert:
  - "slack"
slack_webhook_url: 'https://hooks.slack.com/services/xxx'
slack_channel_override: "#private"
slack_emoji_override: ":kissing_cat:"
slack_msg_color: "warning"
slack_parse_override: "none"
slack_username_override: "elastalert"

各種項目の説明

ルールの基本

name: "test_alert"
ルールの名前。Slack 通知などに出てくる。

type: "frequency"
「一定時間内に指定した件数以上のイベントがあるとアラートを出す」というタイプ。

index: "fluentd"
監視対象の Elasticsearch インデックス名。

is_enabled: true
このルールが有効になっている。

発火条件

num_events: 2
  イベント件数のしきい値。

timeframe: minutes: 5
  評価対象の時間範囲。
  → 「5分間に2件以上あればアラート」

realert: minutes: 5
  一度アラートが出た後、同じ条件で再度アラートを出すまでのクールダウン時間。
  → 5分間は抑止する。

terms_size: 50
  集計クエリのサイズ。frequency ルールでは多くの場合デフォルトでOK。

タイムスタンプ関連

timestamp_field: "@timestamp"
  イベントの時刻として使う Elasticsearch のフィールド。

timestamp_type: "iso"
  日時フォーマットの種類。ISO 8601 形式。

use_strftime_index: false
  インデックス名に日付を埋め込まない(例: fluentd-%Y.%m.%d ではなく fluentd 固定)。

通知メッセージ

alert_subject: "Test {} 123 aa☃"
  Slack の件名やタイトル部分に使うテンプレート。
  {} に alert_subject_args のフィールドが入る。

alert_subject_args: "log"
  → log フィールドの値が {} に挿入。

alert_text: "Test {} 123 bb☃"
  本文テンプレート。
  {} に alert_text_args のフィールドが入る。

alert_text_args: "log"
  → log フィールドの値が {} に挿入。

検索条件

filter:
  単純に @timestamp フィールドが存在する全ログを対象にする。
  実質「全件」になる。

ElastAlert2 コンテナの起動

ではコンテナを起動します
ホスト側に作成した各種設定ファイルがちゃんとコンテナにマウントされるようにしましょう

  • docker run -d --name elastalert --restart=always -v $(pwd)/elastalert.yaml:/opt/elastalert/config.yaml -v $(pwd)/rules:/opt/elastalert/rules jertel/elastalert2 --verbose

ログを見ると

Background alerts thread 0 pending alerts sent at 2025-09-17 23:35 UTCINFO:elastalert:1 rules loaded

でルールが有効になっていることが確認できます
また以下のログがあれば Slack に通知できているログになります

INFO:elastalert:Ran test_alert from 2025-09-17 23:54 UTC to 2025-09-17 23:55 UTC: 2 query hits (0 already seen), 1 matches, 1 alerts sent

動作確認

5分間待って Slack に通知が来ることを確認しましょう

以下のように変数部分が <MISSING VALUE> になる場合は ES9 上に指定のフィールドが存在するか確認してください

おまけ: 事前にルールファイルの確認をする

  • docker run --entrypoint "" --rm -v $(pwd)/elastalert.yaml:/opt/elastalert/config.yaml -v $(pwd)/rules:/opt/elastalert/rules jertel/elastalert2 elastalert-test-rule /opt/elastalert/rules/test_alert.yaml

最後に

ES9 と ElastAlert2 を連携させて特定のログが出た場合に Slack に通知する仕組みを試してみました
基本的には filter や timeframe などの監視条件をいろいろ変更してログ監視ルールを作成していく感じになります

また今回の構成だと rules ディレクトリにルールファイルをどんどん追加していく感じになりますが追加したルールファイルが1つでも壊れている(YAML構文エラーや必須のディレクティブが定義されていないなどがある)と ElastAlert2 自体が起動しないので注意してください

今回紹介した機能以外にもたくさんの機能があるので興味があれば参考サイトから公式のドキュメントを参照してみてください

参考サイト

0 件のコメント:

コメントを投稿