Lambda 関数の CloudWatch Logs を表示する - AWS Lambda

Lambda 関数の CloudWatch Logs を表示する

Lambda 関数の Amazon CloudWatch logs は、Lambda コンソール、CloudWatch コンソール、または AWS Command Line Interface (AWS CLI) を使って表示できます。関数のログにアクセスするには、次のセクションの手順を実行します。

CloudWatch Logs ライブテールを使用して関数ログをストリーミングする

Amazon CloudWatch Logs ライブテールは、Lambda コンソールで新しいログイベントのストリーミングリストを直接表示することで、関数のトラブルシューティングを迅速に行うのに役立ちます。Lambda 関数から取り込まれたログをリアルタイムで表示、フィルタリングできるため、問題をすばやく検出して解決することができます。

注記

Live Tail セッションでは、セッションの使用時間ごとに 1 分間隔でコストが発生します。料金の詳細については、「Amazon CloudWatch の料金」を参照してください。

ライブテールと --ログ-タイプテールの比較

CloudWatch Logs ライブテールと Lambda API (AWS CLI の --log-type Tail) の LogType: Tail オプションには以下のいくつかの違いがあります:

  • --log-type Tail は、呼び出しログの最初の 4 KB のみを返します。ライブテールは、この制限を共有せず 1 秒あたり最大 500 件のログイベントを受信できます。

  • --log-type Tail はレスポンスでログをキャプチャして送信します。これにより、関数のレスポンスレイテンシーに影響を与える可能性があります。ライブテールは、関数レスポンスのレイテンシーには影響しません。

  • --log-type Tail は同期呼び出しのみをサポートします。ライブテールは、同期呼び出しと非同期呼び出しの両方で機能します。

アクセス許可

CloudWatch Logs ライブテールセッションを開始および停止するには、以下のアクセス許可が必要です:

  • logs:DescribeLogGroups

  • logs:StartLiveTail

  • logs:StopLiveTail

Lambda コンソールでライブテールセッションを開始する

  1. Lambda コンソールの [関数ページ] を開きます。

  2. 関数の名前を選択します。

  3. [テスト] タブを選択します。

  4. [テストイベント] ペインで、[CloudWatch Logs ライブテール] を選択します。

  5. [ロググループを選択] で、関数のロググループはデフォルトで選択されます。一度に最大 5 つのロググループを選択できます。

  6. (オプション) 特定の単語やその他の文字列を含むログイベントのみを表示するときは、その単語または文字列を [フィルターパターンを追加] ボックスに入力します。フィルターフィールドでは、大文字と小文字が区別されます。このフィールドには、正規表現 (regex) を含む、複数の用語とパターン演算子を含めることができます。パターン構文の詳細については、「Amazon CloudWatch Logs ユーザーガイド」の「フィルターパターン構文」を参照してください。

  7. [開始] を選択します。一致するログイベントがウィンドウに表示されます。

  8. Live Tail セッションを停止するには、[停止] をクリックします。

    注記

    ライブテールセッションは、15 分間非アクティブ状態になった後、または Lambda コンソールセッションがタイムアウトすると自動的に停止します。

コンソールを使用して関数ログにアクセスする

  1. Lambda コンソールの [関数ページ] を開きます。

  2. 関数を選択します。

  3. [Monitor] (モニタリング) タブを選択します。

  4. [View CloudWatch Logs を表示] を選択して、CloudWatch コンソールを開きます。

  5. 下にスクロールし、表示したい関数呼び出しのログストリームを選択します。

    Lambda 関数のログストリームの一覧。

Lambda 関数の各インスタンスには、専用のログストリームがあります。関数がスケールアップした場合は、各同時インスタンスが独自のログストリームを持ちます。呼び出しに応じて新しい実行環境が作成されるたびに、新しいログストリームが生成されます。ログストリームの命名規則は次のとおりです。

YYYY/MM/DD[Function version][Execution environment GUID]

