こんにちは!オブザーバビリティの世界へようこそ。
システム運用をしていると、夜中に突然鳴り響くアラートで起こされ、ログやグラフを見てみたら「なんだ、ただの毎週月曜恒例のバッチ処理の負荷じゃないか……」と、冷や汗と徒労感に包まれた経験はありませんか?
固定のしきい値(例えば「CPU使用率が85%を超えたらアラート」)は、平日の昼間には有効でも、曜日や時間帯によってトラフィックが激しく変動する現代のWebサービスやクラウド環境の前では、あまりに無力です。深夜の静かな時間帯の85%は大問題なのに、月曜朝のピーク時の85%は正常稼働の証だったりする。これでは、本当に検知すべき異常を見逃すか、無駄なアラート対応に追われるかの二者択一になってしまいます。
今回は、Zabbixの秘儀とも言える「トレンド関数(`trendavg`, `trendmax`)」と「time()マクロ」を駆使し、過去のデータから「今の正常」を自動で算出して動的にアラートを制御する、極上のトリガー式設計術を伝授します。
これをマスターすれば、深夜の無駄なアラートに悩まされる日々とはお別れです。一緒に、スマートでノイズのない監視の世界へ足を踏み入れましょう!
—
1. Zabbixの役割と「トレンド関数」の真価
そもそもZabbixは、単に「データを集めてグラフにするツール」ではありません。集めた時系列データを長期保存し、数学的なアプローチで「今、システムで何が起きているか」を判定する強力なエンジンです。
Zabbixのトリガー関数には、直近の数分間を見る関数(`last()`, `avg()`など)のほかに、過去の長期トレンドデータを参照する関数が用意されています。
- `trendavg(period, time_shift)`: 指定した期間の平均値(DBに蓄積された1時間ごとの集計データ)を取得します。
- `trendmax(period, time_shift)`: 指定した期間の最大値を取得します。
ここで重要なのが `time_shift`(時間シフト) です。これを使うと、「ちょうど1週間前の同じ曜日、同じ時間帯のデータ」を簡単に引きずり出すことができます。
つまり、「先週の月曜日のこの時間はCPUが平均して70%使われていたから、今日のこの時間も70%前後なら正常」という、季節性・曜日を考慮した動的なしきい値が作れるのです。
—
2. 【基礎セットアップ】動的アラートの土台を作る
高度な数式を書く前に、Zabbixがしっかりと過去のトレンドデータを保持できる状態になっているか確認しましょう。Zabbixは、古いデータを細かい粒度(1分ごとなど)から、集約されたトレンドデータ(1時間ごとなど)へ変換して長期保存します。
ステップ①:ヒストリとトレンドの保存期間の確認
「設定」>「アイテム」から、対象のアイテム(例: `CPU utilization`)を開き、「データ保存期間」を確認してください。
- ヒストリの保存期間: 例: `7d`(直近7日間の詳細データ)
- トレンドの保存期間: 例: `365d`(過去1年間の傾向データ)
トレンド関数は、この「トレンドの保存期間」に蓄積されたデータを参照して動作します。ここが短すぎると過去比較ができないので、最低でも数週間〜1年以上のトレンド保存を推奨します。
—
3. 【HelloWorld的実践】先週の自分と比較するトリガー式
それでは、実際に「先週の同じ曜日の平均値よりも、現在値が50%以上跳ね上がっていたら異常検知する」という、実用的なトリガー式を作ってみましょう。
トリガー式の構築
対象アイテム:`system.cpu.util[,user]` (CPU使用率)
以下の式をトリガーの「条件式」に設定します。
last(/Linux host/system.cpu.util[,user]) > (trendavg(/Linux host/system.cpu.util[,user], 1h, “now-1w”) 1.5)
この数式の解剖(ここが重要です!)
1. `last(…)`: 現在のCPU使用率を取得します。
2. `trendavg(…, 1h, “now-1w”)`: 「今からちょうど1週間前(now-1w)の、前後1時間(1h)の平均CPU使用率」を取得します。
3. ` 1.5`: 先週の平均値に対して、50%増しの余裕を持たせています。
4. `>`: 現在値がその基準を超えていれば、「障害(Problem)」と判定します。
これで、「月曜の朝は混むものだから高くて当然、でもその平常運転のラインからさらに50%跳ね上がったら異常」という、人間の感覚に近いスマートな検知が可能になります。
—
4. 応用編:深夜帯の誤検知を完全にゼロにする `time()` マクロの組み合わせ
さらに精度を上げるために、`time()` マクロを組み合わせましょう。
例えば、「昼間なら多少の変動は許容するが、トラフィックがほぼないはずの深夜(深夜2時〜朝4時)に、普段と違う動きがあった場合は即座に検知したい」といった場合です。
以下のトリガー式を見てください。
time() >= 020000 and time() <= 040000 and last(/Linux host/system.cpu.util[,user]) > (trendavg(/Linux host/system.cpu.util[,user], 1h, “now-1w”) + 10)
- `time() >= 020000 and time() <= 040000`: 深夜2時〜4時の間だけこのトリガーを有効化します。
- `… + 10`: 深夜帯はベースの負荷が低いため、割合(何倍)ではなく、絶対値のプラスアルファ(先週の平均+10%)で厳しく監視します。
このように時間帯によって判定ロジックを切り替えることで、監視の精度は劇的に跳ね上がります。
—
5. 先輩エンジニアからのアドバイス:導入時の注意点
トレンド関数を使う上で、一つだけ注意すべき罠があります。それは「データがまだ蓄積されていない初期段階」の挙動です。
運用を始めたばかりのホストや、新しく追加したアイテムに対してこのトリガーを設定すると、1週間前のデータ(`now-1w`)が存在しないため、関数が評価できず、トリガー自体が「不明(Unknown)」状態になることがあります。
対策:
新しく監視を始めるサーバーの場合は、まずは通常の固定しきい値で数週間運用し、十分なトレンドデータがDBに蓄積されたことを確認してから、今回紹介したトレンド関数入りのトリガーに切り替えるのが、最も安全で確実な手順です。
—
まとめ
固定のしきい値に縛られた監視から卒業し、Zabbixのトレンド関数(`trendavg` / `trendmax`)や `time()` マクロを使いこなせるようになると、監視設計の引き出しが一気に広がります。
「なぜアラートが鳴ったのか」を誰もが納得できるロジックで説明できるようになり、無駄なアラート対応のストレスから解放されるだけでなく、真のインシデントだけを素早くキャッチできる美しいオブザーバビリティ環境が手に入ります。
これをマスターすれば、毎日の運用作業が劇的に楽になりますよ。ぜひ、次のメンテナンスのタイミングであなたのZabbix環境に取り入れてみてください!