AWS Lambdaの監視をLambdaでおこなう
AWS Lambdaを運用しているとエラーを監視したいという要件が多々出てくると思います。 エラー監視をどうするかというと以下の3つのような選択肢が出てくるかなと思います。
- CloudWatch アラームを使用
- Mackerelのような監視ツールを使用
- 独自の監視ツールを作成
要件
CloudWatch アラームを使用は1番簡単にできる選択肢だと思います。
しかし、CloudWatchのアラームは、エラーを起こした関数がわかる、かつ、監視対象をまとめてセットすることができません。
できるのは、以下の2パターンです。
- CloudWatchのメトリクス(Lambda>全ての関数>エラー(Errors)) にアラームをセットし、通知
どのLambdaにエラーが起きたかがわからない。 - CloudWatchのメトリクス(Lambda>関数の名称別>[ファンクション名]>エラー(Errors))にアラームをセットし、通知
監視対象のLambdaを逐一設定する必要がある。
Lambdaが頻繁に追加したり、削除する要件がなければ、この方法でもよかったのですが、
検証と本番を合わせると30以上のLambdaが存在し、また、今後も増えていく予定があったためにこちらの方法は諦め、
3. 独自の監視ツールを作成を選択しました。
独自の監視ツール
構成
エラー監視ようのLambdaを作成し、5分ごとに起動するようにしています。
コード
- 特定のprefixのlambdaを取得する
lambda.listFunctions({}, (err, res) => { if(err) console.log(err); res.Functions .map(f => f.FunctionName) .filter(f => f.startsWith("staging") });
2.CloudWatchからErrorMetrics取得、エラーが起こったものに絞り込み
createParams = name => { return { Namespace: 'AWS/Lambda', StartTime: startTime, EndTime: endTime, Period: 300, MetricName: 'Errors', Dimensions: [ { Name: 'FunctionName', Value: name } ], Statistics: ["Sum"], } }; const fetchMetrics = (name) => { return new Promise((resolve, reject) => { const params = createParams(name); cloudwatch.getMetricStatistics(params, (err, res) => { if(err) { reject(err) } if (!res || !res.Datapoints) return; errorMetrics = res.Datapoints.filter(r => r.Sum > 0); if (errorMetrics.length > 0) { resolve(name) } else { resolve() } }); }) };
3.slackに通知
const notifySlack = (errorFunctionNames) => { const url = 'https://slack.com/api/chat.postMessage'; const data = { token: ''token, channel: '#channel', username: 'username', text: `error!!!!${errorFunctionNames}` }; const headers = { 'Content-Type': 'application/json' }; const options = { url, method: 'POST', headers, json: true, form: data }; request(options, (error, response, body) => { console.log(error) }) };