概要
AWS CloudWatchのアラームを利用して、とある既存アプリケーション(ECSコンテナ)で指定した閾値を超えた場合にアラートが出るようにしていました。今回、同じアラーム設定内容をセットで別の新規アプリを導入したところ、一方で閾値を超えると両方のアラートが飛んできてしまう現象に遭遇しました。
こちらの原因と解決法がわかったので紹介します。
前提
既存アプリで使っていたアラームの設定は以下の内容です。
管理コンソールから確認すると以下の通りです。
Cloudformationテンプレートは以下の内容で設定していました。
NginxLogAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref SampleTopic
Namespace: 'Nginx'
MetricName: 'Error'
ComparisonOperator: GreaterThanOrEqualToThreshold
EvaluationPeriods: '1'
Period: 60
Statistic: Sum
Threshold: 1
TreatMissingData: notBreaching
NginxMetricFilter:
Type: AWS::Logs::MetricFilter
Properties:
LogGroupName: '/aws/ecs/docker'
FilterPattern: 'ERROR'
MetricTransformations:
-
MetricValue: '1'
MetricNamespace: 'Nginx'
MetricName: 'Error'
これは、/aws/ecs/dockerロググループ内のERRORという文字列を含むログイベントを検出し、それをNginx名前空間のErrorメトリクスとしてCloudWatchに送信する、という設定になります。
ERRORをフィルターしていたのは、GunicornやuWSGIでエラーが起きる時に以下のようなエラーメッセージが表示されるためです。
[ERROR] Exception in worker process
こんな感じです。
上記のCloudwatchアラームの設定では、NginxLogAlarmがこのErrorメトリクスを監視し、60秒間に1つ以上のエラーが発生した場合にアラームをトリガーし、SampleTopicに通知を送信する、という流れです。
同時に検知してしまう現象の原因
上記と同じことがしたかったので、新規アプリでも同じ構成と流れでアラームを設定しました。
ロググループだけ別の名前/aws/ecs/docker_sampleにして、他は同じです。
しかし、いざ、これで構築が完了した後、新規アプリでエラーを検知すると既存アプリ・新規アプリの両方とも検知してしまい、アラートが2回きてしまうという現象が発生。
なぜか?
答えは、メトリクスの名前設定にありました。
公式ドキュメントには以下のように記載があります。
メトリクスは名前、名前空間、0 以上のディメンションで一意に定義されます。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html
つまり、既存と同じ MetricNamespace x MetricName の組み合わせを使うと、一意の識別子として機能して互いに検知してしまうのです。
異なるロググループから同じMetricNamespaceとMetricNameを使用してメトリクスを送信する場合であっても、それらのメトリクスはCloudWatch内で同じメトリクスとして扱われる、という意味です。
上記の場合、/aws/ecs/dockerと/aws/ecs/docker_sampleという異なるロググループ名を持つ2つのNginxMetricFilterがありますが、どちらもERRORというフィルターパターンでNginx名前空間のErrorメトリクスにデータを送信します。これにより、どちらのロググループからのエラーも同じNginx名前空間のErrorメトリクスに集約されていたのです...
なるほど。どちらのロググループでERRORが検出されても、それは同じNginxのErrorメトリクスに集約され、アラーム条件を満たしてしまうのでどちらでもアラートが上がる、ということなんですね。
確かに、それぞれのロググループのメトリクスフィルターを見ると、Alarmsのところに二つのアラームが並んでいました。これを見れば一目瞭然でしたね。
解決方法
ということで、新規アプリの方のMetricNamespaceを既存アプリのメトリクス空間名と重複しないものに設定して、再度構築。すると、上記の管理コンソールから確認しても、それぞれのロググループには一つのアラームしか存在しないようになったことを確認できました。
これでエラーが起きても、両方で検知されることは無くなりました。
めでたしめでたし。



