Amazon CloudWatchのアラームをMackerelアラートにする仕組み

SREチームの吉村です。

弊社では主にAmazon Web Service(AWS)を使ってサービスを構築、運用しており、そのサービスの監視にMackerelを利用しています。 Amazon CloudWatchのメトリクスのうち主要なものはfluentd(fluent-plugin-cloudwatchfluent-plugin-mackerel)を利用してMackerelに登録していますが、量が多くなるとfluentdの設定が煩雑になってしまいます。

そこで、Mackerelへの登録に必要なそれらの設定なしに、CloudWatch Alarmを使ってMackerelのアラートとして発報できる仕組みを作りました。 Mackerelへアラートを発報するようにした理由は、アラートの通知や管理はMackerelで一元管理をしているためです。

今回その仕組みについてご紹介、組み込み手順まで説明したいと思います。

概要

cloudwatch-alarm-to-mackerel

cloudwatch-alarm-to-mackerel

上図はCloudwatch AlarmからMackerelへアラートが上がるまでの流れを表した図です。 CloudWatch Alarmが発火されたら、そのアラームのactionsに設定したAmazon Simple Notification Service(SNS)のtopic1へメッセージが飛びます。 そのメッセージは予めSNS上で登録したサブスクリプションによってcloudwatch-alarm-to-mackerel関数へ流れていきます。 最後に、メッセージはMackerelへアラートを上げます2

次に、実際の導入方法を説明します。

導入方法

必要なもの

以下のツールを事前に用意してください。

1. SNSのtopicを作成する

CloudWatch Alarm発火後の通知先に、先に述べたSNSのtopicが必要のため事前に作成します。

$ aws sns create-topic --name sample

2. Mackerelにホストを作成

Mackerelの POST /api/v0/monitoring/checks/report ではhost idが必要なので、 cloudwatch-alarm-to-mackerel専用のhostをMackerel側に登録します。

$ mkr create sample_host

3. Lambdaの組み込み

cloudwatch-alarm-to-mackerelはapexの利用を想定しています。 以下、apexのディレクトリ階層の例です。

.
├── functions
│   └── cloudwatch-alarm-to-mackerel
│       ├── function.json
│       └── main.go
└── project.json

main.goとfunction.jsonを作成します.

  • main.go
package main

import (
    "github.com/kayac/cloudwatch-alarm-to-mackerel"
)

func main() {
    cwa2mkr.ApexRun()
}
  • function.json
{
  "name": "cloudwatch-alarm-to-mackerel",
  "description": "alert cloudwatch alarm to mackerel",
  "runtime": "go1.x",
  "memory": 128,
  "timeout": 60,
  "handler": "main",
  "environment": {
    "HOST_ID": "mackerelのhost id",
    "MACKEREL_APIKEY": "mackerel apikey"
  }
}

※ HOST_ID, MACKEREL_APIKEY は適宜正しい値を入力してください。
※ 注意: mackere_apikeyは秘密情報なので、apex deploy --env ... 等で実行時のみ入れるなどの工夫をしたほうが良いです。

  • project.json
{
  "name": "sample",
  "description": "sample project",
  "memory": 128,
  "timeout": 60
}

この状態で、先のディレクトリ階層の現在位置でapexよりデプロイを実行します。

# dryrunで確認
$ apex deploy --dry-run cloudwatch-alarm-to-mackerel

# デプロイ
$ apex deploy cloudwatch-alarm-to-mackerel

# 登録の確認 & arnのチェック
$ aws lambda get-function --function-name sample_cloudwatch-alarm-to-mackerel | jq -r .Configuration.FunctionArn

※ function名に sample_ がつくのはproject.jsonのnameがsampleなためです。

次にSNSサブスクリプションを登録します。

$ aws sns subscribe --topic-arn <topic arn> --protocol lambda --notification-endpoint <lambda arn>

<topic arn>には1で作成したtopicのarn、<lambda arn>には先程登録したLambdaのarnを入れます。

