読者です 読者をやめる 読者になる 読者になる

nmtysh.log

Tech系のネタや日々の独り言などを書いています。

Zabbixで特定のキーワードを除くログ出力を検知する

Webサーバーのアクセスログでサーバーエラーの5xxのレスポンスが発生したことを検知したいのですが、
無視したいリクエストもあります。

色々試行錯誤したので、備忘録的に。

ログの収集

アイテムを作成してログを収集します。
詳細はマニュアルを見てください。
ローテートされるログにも対応してます。

log[/var/log/nginx/access_log, "\" 5[0-9]{2} "]

アクセスログすべてを収集すると件数が多くて大変なので、レスポンスコードが5xxのログのみ収集します。

トリガーの設定

検知したい条件

まず、検知したいログ条件をはっきりさせます。

  • 30秒以内の間に5xx系のログが出力された
  • ただし、sitemap.xmlへのアクセスは対象外とする

これを元にトリガーの条件を組み合わせます。

ログの収集時点で5xx系のみに絞っていますので、
全体のログ件数が除外したいsitemap.xmlが含まれるログ件数よりも多ければ、
異常があったと判断してよいかと思います。

5xx系ログ件数のカウント

{web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30)}

除外したいsitemap.xmlが含まれるログ件数のカウント

{web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30, "sitemap.xml")}

2つを合わせる

{web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30)} > {web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30, "sitemap.xml")}

これで良さそうにも見えます。

試してみると、異常検知はできるのですが、5xx系のログが最後に出力されてから30秒を経過しても正常状態へ復帰しません。
なので条件を追加します。

30秒間5xx系のログがでなければ復帰させる

{web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30)} > {web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].count(30, "sitemap.xml")} and {web:log[/var/log/nginx/access_log, "\" 5[0-9]{2} "].nodata(30)} = 0

.nodata() で30秒間ログの出力が無ければ、条件式が偽になるようにして、正常状態へ復帰したと判定させます。

関連