メニュー
AWS Lambda
開発者ガイド

Lambda ベースのアプリケーションのトラブルシューティング

典型的な Lambda ベースのアプリケーションは、Amazon S3 へのオブジェクトのアップロード、Amazon SNS 通知、および API アクションなどのイベントによってトリガーされる 1 つ以上の関数で構成されます。これらの関数がトリガーされると、通常、DynamoDB テーブルや Amazon S3 バケットなどのダウンストリームリソースが呼び出されるか、別の API 呼び出しが実行されます。AWS Lambda では、Amazon CloudWatch を利用して関数のすべての呼び出しのメトリックスとログを自動的に出力します。ただし、Lambda 関数を呼び出したイベントソースをトレースしたり、関数が実行したダウンストリーム呼び出しをトレースするには、このメカニズムがない方が便利な場合もあります。トレースがどのように機能するかについての完全な概要については、「AWS X-Ray」を参照してください。

AWS X-Ray を使用した Lambda ベースのアプリケーションのトレース

注記

これはプレビューリリースの機能に関するプレリリースドキュメントです。このドキュメントは変更される可能性があります。この機能を使用するには、サインアップは不要です。

AWS X-Ray は、AWS Lambda アプリケーションのパフォーマンスに関する問題を検出、分析、および最適化できる AWS のサービスです。X-Ray は、アプリケーションを構成する Lambda のサービスやアップストリームまたはダウンストリームサービスからメタデータを収集します。X-Ray はこのメタデータを使用して詳細なサービスグラフを生成します。これによりパフォーマンスのボトルネック、レイテンシーのスパイク、その他 Lambda アプリケーションに影響を及ぼす問題が図示されます。

AWS X-Ray サービスマップ上の Lambda 」を使用して問題のあるリソースやコンポーネントを識別したら、そのリクエストが視覚的に表現された部分を拡大して確認できます。この視覚化には、イベントソースが Lambda 関数をトリガーした時から関数の実行が完了されるまでが含まれます。X-Ray では、Lambda 関数が他のサービスに対して実行したダウンストリーム呼び出しに関する情報など、関数のオペレーションの内訳が提供されます。さらに、X-Ray を Lambda に統合することで、AWS Lambda サービスのオーバーヘッドが視認できるようになります。これは、リクエストのドウェル時間や呼び出し数などの詳細を表示することで行われます。

注記

現在 X-Ray と統合されているサービスのみが、Lambda トレースとは別にスタンドアロントレースとして表示されます。現在 X-Ray をサポートしているサービスのリストについては、X-Ray を参照してください。

AWS X-Ray の Lambda でのセットアップ

以下は、Lambda で X-Ray をセットアップする方法の詳細情報です。

開始する前に

