今回は外形監視みたいなことしてCloudwatchで監視設定します。
簡単にいえばアクセスログで400エラーなんやらが発生したらslack へ通知を出します。
メール通知はアドレス入れるだけで簡単ですけど最近流行らないですからね、
構成
ざっくりこうです。(よくある)
設定順番は以下
1.SNSへトピック追加
2.CloudWatchのアラート設定
3.slackのwebhookURL確認
4.Lambdaの設定
5.SNSとLambdaの設定
SNSへトピック追加
とりあえずはSNSでトピックだけ作成 適当な名前を決めるだけ。サブスクリプションは最後に設定。
CloudWatchのアラート設定
httpdのアクセスログから400番台エラーを検知するようにします。
一発CLIだとこう
aws logs put-metric-filter \ --log-group-name /HttpdAccessLog \ --filter-name HTTP4xxErrors \ --filter-pattern '[ip, id, user, timestamp, request, status_code=4*, size]' \ --metric-transformations \ metricName=HTTP4xxErrors,metricNamespace=MyNamespace,metricValue=1,defaultValue=0
(--log-group-name だけは各々の環境に修正すること)
コンパネからするやり方だと
「ログ」を選択しアラームを作成するロググループをチェック
「メトリクスフィルタを作成する」を選択
[ip, id, user, timestamp, request, status_code=4*, size]
フィルタパターンに上記を入力して「メトリクスの割り当て」
2枚上画像のログ一覧から右側のメトリクスフィルタから作成したメトリクスを選択(数字を押す)
そしてアラームの作成
画像のように設定して通知先を先程作成したSNSトピックにする
slackのwebhookURL確認
slackの設定から確認
こんな感じ
Lambdaの設定
「関数の作成」から以下を
ランタイムは「node.js 8.10」
4行目のwebhookUrlを環境に合わせる
var url = require('url'); var https = require('https'); var hookUrl = 'https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; var processEvent = function(event, context) { var message = JSON.parse(event.Records[0].Sns.Message); // Format Slack posting message var text = "<!channel> *" + message.AlarmDescription + "* state is now `" + message.NewStateValue + "`\n" + "```" + "reason: " + message.NewStateReason + "\n" + "alarm: " + message.AlarmName + "\n" + "time: " + message.StateChangeTime + "```" ; var slackMessage = { text: text }; postMessage(slackMessage, function(response) { if (response.statusCode < 400) { console.info('Message posted!'); context.succeed(); } else if (response.statusCode < 500) { console.error("4xx error occured when processing message: " + response.statusCode + " - " + response.statusMessage); context.succeed(); // Don't retry when got 4xx cuz its request error } else { // Retry Lambda func when got 5xx errors context.fail("Server error when processing message: " + response.statusCode + " - " + response.statusMessage); } }); }; var postMessage = function(message, callback) { var body = JSON.stringify(message); var options = url.parse(hookUrl); options.method = 'POST'; options.headers = { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body), }; var postReq = https.request(options, function(res) { var chunks = []; res.setEncoding('utf8'); res.on('data', function(chunk) { return chunks.push(chunk); }); res.on('end', function() { var body = chunks.join(''); if (callback) { callback({ body: body, statusCode: res.statusCode, statusMessage: res.statusMessage }); } }); return res; }); postReq.write(body); postReq.end(); }; exports.handler = function(event, context) { if (hookUrl) { processEvent(event, context); } else { context.fail('Missing Slack Hook URL.'); } };
トリガーにSNSを設定
先程作ったトピックネームを選択
SNSとLambdaの設定
プロトコルは「Lambda」
エンドポイントは先程作成したLambda関数を選択
確認
400エラーを発生させてみる
きた
まとめ
あくまでログから判断する擬似的な外形監視なので500エラーは検知できない。 それをやるならほんとうに外側からやる必要がある。
いざやってみると複数のサービスで作成順番があるのでちょっと混乱した。
(SNSないからCloudWatchの通知ないやんけとか)
一度つくって理解しとくと作業自体は簡単