4. Cloudwatch Alarmを作成

アラート検知させたいCloudwatch Alarmを作成します。 アラーム設定したいメトリクスを選択肢、登録したトピックを通知先に設定します。

以下、console上でのアラームの通知先設定の画面です。

cloudwatch alarmの設定

①ではデータが不足している場合の挙動を設定できます。 画像では現状維持を設定しています。 こちらは適宜設定してください。 ②で、通知先のアクションが設定します。 先に作ったsampleのSNSトピックを選択します。

5. 動作確認

登録した Cloudwatch Alarm の閾値を調整して、現在のメトリクス値で適当に発報されるようにconsole上から設定して動作を確認します。 以下の画像のようにMackerel側にアラートが上がるのを確認できます。

warningのアラート結果

criticalアラームの設定

cloudwatch-alarm-to-mackerelは、デフォルトでWarningレベルでアラートを投稿しますが、 alarmのdescriptionの先頭がCRITICALという文字列だった場合、Criticalレベルでアラートを投稿します。

以下、設定を変更してCriticalレベルのアラートになるか確認した結果です。

criticalのアラート結果

おまけ: PostChecksReports の利用

Mackerelへpostする部分は別パッケージからも利用できるようにしてあります。 このAPIだけ簡単に利用したい場合にどうぞ。

package main

import (
    "log"
    "time"

    "github.com/kayac/cloudwatch-alarm-to-mackerel"
)

func main() {
    now := time.Now().Unix()
    apiKey = "Your mackerel api key"

    reports := cwa2mkr.Reports{
        Reports: []cwa2mkr.Report{
            cwa2mkr.Report{
                Source: cwa2mkr.Source{
                    Type:   "host",
                    HostID: "host id",
                },
                Name:       "test alarm",
                Status:     cwa2mkr.StatusWarning,
                Message:    "this is a test",
                OccurredAt: now,
            },
        },
    }

    if err := cwa2mkr.PostChecksReport(apiKey, reports); err != nil {
        log.Println(err)
    }
}

さいごに

AWSのリソースに対する監視をCloudwatch Alarmの新規作成のみで設定できるようになる点が良いところだと思います。設定が簡単なので、AWSのメトリクスから一旦アラートだけ上げられるようにして、あとから細かく監視を調整していくと行った場合でも便利かと思いました。

kayacではいつでもエンジニア募集中です!


  1. SNS topicはメッセージを送信、受信するための通信チャネルで、CloudWatch Alarm以外の様々なAWSサービスから利用できます。

  2. MackerelのアラートにはPOST /api/v0/monitoring/checks/reportを使っています。

builderscon 2018 に弊社社員が登壇/参加しました

こんにちはブログ編集委員の竹田です。

先日、2018/9/6,7,8の3日間に渡り、慶應義塾大学 日吉キャンパス内で行われたbuilderscon 2018の3セッションに弊社社員が登壇しました。

弊社谷脇もスタッフと参加しており、謎のガジェットの仕込みに奮闘していたようです。

今回はも登壇者として参加させていただきました。

【前夜祭】KAYAC hara: 人類バーチャル化のすすめ

登壇者:原 真人

機械学習を用いず数学でゲーム内の需要予測をする

登壇者:禰寝 崇之

speakerdeck.com

ソーシャルゲームが高負荷に陥っているとき、何が起こっているのか

登壇者:竹田 昭仁

speakerdeck.com

「知らなかった、を聞く」が、このカンファレンスのテーマ。上記いずれもテーマに答えられたのでは無いでしょうか (自賛

また、弊社の他社員もリスナーとして参加させていただきました、大変有意義な時間を過ごすことができたようです。

buildersconの運営スタッフ・スポンサー・関係者の皆様ありがとうございました。


カヤックでは人類バーチャル化・数学での未来予測・ソーシャルゲームの高負荷に興味のあるエンジニアを積極的に募集しています。