8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ミロゴスAdvent Calendar 2022

Day 1

Lambdaの実行時間がタイムアウトの8割を超えたらアラートを出す

Last updated at Posted at 2022-11-30

はじめに

この記事は、ミロゴス Advent Calendar 2022 1日目の記事です。

社内システムで利用しているAWS Lambda(Node.js)の実行時間がタイムアウト時間の
8割に達した時にアラートを出したいという要件があったため対応しました。

✳︎ 記事はCDKがある程度書かれている前提で記載しています
✳︎ 変数部分は適宜置き換えて下さい

ログストリームのLambda実行後ログから実行時間を取得してアラートを出す

実装内容は下記です。
実装はTypeScriptで行います。

  • CDK
    • 対象ロググループにlambdaの実行ログからDuration値を検知するMetricFilterを作成する
    • 60秒間での合計検知数を見るMetricを作成する
    • 閾値をタイムアウト時間の8割でアラームを定義
MetricFilterの定義・LogGroupへの追加
const metricFilterProps: logs.MetricFilterOptions = {
     metricNamespace: metricNameSpace,
     metricName: metricName,
     filterPattern: logs.FilterPattern.literal('[type=REPORT, request_id_label, request_id, duration_label, duration, ...]'),
     metricValue: '$duration',
};

logGroup.addMetricFilter('MetricFilter', metricFilterProps);

REPORTから始まるログはスペース区切りになっているので、下記部分でフィールドを指定してduration値を$durationとして取得できるようにしています。
スペース区切りログイベントから値を取得するメトリクスフィルターの使用

filterPattern: logs.FilterPattern.literal('[type=REPORT, request_id_label, request_id, duration_label, duration, ...]')

取得した$durationはmetric値としてそのまま使います

metricValue: '$duration'
Metric定義
const metric = new cloudwatch.Metric({
    namespace: metricNameSpace,
    metricName: metricName,
    period: Duration.seconds(60),
    statistic: cloudwatch.Statistic.SUM,
});

Alarm定義

const alarm = new cloudwatch.Alarm(this, 'Alarm', {
     alarmName: alarmName,
     alarmDescription: alarmName,
     comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
     metric: metric,
     threshold: lambdaTimeout * 0.8,
     evaluationPeriods: 1,
     datapointsToAlarm: 1,
     actionsEnabled: true,
     treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
});

今回は閾値を実行時間の8割としたいので、下記のようにしています。

threshold: lambdaTimeout * 0.8,

(別パターン)Lambda側で実行時間を検証する

採用はしませんでしたが、最初Lambda側で実行時間をチェックするような実装をしようと思っていたので、そちらも記載します。

実装内容は下記です。

  • Lambda
    • タイムアウトの8割を過ぎたタイミングでcloudwatchにログを吐き出す
  • CDK
    • 対象ロググループにlambdaの実行ログから「WARNING elapsed time」を検知するMetricFilterを作成する
    • 60秒間での合計検出数を見るMetricを作成する
    • 閾値1でアラームを定義

Lambda

実行時間の取得はcontextオブジェクトのgetRemainingTimeInMillis()メソッドを利用します。
下記のドキュメントにも書かれていますが、こちらのメソッドは実行がタイムアウトするまでの残り時間をミリ秒で返してくれます。
Node.js の AWS Lambda context オブジェクト

実装
export const handler = async (event, context) => {
  const timeout = 60000;
  setTimeout(
    () => console.log(`WARNING elapsed time ${timeout - context.getRemainingTimeInMillis()}ms`),
    timeout * 0.8,
  );

lambda handler実行後すぐにsetTimeout実行し、無理やり実行時間を見ています。

CDK

MetricFilterの定義・LogGroupへの追加
const metricFilterProps: logs.MetricFilterOptions = {
     metricNamespace: metricNameSpace,
     metricName: metricName,
     filterPattern: logs.FilterPattern.literal('WARNING elapsed time'),
     metricValue: 1,
};

logGroup.addMetricFilter('MetricFilter', metricFilterProps);
Metric定義
const metric = new cloudwatch.Metric({
    namespace: metricNameSpace,
    metricName: metricName,
    period: Duration.seconds(60),
    statistic: cloudwatch.Statistic.SUM,
});

Alarm定義

const alarm = new cloudwatch.Alarm(this, 'Alarm', {
     alarmName: alarmName,
     alarmDescription: alarmName,
     comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
     metric: metric,
     threshold: 1,
     evaluationPeriods: 1,
     datapointsToAlarm: 1,
     actionsEnabled: true,
     treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
});

ただ、自前でログを出さなくても、Lambda実行時はかれるログストリーム上のREPORTから始まるログに、Duration(実行時間)も記載されているため、上記の実装はやめて下記のようにしました。

まとめ

以上でlambdaの実行時間によるアラート設定ができました!
Lambdaの実行後ログに色々書いてあるおかげで余計なことせずに済みました。

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?