Lambda CLI を使用した Lambda 関数のトレースを有効にするには、まず関数の実行ロールにトレース用のアクセス権限を追加する必要があります。これを行うには、次のステップを実行します。

  • IAM コンソール (https://console.aws.amazon.com/iam/) にサインインします。

  • Lambda 関数の実行ロールを見つけます。

  • 次の管理ポリシーをアタッチします。AWSXrayWriteOnlyAccess

これらのポリシーの詳細については、AWS X-Ray を参照してください。

Lambda コンソールを使用してトレースモードをアクティブに変更する場合は、トレース用アクセス権限が自動的に追加されます。詳しくは次のセクションを参照してください。

トレース

アプリケーションを経由するリクエストのパスは、トラック ID を使用して追跡されます。トレースでは、1 つのリクエスト (通常は HTTP GET または POST リクエスト) で生成されたセグメントをすべて収集します。

Lambda 関数のトレースには 2 つのモードがあります。

  • パススルー: 関数の実行ロールにトレース用のアクセス権限を追加している場合は、これがすべての Lambda 関数のデフォルト設定になります。この手法では、Lambda 関数は、AWS Elastic Beanstalk などのアップストリームサービスで X-Ray が有効になっている場合にのみトレースされます。

  • アクティブ: Lambda 関数にこの設定がある場合、Lambda は X-Ray によって指定されるサンプリングアルゴリズムに基づいて呼び出しリクエストを自動的にサンプリングします。

    注記

    X-Ray はサンプリングアルゴリズムを適用することで、トレースを効率的にしつつ、アプリケーションが処理するリクエストの代表的なサンプルを提供できるようにします。デフォルトのサンプリングアルゴリズムは 1 分間につき 1 リクエストで、この制限を超えた場合はリクエストの 5 パーセントがサンプリングされます。

Lambda 関数のトレースモードは、Lambda マネジメントコンソールを使用するか、Lambda CreateFunction API アクションまたは UpdateFunctionConfiguration API アクションを使用して変更できます。

Lambda コンソールを使用する場合は、次のようになります。

  • 関数のトレースモードをアクティブに変更すると、トレース用のアクセス権限が自動的に関数の実行ロールにアタッチされます。Lambda が [AWSLambdaTraceExecution] ポリシーを関数の実行ロールに追加できなかったというエラーを受け取った場合は、https://console.aws.amazon.com/iam/ の IAM コンソールにサインインして、手動でポリシーを追加してください。

  • アクティブなトレースを有効にするには、[Configure function] で [Advanced settings] を選択し、[Enable active tracing] ボックスを選択します。

Lambda CreateFunction API アクションまたは UpdateFunctionConfiguration API アクションを使用する場合:

注記

関数の実行ロールにトレース用のアクセス権限が追加されていない場合は、エラーが発生します。詳細については、「開始する前に」を参照してください。

  • トレースモードをアクティブにする場合は、TracingConfig パラメータの Mode プロパティを Active. に設定します。繰り返しになりますが、新規関数のトレースモードはデフォルトで PassThrough に設定されます。

  • 新規または更新された Lambda 関数は、指定された値に設定された $LATEST バージョンがあります。

AWS X-Ray サービスマップ上の Lambda

X-Ray では、Lambda で処理されるリクエストのサービスマップに 3 つのタイプのノードが表示されます。

  • Lambda サービス (AWS::Lambda) – このタイプのノードは、Lambda サービスでリクエストの処理にかかった時間を表します。時間は Lambda が最初にリクエストを受信したときに開始され、リクエストが Lambda サービスを離れたときに終了します。

  • Lambda 関数 (AWS::Lambda::Function) – このタイプのノードは Lambda 関数の実行時間を表します。

  • ダウンストリームサービス呼び出し – このタイプでは、Lambda 関数内からのお各ダウンストリームサービス呼び出が個別のノードで表されます。

次の図では、ノードは (左から右に) Lambda サービス、ユーザー関数、および Amazon S3 に対するダウンストリーム呼び出しを表します。

詳細については、サービスマップの表示を参照してください。

AWS X-Ray トレースとしての Lambda

サービスマップから拡大して Lambda 関数のトレースビューを表示できます。トレースには、関数呼び出しに関する詳細情報が、セグメントおよびサブセグメントとして表示されます。

  • Lambda サービスセグメント – このセグメントは、関数の呼び出しに使用されるイベントソースに応じて異なる情報を表します。

    • 同期とストリームイベントソース – サービスセグメントは Lambda サービスがリクエストやイベントを受信したときからリクエストが Lambda サービスを離脱したとき (リクエストの最後の呼び出しが完了した後) までを計測します。

    • 非同期 - サービスセグメントは応答時間を表します。つまり、Lambda サービスが 202 レスポンスをクライアントに返すまでにかかった時間です。

    Lambda サービスセグメントには、2 つのタイプのサブセグメントを含めることができます。

    • 度ウェル時間 (非同期呼び出しのみ) – 関数が呼び出される前に Lambda サービス内で経過した時間を表します。このサブセグメントは Lambda サービスがリクエストやイベントを受信したときに開始され、Lambda 関数が最初に呼び出されたときに終了します。

    • 試行 – 単一の呼び出し試行を表します。Lambda サービスによって導入されたオーバーヘッドを含みます。オーバーヘッドの例としては、関数のコードの初期化にかかった時間や関数の実行時間があります。

  • Lambda 関数セグメント - 指定された呼び出し試行における関数の実行時間を表します。関数ハンドラーが実行を開始したときから始まり、関数が終了すると終了します。このセグメントには 3 タイプのサブセグメントを含めることができます。

    • 初期化 - 関数の initialization コードの実行で経過した時間です。Lambda 関数ハンドラまたは静的イニシャライザ外部のコードとして定義されます。

    • ダウンストリーム呼び出し - Lambda 関数のコードから他の AWS のサービスに対する呼び出しです。

    • カスタムサブセグメント - X-Ray SDK を使用して Lambda 関数セグメントに追加できるカスタムサブセグメントまたはユーザーの注釈です。

注記

トレースされる各呼び出しについて、Lambda は Lambda サービスセグメントとそのすべてのサブセグメントを発行します。これらのセグメントはランタイムに関係なく発行され、コードの変更は不要です。

Lambda 関数からのトレースセグメントの発行

トレースされる各呼び出しについて、Lambda は Lambda サービスセグメントとそのすべてのサブセグメントを発行します。さらに、Lambda は Lambda 関数セグメントと init サブセグメントを発行します。これらのセグメントは関数のランタイムに関係なく発行され、コードの変更や追加のライブラリは必要ありません。Lambda 関数の X-Ray トレースにダウンストリーム呼び出しのカスタムセグメント、注釈、サブセグメントを含める場合は、追加のライブラリまたはコードの注釈を含める必要がある場合があります。

注記

現在、これらの追加機能 (ダウンストリーム呼び出しのカスタムセグメント、注釈、サブセグメント) は、Node.js ランタイムおよび Java ランタイムでのみ使用できます。

Node.js

Node.js では、Lambda によってサブセグメントを X-Ray に発行して、関数が行った他の AWS サービスへのダウンストリーム呼び出しに関する情報を表示できます。これを行うには、最初に AWS X-Ray SDK for Node.js をデプロイパッケージに含める必要があります。さらに、AWS SDK の require ステートメントを以下の方法でラップします。

Copy
var AWSXRay = require(‘aws-xray-sdk-core’); var AWS = AWSXRay.captureAWS(require(‘aws-sdk’));

次に、前の例で定義された AWS 変数を使用して、X-Ray でトレースするサービスクライアントを初期化します。次に例を示します。

Copy
s3Client = AWS.S3();

これらのステップに従うと、s3Client を使用して関数から行われた呼び出しがその呼び出しを表す X-Ray サブセグメントになります。例として、以下の Node.js 関数を実行し X-Ray でのトレースの様子を確認できます。

Copy
var AWSXRay = require('aws-xray-sdk-core'); var AWS = AWSXRay.captureAWS(require('aws-sdk')); s3 = new AWS.S3({signatureVersion: 'v4'}); exports.handler = (event, context, callback) => { var params = {Bucket: BUCKET_NAME, Key: BUCKET_KEY, Body: BODY}; s3.putObject(params, function(err, data) { if (err) { console.log(err) } else { console.log(‘success!’) } }); };

前述のコードによって発行されたトレースは以下のようになります (同期呼び出し)。

Java

Java では、Lambda によってサブセグメントを X-Ray に発行して、関数が行った他の AWS サービスへのダウンストリーム呼び出しに関する情報を表示できます。この機能を利用するには、AWS X-Ray SDK for Java をデプロイパッケージに含めます。コードの変更は必要ありません。AWS SDK バージョン 1.11.48 以前を使用している限り、トレースする関数からのダウンストリーム呼び出しにコード行を追加する必要はありません。

AWS SDK は X-Ray SDK を動的にインポートして、関数によって行われたダウンストリーム呼び出しのサブセグメントを発行します。X-RaySDK for Java を使用することで、カスタムサブセグメントの発行または X-Ray セグメントへの注釈の追加のためにコードを計測できます。

次の例では、X-Ray SDK for Java を使用して Lambda 関数を計測し、カスタムサブセグメントを発行して X-Ray にカスタム注釈を送信します。

Copy
package uptime; import java.io.IOException; import java.time.Instant; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import com.amazonaws.regions.Regions; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder; public class Hello { private static final Log logger = LogFactory.getLog(Hello.class); private static final AmazonDynamoDB dynamoClient; private static final HttpClient httpClient; static { dynamoClient = AmazonDynamoDBClientBuilder.standard().withRegion(Regions.US_EAST_1).build(); httpClient = HttpClientBuilder.create().build(); } public void checkUptime(Context context) { AWSXRay.createSubsegment("makeRequest", (subsegment) -> { HttpGet request = new HttpGet("https://aws.amazon.com/"); boolean is2xx = false; try { HttpResponse response = httpClient.execute(request); is2xx = (response.getStatusLine().getStatusCode() / 100) == 2; subsegment.putAnnotation("responseCode", response.getStatusLine().getStatusCode()); } catch (IOException ioe) { logger.error(ioe); } Map<String, AttributeValue> item = new HashMap<>(); item.put("Timestamp", new AttributeValue().withN("" + Instant.now().getEpochSecond())); item.put("2xx", new AttributeValue().withBOOL(is2xx)); dynamoClient.putItem("amazon-2xx", item); }); } }

前述のコードによって発行されたトレースは以下のようになります (同期呼び出し)。

Lambda 環境の AWS X-Ray デーモン

AWS X-Ray デーモンは、未加工セグメントデータを収集して AWS X-Ray サービスに受け渡すソフトウェアアプリケーションです。デーモンは SDK によって送信されたデータが X-Ray サービスに到達するように AWS X-Ray SDK と連動します。

Lambda 関数をトレースする場合、X-Ray デーモンが Lambda 環境で自動的に実行され、トレースデータが収集されて X-Ray に送信されます。トレース時は、X-Ray デーモンによって最大 16 MB または関数のメモリ割り当ての 3 パーセントが消費されます。たとえば、Lambda 関数に 128 MB のメモリを割り当てている場合、X-Ray デーモンが関数のメモリ割り当てのうち 16 MB を使用します。Lambda 関数に 1024 MB が割り当てられている場合、X-Ray デーモンには 31 MB (3 パーセント) が割り当てられます。詳細については、AWS X-Ray デーモンを参照してください。

注記

Lambda は関数のメモリ制限を超えないよう、X-Ray デーモンを終了しようとします。たとえば、Lambda 関数に 128 MB が割り当てられている場合、X-Ray デーモンには 16 MB が割り当てられます。つまり、Lambda 関数には 112 MB のメモリ割り当てが残ります。ただし、関数が 112 MB を超える場合、メモリ不足エラーがスローされないように X-Ray デーモンは終了されます。

環境変数を使用した AWS X-Ray との通信

AWS Lambda は自動的に X-Ray デーモンとの通信を容易にするために 3 つの環境変数を生成し、X-Ray SDK の構成を設定します。

  • _X_AMZN_TRACE_ID: サンプリングデシジョン、トレース ID および親セグメント ID が含まれるトレースヘッダーが含まれます。(これらのプロパティの詳細については、トレースヘッダーを参照してください。)関数が呼び出されたときに Lambda がトレースヘッダーを受信すると、ヘッダーは _X_AMZN_TRACE_ID 環境変数の入力に使用されます。トレースヘッダーが受信されない場合、Lambda がそれを生成します。

  • AWS_XRAY_CONTEXT_MISSING: X-Ray SDK はこの変数を使用して、関数が X-Ray データを記録しようとしたがトレーシングヘッダーを使用できない場合の動作を決定します。Lambda は、デフォルトでこの値を LOG_ERROR に設定します。

  • AWS_XRAY_DAEMON_ADDRESS: この環境変数は、X-Ray デーモンのアドレスを IP_ADDRESS:PORT 形式で表示します。X-Ray デーモンのアドレスを使用して、X-Ray SDK を使用せず X-Ray デーモンにトレースデータを直接送信できます。

AWS X-Ray コンソールでの Lambda トレース: 例

以下に、2 つの異なる Lambda 関数の Lambda トレースを示します。各トレースで、異なる呼び出しタイプ (同期と非同期) のトレース構造を説明します。

  • 非同期 - 以下は、正常呼び出し 1 回および DynamoDB へのダウンストリーム呼び出し 1 回を行う非同期 Lambda リクエストの例です。

    Lambda サービスセグメントは応答時間をカプセル化します。応答時間とは、クライアントにレスポンス (例: 202) を返すまでにかかった時間です。これには、Lambda サービスキューで経過した時間 (ドウェル時間) および各呼び出し試行のサブセグメントが含まれます。(前述の例では呼び出し試行は 1 つのみ表示されています。)サービスセグメント内の各試行サブセグメントには、対応するユーザー関数セグメントがあります。この例では、ユーザー関数セグメントには 2 つのサブセグメントがあります。ハンドラ前に実行される関数の初期化コードを表す初期化サブセグメントと、DynamoDB への ListTables 呼び出しを表すダウンストリーム呼び出しサブセグメントです。

    各呼び出しセグメントおよび各ダウンストリーム呼び出しごとにステータスコードおよびエラーメッセージが表示されます。

  • 同期 - 以下に Amazon S3 へのダウンストリーム呼び出し 1 回を行う同期リクエストの例を示します。

    Lambda サービスセグメントはリクエストが Lambda サービスで経過した時間全体をキャプチャします。サービスセグメントには、対応するユーザー関数セグメントがあります。この例では、ユーザー関数セグメントに関数の初期化コード (ハンドラ前に実行されるコード) を表すサブセグメントおよび Amazon S3 への PutObject 呼び出しを表すサブセグメントが含まれます。

注記

HTTP 呼び出しをトレースする場合は、HTTP クライアントを使用する必要があります。詳細については、X-Ray SDK for Java を使用してダウンストリーム HTTP ウェブサービスの呼び出しをトレースするまたは X-Ray SDK for Node.js を使用してダウンストリーム HTTP ウェブサービスの呼び出しをトレースするを参照してください。