単一の実行環境は、その存続期間中は同じログストリームに書き込みます。ログストリームには、その実行環境からのメッセージと、Lambda 関数のコードからの出力が含まれます。カスタムログを含め、すべてのメッセージにはタイムスタンプが付けられます。関数がコードからの出力をログに記録しない場合でも、呼び出しごとに 3 つの最小ログステートメントが生成されます (START、END、REPORT)。

モニタリングとオブザーバビリティの図 3

これらのログには、以下が表示されます。

  • RequestId - リクエストごとに生成される一意の ID です。Lambda 関数がリクエストを再試行しても、この ID は変更されず、その後再試行するごとにログに表示されます。

  • 開始/終了 - 単一の呼び出しをブックマークするため、これらの間にあるすべてのログ行は同じ呼び出しに属します。

  • 所要時間 - INIT コードを除く、ハンドラー関数の合計呼び出し時間。

  • 請求期間 - 請求目的で四捨五入ロジックを適用します。

  • メモリサイズ - 関数に割り当てられたメモリの量。

  • 最大使用メモリ - 呼び出し中に使用されたメモリの最大量。

  • 初期所要時間 - メインハンドラーの外部で、コードの INIT セクションを実行するためにかかった時間。

AWS CLI を使用したログへのアクセス

AWS CLI は、コマンドラインシェルでコマンドを使用して AWS サービスとやり取りするためのオープンソースツールです。このセクションの手順を完了するには、AWS CLIバージョン 2 が必要です。

AWS CLI および --log-type コマンドオプションを使用して、呼び出しのログを取得します。レスポンスには、LogResultフィールドが含まれ、このフィールドには、呼び出しから base64 コードされた最大 4 KB のログが含まれます。

例 ログ ID を取得します

次の例は、LogResultという名前の関数のmy-functionフィールドからログ ID を取得する方法を示しています。

aws lambda invoke --function-name my-function out --log-type Tail

次のような出力が表示されます。

