AWS Lambdaのログまわりに関すること まとめ

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

最近、AWS Lambdaの勉強をしているのですがログまわりの機能が非常に便利だと感じました。私がAWS Lambdaのログ周りで調査した内容をまとめます。 Lambda使いたいけどCloudWatchあまり使ったことない方にぜひ読んでもらいたいです。言語は私はPythonとNode.jsを使えないのでJavaで試しています。

ロギングライブラリに関して

まずはロギングライブラリに関してです。 Javaに関する話になっていしまいますが、LambdaLoggerlog4jを利用することでCloudWatchログに書き込むことが可能です。CloudWatchであれば過去ログの検索が簡単できたり、特定の文字列を含むログが出力された場合に通知することができるためかなり便利です。バックアップを自分で作成する必要もありません。

CloudWatchに書き込んだログを確認する

まずはLambdaLoggerを使ったログ出力のサンプルを作って試してみます。以下のLambda Functionを実行してみましょう。

package s3sample;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;

public class SampleLambdaFunction implements RequestHandler<S3Event, Object> {
    @Override
    public Object handleRequest(S3Event input, Context context) {
        context.getLogger().log("Input: " + input);

        // TODO: implement your handler
        return null;
    }
}


Lambdaのロールに以下のポリシーを適用すると、CloudWatchにログ出力できるようになります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:*:*:*"
      ]
    }
  ]
}


実行したらログが出力されているかを確認します。Management ConsoleのCloudWatchの画面で左のメニューにあるログを選択します。

lambda_log1


実行したLambda Functionと同じ名前のロググループがあるのでクリックします。次にログストリームの一覧が表示されますが、時間が一番新しいログストリームを選択してください。以下のように出力したログが表示されていると思います(2行目)。時間とキーワードで検索できます。キーワードはスペースで区切って複数指定できます。

lambda_log2

log4jの導入手順

log4jはログレベル(DEBUG、INFO、WARN、ERROR、FATAL)を分けやすいのとlog4j.propertiesで自由にフォーマットを変えられるのでお勧めです。クラス名やソースコードの行数なども出力できます。CloudWatchログで検索する際にログレベルやクラス名を検索できますので便利ではないかと思います。

以下は2行目がlog4jで3行目をLambdaLoggerで出力しています。ログにクラス名と行数が表示されているのが分かります。

lambda_log_6

LambdaからLog4jを使ってCloudWatchログに出力するためには、log4のjarファイルとLambdaAppenderクラスを含んだjarファイルをダウンロードしクラスパスを通します。次に設定ファイルであるlog4j.propertiesを作成し、クラスパスが通っている場所に置いておきます。以下はLog4jでログ出力するサンプルソースになります。

Apache log4j 1.2 -
Maven Repository: com.amazonaws » aws-lambda-java-log4j » 1.0.0

import org.apache.log4j.Logger;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;

public class LambdaLogSample implements RequestHandler<S3Event, Object> {

    static final Logger logger = Logger.getLogger(LambdaLogSample.class);

    @Override
    public Object handleRequest(S3Event input, Context context) {
        logger.debug("log4j logger");
        return null;
    }
}


以下はlog4j.propertiesのサンプルになります。

log = .
log4j.rootLogger = DEBUG, LAMBDA

#Define the LAMBDA appender
log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender
log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout
log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n

以下のドキュメントを参考にしています。
ロギング(Java) - AWS Lambda

ログの保持期間に関して

ログの保持期間はデフォルトは無期限になっています。有効期限を設定する場合はCloudWatchの以下の画面で「失効しない」リンクをクリックすると設定画面が表示されます。保持期間を選択してOKボタンをクリックして下さい。

lambda_log5

CloudWatchのログ監視に関して

CloudWatchログの監視機能を使えばログを監視して、特定の文字列が含まれるログが出力した場合にAmazon SNSで通知することができます。メトリックスフィルタ列の0フィルタというリンクをクリックします。

lambda_log3

ここで監視する文字列を指定します。実際に出力されているログを使ってどの程度一致するかを確認ことができます。 この例ではExeptionという文字列が含まれていた場合に通知するようにしました。

lambda_log_5

例外発生時の通知

Lambda Function内でcatchされない例外が発生した場合にCloudWatchのアラームに表示するようにできます。Amazon SNSを使ってメールなどで通知することも可能です。詳細はCloudWatchログにも出力されていますのでそちらを確認する必要があります。

Management ConsoleのCloudWatchの画面を開きます。左側のメニューからアラームを選択し、アラームを作成ボタンをクリックします。

lambda_exception1


検索窓にLambdaファンクション名と"Errors"という文字列を入力しメトリックスをフィルタリングします。

lambda_exception2


表示されたメトリックスにチェックを入れ、次へボタンをクリックします。

lambda_exception3


次にアラームの定義をします。以下のようにエラー(Errors)>=1 が1回連続した場合にアラームを発生させるようにします。 通知する場合はSNSの設定が必要がです。

lambda_exception4


アラームの作成は以上になります。わざと例外を発生させてメールが送信されるのを確認してみてください。 例外が発生してしまった場合は自動的にリトライしてくれるようです。回数などはサービスによって違います。

最後に

調べたことは以上になります。Lambdaから出力したログはManagement Console上で管理できメール送信の設定も簡単で驚きました。 個人的にはlog4j使えるのが嬉しかったです。CloudWatchあまり使ったことない方はぜひ試してみてください。