大量アラートを抑止(要件:”規定時間内に規定回数までアラート発砲し、規定回数を超えたらアラート抑制する”、および ”規定時間を経過したらリセットして同じサイクルを回す”)

#課題:Zabbixにおける大量アラートの抑制
Zabbix初心者です。現在、大量アラートを抑制するための運用課題に取り組んでいますが、要件が複雑なため、調査と検証が難航しています。

#要件(実現したいこと)
以下の要件を満たすアラート制御を実現したいと考えています。
なお、ZabbixバージョンはZabbix 6.0.14

1.規定時間内のアラート発報制御:
・「抑止時間」(例:300秒)内に、同一のログメッセージが「規定回数」(例:3回)に達するまでは、ログメッセージが検出されるたびに毎回アラートを発報する。
2.規定回数超過時のアラート抑制:
・「抑止時間」内に、同一のログメッセージの検出回数が「規定回数」を超えた場合、それ以降のアラート発報を抑制する。
例:「抑止時間」300秒、「規定回数」3回の場合、4回目以降の同一ログメッセージ検出ではアラートを発報しない。
3.時間経過後のリセットとアラート再開:
・「抑止時間」が経過したら、アラート発報回数のカウントをリセットし、リセット後に最初に同一のログメッセージが検出された時点から、再度カウントを開始する。
・リセット前のアラート発報回数に関わらず、リセット後の最初のログメッセージ検出を1回目としてカウントを再開し、上記1)からのサイクルを繰り返す。

#現状の課題
・アラート発報対象の同一ログメッセージが短時間に複数行出力されると、ログ出力数と同数のアラートが発報され、運用負荷が増大しています。
・上記要件を満たすトリガー条件の構築に苦戦しています。

#これまでの調査・実施内容
上記要件の実現に向け、既存のトリガー条件に追加する形で以下の関数を組み合わせて検証を行ってきました。

1.find()関数:ログからの特定メッセージ抽出(既存のトリガー条件)
2.count()関数:「抑止時間」内のログメッセージ検出回数をカウントし、「規定回数」超過時のアラート抑制
3.nodata()関数、last()関数など:「抑止時間」経過後のカウントリセットとアラート再開
検証の結果、count()関数による「規定回数」超過時のアラート抑制は実現できましたが、「抑止時間」経過後のリセットとアラート再開(上記3)の制御がうまくいきません。

・nodata()関数などを組み合わせると、30秒ごとにアラート抑制対象のログメッセージが繰り返し出力される、あるいは1回のログ出力で30秒ごとにログメッセージが繰り返し出力されるといった意図しない動作が発生しています。

#質問事項
1.上記要件と類似したアラート制御の事例はありますでしょうか。
2.「抑止時間」経過後のカウントリセットとアラート再開を制御するために、有効な関数やトリガー条件の構築方法についてアドバイスをいただけますでしょうか。

#<参考>
◇これまで試したトリガ条件式(要件実現のためドキュメントや生成AIを駆使して調査したトリガ条件式)
□1つ目のトリガ条件
find(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],,"regexp",".*")=1
and
(count(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],300s,"regexp",".*") <= 3
or
nodata(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],300s)=0)

□2つ目のトリガ条件
find(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],,"regexp",".*")=1
and
(
(count(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],300s,"regexp",".*") <= 3 and nodata(/Job_Template/logrt["/var/log/messages","\.extractionA>|\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE> ","UTF-8",600,skip,,,rotate],300s) = 1)
or
(count(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],300s,"regexp",".*") > 3 and nodata(/Job_Template/logrt["/var/log/messages","\.extractionA>|\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE> ","UTF-8",600,skip,,,rotate],300s) = 0)
)

□3つ目のトリガ条件
find(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],,"regexp",".*")=1
and
(
(count(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE>","UTF-8",600,skip,,,rotate],300s,"regexp",".*")<=3)
or
(last(/Job_Template/logrt["/var/log/messages","\.extractionA> |\.extractionB> |\.extractionTEST1> |\.extractionD> |\.extractionE> ","UTF-8",600,skip,,,rotate])=0 and (now()-time())>300)
)

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー batica の写真

ご質問に対する直接な回答ではないこと、ご容赦ください。
nodata関数は30秒ごとに再計算されます。

nodata()関数などを組み合わせると、30秒ごとにアラート抑制対象のログメッセージが繰り返し出力される、あるいは1回のログ出力で30秒ごとにログメッセージが繰り返し出力される

⇒こちらの事象は、nodata関数が30秒ごとに再計算されていることに起因するのでは、と考えられます。

【参考資料】
https://www.zabbix.com/documentation/6.0/en/manual/config/triggers

Date and time and/or nodata() functions are recalculated every 30 seconds by the Zabbix history syncer process.

ユーザー RyusakuFUTORI の写真

batica様
 ご助言ありがとうございます。
 参考にさせて頂きます。