{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
例 ログをデコードします

同じコマンドプロンプトで、base64 ユーティリティを使用してログをデコードします。次の例は、my-functionの base64 でエンコードされたログを取得する方法を示しています 。

aws lambda invoke --function-name my-function out --log-type Tail \ --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode

AWS CLI バージョン 2 を使用している場合、cli-binary-format オプションは必須です。これをデフォルト設定にするには、aws configure set cli-binary-format raw-in-base64-out を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「AWS CLI でサポートされているグローバルコマンドラインオプション」を参照してください。

以下の出力が表示されます。

START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB

base64このユーティリティは、Linux、macOS、および Windows の Ubuntu で使用できます。macOS ユーザーは、base64 -Dを使用する必要があります 。

例 get-logs.sh スクリプト

同じコマンドプロンプトで、次のスクリプトを使用して、最後の 5 つのログイベントをダウンロードします。このスクリプトはsedを使用して出力ファイルから引用符を削除し、ログが使用可能になるまで15秒待機します。この出力には Lambda からのレスポンスと、get-log-events コマンドからの出力が含まれます。

次のコードサンプルの内容をコピーし、Lambda プロジェクトディレクトリに get-logs.sh として保存します。

AWS CLI バージョン 2 を使用している場合、cli-binary-format オプションは必須です。これをデフォルト設定にするには、aws configure set cli-binary-format raw-in-base64-out を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「AWS CLI でサポートされているグローバルコマンドラインオプション」を参照してください。

#!/bin/bash aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out sed -i'' -e 's/"//g' out sleep 15 aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
例 macOS および Linux (専用)

同じコマンドプロンプトで、macOS と Linux ユーザーが次のコマンドを実行して、スクリプトが実行可能であることを確認する必要があります。

chmod -R 755 get-logs.sh
例 最後の 5 つのログイベントを取得します

同じコマンドプロンプトで、次のスクリプトを実行して、最後の 5 つのログイベントを取得します。

./get-logs.sh

以下の出力が表示されます。

{ "StatusCode": 200, "ExecutedVersion": "$LATEST" } { "events": [ { "timestamp": 1559763003171, "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n", "ingestionTime": 1559763003309 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r \"key\": \"value\"\r}\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n", "ingestionTime": 1559763018353 } ], "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795", "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080" }

ログの解析と構造化ログ記録

CloudWatch Logs Insights を使用すると、特殊なクエリ構文を使用してログデータを検索および分析できます。複数のロググループに対してクエリを実行し、グロブおよび正規表現のパターンマッチングを使用した強力なフィルタリングを提供します。

Lambda 関数に構造化ログ記録を実装することにより、これらの機能を活用できます。構造化ログ記録はログを事前定義された形式に整理し、クエリを容易にします。ログレベルの使用は、情報メッセージを警告やエラーから分離するフィルター対応のログを生成するために重要な最初のステップです。例えば、次の Node.js コードの例を検討します。

exports.handler = async (event) => { console.log("console.log - Application is fine") console.info("console.info - This is the same as console.log") console.warn("console.warn - Application provides a warning") console.error("console.error - An error occurred") }

結果の CloudWatch ログファイルには、ログレベルを指定する個別のフィールドが含まれています。

モニタリングとオブザーバビリティの図 10

その後、CloudWatch Logs Insights クエリはログレベルでフィルタリングできます。例えば、エラーのみをクエリするには、次のクエリを使用できます。

fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc

JSON 構造化ログ記録

JSON は、アプリケーションログの構造を提供するために一般的に使用されます。次の例では、ログが JSON に変換されて 3 つの異なる値が出力されます。

モニタリングとオブザーバビリティの図 11

CloudWatch Logs Insights の機能により、JSON 出力の値が自動的に検出され、メッセージがフィールドとして解析されます。カスタムのグロブや正規表現は必要ありません。JSON 構造化ログを使用することで、次のクエリは、アップロードされたファイルが 1 MB を超え、アップロード時間が 1 秒を超え、呼び出しがコールドスタートではなかった呼び出しを検出します。

fields @message | filter @message like /INFO/ | filter uploadedBytes > 1000000 | filter uploadTimeMS > 1000 | filter invocation != 1

このクエリは、次のような結果を生成する場合があります。

モニタリングとオブザーバビリティの図 12

JSON で検出されたフィールドは、右側の検出されたフィールドメニューに自動的に入力されます。Lambda サービスによって発行された標準フィールドには「@」のプレフィックスが付けられ、同じ方法でこれらのフィールドをクエリできます。Lambda ログには、@timestamp、@logStream、@message、@requestId、@duration、@billedDuration、@type、@maxMemoryUsed、@memorySize フィールドが必ず含まれています。X-Ray が関数に対して有効になっている場合は、@xrayTraceId と @xraySegmentId もログに含まれています。

Amazon S3、Amazon SQS、Amazon EventBridge などの AWS イベントソースが関数を呼び出すと、イベント全体が JSON オブジェクト入力として関数に提供されます。関数の最初の行にこのイベントをログ記録することにより、CloudWatch Logs Insights を使用してネストされた任意のフィールドにクエリを実行できます。

便利な Insights クエリ

次の表に、Lambda 関数のモニタリングに役立つ Insights クエリの例を示しています。

説明 のクエリ構文の例

最後の 100 件のエラー

 fields Timestamp, LogLevel, Message
 | filter LogLevel == "ERR"
 | sort @timestamp desc
 | limit 100

請求された呼び出しの上位 100 件

filter @type = "REPORT"
| fields @requestId, @billedDuration
| sort by @billedDuration desc
| limit 100

合計呼び出し数でのコールドスタートの割合

filter @type = "REPORT"
| stats sum(strcontains(@message, "Init Duration"))/count(*) * 100 as
  coldStartPct, avg(@duration)
  by bin(5m)

Lambda 期間のパーセンタイルレポート

filter @type = "REPORT"
| stats
    avg(@billedDuration) as Average,
    percentile(@billedDuration, 99) as NinetyNinth,
    percentile(@billedDuration, 95) as NinetyFifth,
    percentile(@billedDuration, 90) as Ninetieth
    by bin(30m)

Lambda メモリ使用量のパーセンタイルレポート

filter @type="REPORT"
| stats avg(@maxMemoryUsed/1024/1024) as mean_MemoryUsed,
    min(@maxMemoryUsed/1024/1024) as min_MemoryUsed,
    max(@maxMemoryUsed/1024/1024) as max_MemoryUsed,
    percentile(@maxMemoryUsed/1024/1024, 95) as Percentile95

割り当てられたメモリの 100% を使用している呼び出し

filter @type = "REPORT" and @maxMemoryUsed=@memorySize
| stats
    count_distinct(@requestId)
    by bin(30m)

呼び出し全体で使用された平均メモリ

avgMemoryUsedPERC,
    avg(@billedDuration) as avgDurationMS
    by bin(5m)

メモリ統計の視覚化

filter @type = "REPORT"
| stats
    max(@maxMemoryUsed / 1024 / 1024) as maxMemMB,
    avg(@maxMemoryUsed / 1024 / 1024) as avgMemMB,
    min(@maxMemoryUsed / 1024 / 1024) as minMemMB,
    (avg(@maxMemoryUsed / 1024 / 1024) / max(@memorySize / 1024 / 1024)) * 100 as avgMemUsedPct,
    avg(@billedDuration) as avgDurationMS
    by bin(30m)

Lambda が終了した呼び出し

filter @message like /Process exited/
| stats count() by bin(30m)

タイムアウトした呼び出し

filter @message like /Task timed out/
| stats count() by bin(30m)

レイテンシーレポート

filter @type = "REPORT"
| stats avg(@duration), max(@duration), min(@duration)
  by bin(5m)

過剰プロビジョニングされたメモリ

filter @type = "REPORT"
| stats max(@memorySize / 1024 / 1024) as provisonedMemMB,
        min(@maxMemoryUsed / 1024 / 1024) as smallestMemReqMB,
        avg(@maxMemoryUsed / 1024 / 1024) as avgMemUsedMB,
        max(@maxMemoryUsed / 1024 / 1024) as maxMemUsedMB,
        provisonedMemMB - maxMemUsedMB as overProvisionedMB

ログの視覚化とダッシュボード

すべての CloudWatch Logs Insights クエリでは、結果をマークダウン形式または CSV 形式にエクスポートできます。場合によっては、少なくとも 1 つの集計関数があると、クエリから可視化を作成する方が便利なことがあります。stats 関数を使用すると、集計およびグループ化を定義できます。

前の logInsightsJSON の例では、アップロードサイズとアップロード時間でフィルタリングし、最初の呼び出しを除外していました。これにより、データのテーブルが作成されました。本番システムのモニタリングでは、最小、最大、平均のファイルサイズを視覚化して外れ値を見つける方が役立つ場合があります。これを行うには、必要な集計を使用して stats 関数を適用し、毎分などの時間値でグループ化します。

例えば、次のクエリを検討します。これは JSON 構造化ログ記録 セクションのクエリ例と同じですが、追加の集計関数があります。

fields @message | filter @message like /INFO/ | filter uploadedBytes > 1000000 | filter uploadTimeMS > 1000 | filter invocation != 1 | stats min(uploadedBytes), avg(uploadedBytes), max(uploadedBytes) by bin (1m)

最小、最大、平均のファイルサイズを視覚化して外れ値を見つける方が便利な場合があるため、これらの集計を含めました。結果は [可視化] タブで確認できます。

モニタリングとオブザーバビリティの図 14

視覚化の構築が完了したら、オプションでグラフを CloudWatch ダッシュボードに追加できます。これを行うには、視覚化の上にある [ダッシュボードに追加] を選択します。これにより、クエリがウィジェットとして追加され、自動更新間隔を選択できるため、結果を継続的にモニタリングしやすくなります。

モニタリングとオブザーバビリティの図 15