LambdaやAWS CLIを使わず、CloudWatch Alert を特定時間帯のみ通知や、
画面で有効・無効を切り替える方法を発見しました。
普段サーバレスな, 小西 啓介(@komikoni) です。
Qiitaは、アドベント・カレンダー2016を初めて書いて以来です。
背景
AWSに構築したシステムの監視として、CloudWatch Metricsで、
しきい値を超えたときなどに通知に使うのが、CloudWatch Alertです。
その、CloudWatch Alertで悩ましいのが、深夜時間帯等に通知をしないようにしたり、
システムメンテナンスの時に手動で通知しないようにする(いわゆる静観?)設定です。
悩ましい理由としては、以下のようなものがあります。
- CloudWatch AlertやSNS(Simple Notification Service)には、時間等で通知をフィルタリングする機能がない
- CloudWatch AlertやSNSには、画面(AWS Management Console)で、有効・無効を切り替える機能がない(AWS CLIとかAPIでは出来る)
-
コードを書きたくない!
(インフラ屋さんに多い?)
それでも通知をしたくないので、打開策として、
これまで、以下の方法がよく行われていました。(記事もいっぱいある)
-
CloudWatch EventからLambdaを呼び出し、CloudWatch AlertのEnable/Disableを切り替える
-
AWS CLI等を使い、手動で CloudWatch AlertのEnable/Disableを切り替える
-
アマゾンウェブサービス-特定の時間帯にAWS CloudWatchアラームを一時停止/無効化できますか? - stackoverflow
概要解説
今回、追加で利用するのは、以下の3つです。
- CloudWatch Event
- CloudWatch Metrics (及び、Metric Math機能)
- CloudWatch Logs
です。つまり、CloudWatch だけしか使いません。
CloudWatch Eventの利用
CloudWatch Eventは、普段、CloudWatch Eventは、Lambdaを起動したりするのに使いますが、
今回は、スケジュールを組んで監視をしたい時間帯に、CloudWatch Logsのロググループをターゲットにイベントを発行します。
欲しいのは、メトリクスなので、別に、CloudWatch Logsで無くても良いんですが、CloudWatch Eventは、
何らかターゲットが必要なので、一番お金のかからなさそうな、CloudWatch Logsをターゲットにします。
CloudWatch Metricsの利用
上記のCloudWatch Eventでイベントを発行すると AWS/Events
の
Invocations
メトリクス(m1
とする)が出来ます。
このm1
メトリクスと、実際に、監視をしたいメトリクス(m2
とする)を選択して、Metric Math 機能によって、
m1 * m2
のように掛け算した、新たなメトリクスを作成します。(カスタムメトリクスではないので、お金はかからない(はず))
この、新たなメトリクスを、CloudWatch Alertで監視するのです。
ようは、メトリクスといっても、数値なので、通知を出す(0)か出さない(1)かを表すメトリクスを用意して、
監視したいメトリクスと掛け算すれば、通知を出すときは、元のメトリクスを元に監視できるし、
通知を出したくない時には、0を書けるので、通知が出ないということです。
まとめ
これにより、以下を実現できます。
- 監視をしたい時間帯のみ、CloudWatch Alertで通知をすることが可能
- CloudWatch Eventの画面(AWS Management Console)で、通知の有効・無効の切り替えが可能
- Lambda等のコーディング、デプロイが一切不要!!
- コードが無いから、CloudFormation化も簡単!?
2. は、副次的なメリットですが、普段は、通知したい時間帯だが、システムメンテナンス等で、
監視をやめたい(静観)場合もコマンドの実行等が不要というのは、良いですよね!(もちろんコマンドでも出来る)
実施手順
CloudWatch Eventでの手順
1 . CloudWatch Eventでルールを作成する を開く
2 . 「スケジュール」を選択し、任意のCron式を入力 (参考 : Schedule Expressions for Rules - Amazon CloudWatch Events)
下の例では、「0/5 0-9 ? * MON-FRI *」を入力 (月曜から金曜,日本時間の9:00~17:55まで5分毎)
3 . 「ターゲット」の追加にて、「CloudWatchロググループ」を選び、任意のロググループ名を設定し、「設定の詳細」を押す
4 . ルールの定義で、「名前」を入力し、「ルールの作成」を押す
CloudWatch Metricsの手順
5 . CloudWatch Metricsを開く
6. 検索欄に4.で入れた「名前」を入力して検索 (4.が1度以上実行されていないと出てきません)
7 . 「呼び出し(Invocations)」を選択する
8 . (実際に)監視したいメトリクスを追加で選択
9 . 「グラフ化したメトリクス」を選び、「Math Expression」を押して、「Start with empty expression」を選択
10 . 上部のタイトル、ラベルに任意の名称を入れ、詳細に**「m1 * m2」(ここが肝!)**を入力
11 . チェックボックスで先頭のみを選択し、「統計」を「合計」に変更し(キャプチャーでは漏れてました)アラームのアクションを押す
CloudWatch Alertの手順
12 . Cloudwatch Alerm の画面が開かれるので、任意のしきい値を入力し「次へ」を押す
14 . アラーム名を入れて「次へ」を押す
お断り
- 本手法は、実際のシステム等では、まだ利用しておらず、十分な検証をしていません。
- 本手法の適用は、読まれた方ご自身の責任において行われるものとし、筆者は一切の責任を負いません。
- 本記事は、筆者の所属企業とは、一切関係なく、個人としての執筆となります。
- Cloudwatch alertの設定や、SNSの設定は適当な部分があります。
- Cloudwatch logsのロググループは、無期限で作成されます。ログ自体は使用しないので、任意の保管期限に変更して下さい。
- 2019年05月29日現在、似たような記事は確認できなかったので、世界初!?かな?。
余談
今回、ノン・コーディングで実装したいと思って、当初 CloudWatch Alertと連携できるEventBdrigeを使い、
EventBrigeのコンテンツフィルタリングで time
属性で ["T10","T11"・・]
などとフィルタリング出来るかと
おもったのですが、contain関数が無く、実現できませんでした。その後、考えたのがこれです。
でも、今までCloudWatch系は、Logsがメインで、あまり使ったことなかった機能ばかりだったので、色々勉強になりました。