アラームを実行するデータポイントでアラーム状態が短時間だけOK状態に戻る際の誤報を抑制する

2022.01.18

データアナリティクス事業本部の鈴木です。

CloudWatchアラームのアラームを実行するデータポイントを使って、アラーム状態が短時間だけOK状態に戻る際に誤報を抑制できるか検証してみました。

解決したいケース

CloudWatchアラームでメトリクスを監視し、アラーム状態に遷移した際に通知などのアクションをトリガーするユースケースがあると思います。 例えば、以下のように、SQSのデッドレターキューにメッセージが入ると、通知するような仕組みなどです。

解決したいケース

デッドレターキューにメッセージが入った際には、メッセージをポーリングしてメッセージの内容を確認することがあると思いますが、アラームがキューの表示されたメッセージの数などを監視しているような場合は、アラームの設定によってはポーリングの際に一度アラームがOK状態に戻ってしまい、メッセージが再び表示されると通知が飛んでしまうということが起こります。

この誤報を抑制できないかと思い、アラームを実行するデータポイントに注目しました。

アラームを実行するデータポイントとは

この機能により、メトリクスのN個のデータポイントのうちM個がしきい値を超えた場合に、アラーム状態に遷移するアラームを作成できるようになりました。 この設定により、短時間で変化が大きいメトリクスでの誤報を抑制することができます。

詳しくは以下の資料をご確認ください。

準備

以下のCloudFormationテンプレートを使い、3つのSQSのキューとそれを監視するCloudWatchアラームを作成しました。

sqs_with_alarm.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: SQS Standard Queue with alerm

Parameters:
  QueueName:
    Description: Name for queue
    Type: String
  AlarmDatapointsToAlarm:
    Description: DatapointsToAlarm for Alarm
    Type: Number
  AlarmEvaluationPeriods:
    Description: EvaluationPeriods for Alarm
    Type: Number    
  

Resources:
  SQSQueue:
    Type: AWS::SQS::Queue
    Properties:
      MessageRetentionPeriod: 1209600
      QueueName: !Sub ${QueueName}
      VisibilityTimeout: 120

  SQSAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub ${QueueName}-alerm
      ComparisonOperator: GreaterThanThreshold
      DatapointsToAlarm: !Sub ${AlarmDatapointsToAlarm}
      EvaluationPeriods: !Sub ${AlarmEvaluationPeriods}
      Threshold: 0
      Namespace: AWS/SQS
      Dimensions:
          - Name: QueueName
            Value: !Sub ${QueueName}
      MetricName: ApproximateNumberOfMessagesVisible
      Period: 60
      Statistic: Maximum
      TreatMissingData: notBreaching

テンプレートで重要なのはハイライトした箇所になります。

  • キューの可視性タイムアウトを120秒としています。
  • 後ほど説明するアラームを実行するデータポイントを調整するため、DatapointsToAlarmEvaluationPeriodsを設定します。これらはスタックの作成時にパラメータから渡せるようにしています。

検証用に3つスタックを作成します。パラメータは以下のようにしました。

No QueueName AlarmDatapointsToAlarm AlarmEvaluationPeriods 備考
1 cm-nayuts-alerm-target-queue1 1 1 アラームを実行するデータポイントが1/1になるように設定する
2 cm-nayuts-alerm-target-queue2 5 5 アラームを実行するデータポイントが5/5になるように設定する
3 cm-nayuts-alerm-target-queue3 3 5 アラームを実行するデータポイントが3/5になるように設定する

各アラームで、アラームを実行するデータポイントの値を異なるように設定しているのが今回の検証のポイントとなります。

やってみる

0. アラーム状態にする

まずは作成したアラームをアラーム状態に遷移させておきます。今回はアラームがApproximateNumberOfMessagesVisibleのメトリックを監視しており、0より大きい値になった際にアラーム状態に遷移するので、そのために各キューにメッセージを送信して、状態が変わるのを待ちます。

メッセージの送信は、例えば各キューのメッセージを送受信画面から行えるので、以下の例のように適当なメッセージを1件ずつ送信しておきました。

メッセージ送信例

しばらくすると、各アラームで評価が終わった段階で、以下のようにアラーム状態になりました。

アラーム状態の例

1. 監視対象のメトリックの値を変えてみる

各キューの中のメッセージをポーリングしてみて、メッセージを非表示にすることで、ApproximateNumberOfMessagesVisibleの値を一時的に0に戻してみます。

コンソールからだと、例えばメッセージを送受信画面でメッセージをポーリングを押すことでポーリングできます。

メッセージのポーリング例

今は各キューに1件ずつしかメッセージが入っていないはずなので、これで全メッセージが120秒間非表示になり、ApproximateNumberOfMessagesVisibleの値も0になるはずです。

2. アラームの状態を観察してみる

あとはメッセージが再び可視になるのを待って、アラームの状態がどのように変わったのか確認してみます。

アラームを実行するデータポイントが1/1のとき

アラーム状態の表示を見ると、一時的にOK状態に戻っていることが分かります。直前の1点でアラーム状態を判断するため、ポーリングにより一時的にApproximateNumberOfMessagesVisibleの値が0になったことでアラーム状態ではなくなっています。

アラームを実行するデータポイントが1/1のとき

例えばこの設定でポーリングをしてしまうと、2回目のアラーム状態への遷移で誤報が飛んでしまうため、注意が必要です。

アラームを実行するデータポイントが5/5のとき

こちらも一時的にOK状態に戻っていることが分かります。アラーム状態への遷移に必要なデータ点が5点になるためOK状態が長くなりますが、基本的には1/1のときと同じ動きになります。

アラームを実行するデータポイントが5/5のとき

コンソールから設定する場合はあまりないかもしれませんが、CloudFormationからアラームを作成する際にDatapointsToAlarmの値を設定していないと意図せずこのような設定になっている可能性があるので、注意が必要です。

アラームを実行するデータポイントが3/5のとき

このときは、一時的にApproximateNumberOfMessagesVisibleの値が0になってもアラーム状態が維持されていることが分かります。今回は、評価期間の5個のデータポイントのうち4つは閾値を上回っているため、3/5の条件を満たしており、アラーム状態からOK状態に遷移することはありませんでした。

アラームを実行するデータポイントが3/5のとき

この設定であれば、少しポーリングしてメッセージをチェックしたくらいでは誤報が飛ぶことは回避できそうです。

まとめ

今回はSQSとCloudWatchアラームを例に、アラームを実行するデータポイントで一時的にアラーム状態がOK状態に戻ることによる誤報の抑制例を紹介しました。

本検証ではキューの可視性タイムアウトが120秒なのに対して、1分の期間を持つ5個のデータ点のうち3個で実行されるアラームを設定しているので、上手く誤報の抑制ができています。実際の「N 個中 M 個」の値は、監視するメトリクスの変化の度合いに合わせて調整することが必要そうです。

参考