【New Relic】アラート戦略を考える

本記事は[New Relic Advent Calendar 2024](https://qiita.com/advent-calendar/2024/newrelic)のシリーズ1、8日目の記事です。


## 目次
- [はじめに](#はじめに)
  - [なぜアラート戦略を考えることが重要なのか](#なぜアラート戦略を考えることが重要なのか)
- [良いアラートとは](#良いアラートとは)
  - [アラートの目的](#アラートの目的)
  - [よくある運用上の問題](#よくある運用上の問題)
  - [良いアラートの条件](#良いアラートの条件)
- [良いアラートを作成するための戦術](#良いアラートを作成するための戦術)
  - [悪影響の時間を抑えるために](#悪影響の時間を抑えるために)
  - [形骸化させないために](#形骸化させないために)
- [New Relicにおける実践](#new-relicにおける実践)
  - [Runbookの登録](#runbookの登録)
  - [Workflows・Destinationsによる通知先の分離](#workflows・destinationsによる通知先の分離)
  - [Synthetic Monitoringによる複雑なアラートの作成](#synthetic-monitoringによる複雑なアラートの作成)
- [まとめ](#まとめ)
- [参考](#参考)

## はじめに
[エン・ジャパン](https://x.com/enjapan)で働いている、バックエンドエンジニアの[中谷](https://x.com/t__nakatani)と申します。

業務でアラートを作成する中で理解したこと・思索したことを共有したく、記事を書くことにしました。

本記事は New Relic Advent Calendar の一環として、アラート戦略に関する基本的な考え方をまとめたものです。New Relic 固有の機能を掘り下げる記事ではありませんが、他の記事と組み合わせることで、アラート設計の参考となれば幸いです。

### なぜアラート戦略を考えることが重要なのか

アラートは「どのような条件」で「誰に通知するか」と自由度が高く、その良し悪しは使い方次第で大きく変わります。適当に閾値を決めて通知を出しただけでは、チームは誤報（ノイズ）に疲れ、重要なシグナルを見逃してしまいます。

逆に、適切に設計されたアラートは、問題発生から対処までの時間を短縮し、結果的に品質の低下を抑えます。また、アラートは作成して終わりではなく、定期的な見直しと改善を行い、常に有用なツールとして機能させる工夫が必要です。本記事では、そうした「良いアラート」を実現するための考え方を示します。

## 良いアラートとは

### アラートの目的

本記事におけるアラートの目的は、「サービス品質の低下を防ぐ」とします。そのためには、異常を早期に検知し、素早く復旧対応へつなげなければなりません。

障害発生時のサービス品質低下は、大きく「影響度」と「悪影響の持続時間」の2軸で評価できます。これらをアラートがどのように低減できるか考えましょう。

#### 影響度
アラートは直接的に影響度を下げられませんが、「ユーザ影響がどの程度か」を明確に伝えることで、対応者が優先度を正しく判断できるようにします。これにより、リソースを重要な問題に集中させ、結果的に品質低下を最小限に抑えられます。

#### 悪影響の持続時間
**異常発生からアラート発報まで**
この間が短いほど、問題に素早く気づけますが、その分誤報（偽陽性）も増えやすいです。このトレードオフに対処することが重要です。

**アラート発報から問題特定まで**
アラートがトリガーされてから、通知に気づくまでの時間、そして通知を受けた対応者が、原因を特定するまでの時間です。メッセージやRunbookが適切な対処法を伝えられれば、ここで消費する時間が大幅に短くなります。

**問題特定から解決まで**
アラートそのものはこの段階で直接的な力を発揮しませんが、前述のアラートのメッセージやRunbookの手順が間違っている場合や古い場合は、かえって多くの時間を要することになります。

### よくある運用上の問題

アラートを実際に運用すると、作成時には見えなかった運用上の問題が発生するものです。

最も典型的な問題は、アラートが品質の低下について現状を正しく伝えない状況です。例として、次のようなアンチパターンがあります。

- トリガー基準に一貫性がなく、アラートを見ただけでは深刻さが分からない
- 重要度が低い問題と高い問題が同じチャンネルで通知される
- 閾値設定や条件が過度に厳しく、頻繁に誤報が発生する
- 即時対処でなく経過観察が必要なアラートにオンコールされる

こうした環境下では、チームメンバーはしだいにアラートを真剣に受け止めなくなり、結果としてアラートへの対応は形骸化していきます。

### 良いアラートの条件

ここまでで、アラートの目的と運用上の問題が明確になりました。良いアラートとはどのようなものか改めて定義します。

1. **障害による悪影響が及ぶ時間を最小限に抑える**
    
    早期検知と明確な対応フローにより、問題発生から問題特定に至るまでの時間を短縮する
    
2. **状況を正しく伝え、形骸化しない**
    
    適切にトリガーされ、重要度・深刻度に応じた通知内容・通知先が設定されている
    

これら2つの条件を満たすアラートは、品質低下を防ぐための「実用的なツール」として持続的に機能します。

## 良いアラートを作成するための戦術

### 悪影響の時間を抑えるために

**ブラックボックスアラートを採用する**

悪影響が最も長く持続するのは、そもそも異常に気づけないケースでしょう。

予見できる異常にホワイトボックスなアラートを作成することに加え、ユーザ目線での問題を確実に検知するためのブラックボックスなアラートを少数取り入れましょう。何を観測対象にすべきか分からない場合には、まずSLAやSLOに紐づけたものを作成すると良いでしょう。

**偽陽性アラートに対処する**

偽陽性（異常でないものをアラートすること）を減らす工夫が必要です。しかし、「アラートの目的」でも述べましたが、早期検知と偽陽性はトレードオフです。

検知速度を犠牲にしない範囲で集計のウィンドウサイズを大きくしたり、集計値を単純な平均値でなく99パーセンタイルの平均値にするなどの工夫が必要です。

**runbookを作成する**

ホワイトボックスアラートでは、問題が想定できているため、再現性高く使えるRunbookを用意しやすいです。原因調査や復旧の手順、まず確認すべき外部システムなど、対応者が即座に対処に取りかかるための情報を明記します。

また、十分に対処方法が明確であれば自動復旧を検討するのも手です。

### 形骸化させないために

**全てのアラートを基準に従って区分し、通知場所を分ける**

例えば、ユーザ影響は出ていないが経過観測が必要な事態を通知するアラートは、オンコールでなくslackなどでのメッセージ通知に留めるべきです。

この基準を明確にするため、ユーザ影響などの観点から「深刻度レベル」を決めましょう。深刻度の基準を決めた後は、それらが別々の場所で通知されるようにします。

即時対処が必要なケースでオンコール、普段とは異なる状況の経過観察を促すケースではメッセージ通知に留める、という対応が一般的だと思います。

**定期的にアラートの見直しを行う**

不要になったアラートは積極的に削除し、古くなったRunbookは更新します。これにより、常に「有効に機能する」アラート群を維持できます。

使途不明のアラートは消されずに残る傾向にあるため、アラート作成時に作成意図を残すことが重要です。

## New Relicにおける実践

### Runbookの登録

AlertのConditionごとに、runbookのURLを登録することができます。slackなどに通知される際にもrunbookが表示されるので、対応の初動を早めることができます。
参考: [New Relic - アラート活動のためのランブック指示の提供](https://docs.newrelic.com/jp/docs/alerts/create-alert/condition-details/provide-runbook-instructions-alert-activity/)

### Workflows・Destinationsによる通知先の分離

Alert Policies → Notificationsで通知先や、通知条件をWorkflowとして設定することができます。

Alert Conditionで設定したPriorityを元に、Critical・Warningの通知先を変えることができ、形骸化防止策として説明したアラートの区分による通知場所の分割が可能です。
参考: [New Relic - ワークフロー](https://docs.newrelic.com/jp/docs/alerts/get-notified/incident-workflows/)

### Synthetic Monitoringによる複雑なアラートの作成

APMが収集してくれるメトリクスやアプリケーションのログだけでは、サービスが適切に稼働しているか判断が難しい場合があります。Synthetic Monitoringと組み合わせると、特定の状況下での動作や、複数stepに渡るユースケースに対してアラートを設置することができます。
参考: [New Relic - Syntheticモニタリングを開始](https://docs.newrelic.com/jp/docs/synthetics/synthetic-monitoring/getting-started/get-started-synthetic-monitoring/)

## まとめ

以上、本記事では「良いアラート」とは何か、そして実践的な戦術、それらを実現するためのNew Relicの機能について紹介しました。本記事が皆様のアラート設計の参考となれば幸いです。

本記事を作成するにあたり、[Xのアカウント](https://x.com/t__nakatani)を作りました。今後も定期的に記事を書いていく予定なので、本記事が気に入りましたらぜひフォローをお願いします。

## 参考
- [New Relic - アラートの作成](https://docs.newrelic.com/jp/docs/new-relic-solutions/build-nr-ui/contribute-nr-io/create-alerts/)
- [お客さま影響に基づく実践的なアラート方法 | メルカリエンジニアリング](https://engineering.mercari.com/blog/entry/20211215-practical_alerting_methods_based_on_customer_impact/)
- [Runbookに何を書き、どのようにアラートを振り分けるか？](https://speakerdeck.com/egmc/runbooknihe-woshu-ki-donoyouniaratowozhen-rifen-keruka?slide=2)
- [practices-for-making-alerts-actionable.pdf](https://speakerdeck.com/egmc/practices-for-making-alerts-actionable)
- [Google - Site Reliability Engineering](https://sre.google/sre-book/monitoring-distributed-systems/)
- [Google SRE - Prometheus Alerting: Turn SLOs into Alerts](https://sre.google/workbook/alerting-on-slos/)
- [僕たちはアラートを管理できない](https://zenn.dev/kinzal/articles/998707314a8f6e#fn-9abe-32)
- [インフラアラートの運用を改善した話｜ONE CAREER Tech Blog](https://note.com/dev_onecareer/n/ne9bc31e85c69)
- [オンコールアラートアンチパターン](https://dasalog.hatenablog.jp/entry/2022/05/23/141749)