この記事は英語の原文を日本語に翻訳したものです。原文: https://opentelemetry.io/docs/specs/semconv/faas/aws-lambda/

翻訳元: open-telemetry/semantic-conventions v1.44.0(コミット e10a930

AWS Lambdaの計装

ステータス: Development

この文書では、AWS Lambdaのリクエストハンドラーを計装する際にセマンティック規約を適用する方法を定義します。AWS Lambdaは、FaaSの規約に大きく従いつつ、ハンドラーがHTTPリクエストを処理する場合はHTTPの規約も適用されます。

Lambda関数にはさまざまなトリガーがあり、この文書は時間の経過とともにすべての使用例を対象とするよう拡張されます。

すべてのトリガー

すべてのイベントについて、以下で特に述べない限り、関数呼び出しに対応するSERVER種別のスパンが作成されるべきです(SHOULD)。

次の属性が設定されるべきです(SHOULD)。

  • faas.invocation_id - AWS Request IDの値。これは、LambdaのContext上のアクセサから常に取得できます。
  • cloud.account.id - 言語によっては、これはLambdaのContext上のアクセサから取得できます。それ以外の場合は、ARNを:で分割して5番目の項目として解析できます。

Status: Development

このスパンは、AWS Lambdaの呼び出しを表します。

faasリソーストレースの規約、およびクラウドリソースの規約の他の属性も設定することを検討してください。

スパン名は、特に述べない限り、LambdaのContextから取得した関数名に設定しなければなりません(MUST)。

スパン種別は、特に述べない限り、SERVERでなければなりません(MUST)。

スパンステータスエラーの記録文書に従うべきです(SHOULD)。

Attributes:

KeyStabilityRequirement LevelValue TypeDescriptionExample Values
aws.lambda.invoked_arnDevelopmentRecommendedstring関数に渡されたContext上で提供される、呼び出し元の完全なARN(/runtime/invocation/nextが該当する場合のLambda-Runtime-Invoked-Function-Arnヘッダー)。[1]arn:aws:lambda:us-east-1:123456:function:myfunction:myalias
aws.lambda.resource_mapping.idDevelopmentRecommendedstringAWS Lambda EventSource MappingのUUID。イベントソースはLambda関数にマッピングされます。その内容はLambdaによって読み取られ、関数をトリガーするために使用されます。これはLambdaの実行コンテキストやLambdaランタイム環境では利用できません。これは、そのUUIDが存在する場合に各言語のAWS SDKによって設定されます。これに関連する操作には、Create/Delete/Get/List/Update EventSourceMappingなどがあります。587ad24b-03b9-4413-8202-bbd56b36e5b7

[1] aws.lambda.invoked_arn: エイリアスが関わる場合、これはcloud.resource_idと異なる場合があります。

AWS X-Rayのアクティブトレーシングに関する考慮事項

LambdaでAWS X-Rayのアクティブトレーシングが有効になっている場合、ランタイムは設定済みのサンプリングレートに基づいて自動的にスパンを生成し、_X_AMZN_TRACE_ID環境変数(およびJava Lambda関数の場合はcom.amazonaws.xray.traceHeaderシステムプロパティ)を介してスパンコンテキストを伝搬します。 このスパンコンテキストは、X-Ray Tracing Header Formatを使ってエンコードされます。

ユーザーは、このX-Rayの「アクティブトレーシング」スパンコンテキストの伝搬を優先するようプロパゲーターを設定できなければなりません(MUST)。 (参考: OpenTelemetryがAWS X-Rayへのスパン報告用に設定されている場合、トレースを正しくリンクさせるためにこれを有効にすることをおそらく望むでしょう。)

xray-lambdaプロパゲーターの機能

AWS Lambdaの計装を持つSDKは、X-Rayプロパゲーターに加えて、OTEL_PROPAGATORS環境変数の設定でxray-lambdaとして設定できる追加のプロパゲーターを提供すべきです(SHOULD)。 このプロパゲーターは、OTEL_PROPAGATORSリスト内のxrayプロパゲーターを置き換えることが期待されています。このプロパゲーターの挙動は、以下の疑似コードで説明されています。

extract(context, carrier) {
    xrayContext = xrayPropagator.extract(context, carrier)

    // To avoid potential issues when extracting with an active span context (such as with a span link),
    // the `xray-lambda` propagator SHOULD check if the provided context already has an active span context.
    // If found, the propagator SHOULD just return the extract result of the `xray` propagator.
    if (Span.fromContext(context).getSpanContext().isValid())
      return xrayContext

    // If xray-lambda environment variable not set, return the xray extract result.
    traceHeader = getEnvironment("_X_AMZN_TRACE_ID")
    if (isEmptyOrNull(traceHeader))
      return xrayContext

    // Apply the xray propagator using the span context contained in the xray-lambda environment variable.
    return xrayPropagator.extract(xrayContext, ["X-Amzn-Trace-Id": traceHeader])
}

注記: Java実装では、システムプロパティが空でない場合、環境変数の代わりにcom.amazonaws.xray.traceHeaderというキーのシステムプロパティの値を使用すべきです(should)。

xray-lambdaプロパゲーターの設定

AWS LambdaからAWS X-Rayへスパンを報告する場合xray-lambdaプロパゲーターはOTEL_PROPAGATORSの設定内でxrayプロパゲーターを置き換えるべきです(SHOULD)。両方を含めると、xray-lambdaが正しく機能しなくなります。

AWS X-Rayへスパンを報告する場合の有効な設定例。

  • OTEL_PROPAGATORS=tracecontext,baggage,xray-lambda

無効な設定例。

  • OTEL_PROPAGATORS=tracecontext,baggage,xray,xray-lambda
  • OTEL_PROPAGATORS=tracecontext,baggage,xray-lambda,xray

OpenTelemetryがAWS X-Ray以外の別のシステムにトレースを報告している場合、ユーザーはxray-lambdaを使用すべきではありません(SHOULD NOT)。使用すると報告されるトレースが壊れてしまいます。

OpenTelemetryがAWS X-Ray以外の別のシステムにトレースを報告している場合の有効な設定例。

  • OTEL_PROPAGATORS=tracecontext,baggage,xray

API Gateway

API Gatewayを使うと、ユーザーはHTTPリクエストへの応答としてLambda関数をトリガーできます。これは、元のHTTPリクエストに関する情報がLambda関数に渡される純粋なプロキシとして設定することも、REST APIの設定として、デシリアライズされたボディのペイロードのみが利用可能になるように設定することもできます。APIゲートウェイがLambda関数へのプロキシとして設定されている場合、計装されたリクエストハンドラーは、API Gateway Proxy Request Eventの形式でHTTPリクエストに関するすべての情報にアクセスできます。

Lambdaのスパン名とhttp.routeスパン属性は、プロキシリクエストイベントのresourceプロパティに設定されるべきです(SHOULD)。これは、関数名の代わりに、ユーザーが設定したHTTPルートに対応します。

faas.triggerhttpに設定しなければなりません(MUST)。HTTP属性は、プロキシリクエストによって開始されたLambdaイベント内で利用可能な情報に基づいて設定されるべきです(SHOULD)。http.schemeは、Lambdaイベント内のx-forwarded-protoヘッダーとして利用可能です。詳細は、入力イベント形式を参照してください。

SQS

Amazon Simple Queue Service(SQS)は、メッセージのバッチでLambda関数をトリガーするメッセージキューです。 そのため、バッチ全体の処理と個々のメッセージの処理の両方を考慮します。関数呼び出しのスパンは、メッセージのバッチであるSQSイベントに対応しなければなりません(MUST)。各メッセージについて、そのSQSメッセージの処理に対応する追加のスパンが作成されるべきです(SHOULD)。メッセージの処理はLambdaフレームワークではなくユーザーのビジネスロジックの内部で行われるため、コード変更を伴わない自動計装の仕組みでは、個々のメッセージの処理を計装できないことが多いです。計装は、ユーザーコード内でメッセージ処理スパンを作成するためのユーティリティを提供すべきです(SHOULD)。

両方の種類のSQSスパンについて、スパン種別はCONSUMERであるべきです(SHOULD)。

SQSイベント

SQSイベントスパンについて、イベント内のすべてのメッセージが同じイベントソースを持つ場合、スパンの名前は<event source> processでなければなりません(MUST)。バッチ内に複数のソースがある場合、名前はmultiple_sources processでなければなりません(MUST)。親は、関数呼び出しに対応するSERVERスパンであるべきです(SHOULD)。

イベント内のすべてのメッセージについて、(ユーザーが提供するメッセージ属性ではなく)メッセージシステム属性AWSTraceHeaderキーを確認すべきです(SHOULD)。存在する場合、その属性の値からAWS X-Ray Propagatorを使ってOpenTelemetryのContextを解析し、スパンへのリンクとして追加すべきです(SHOULD)。つまり、スパンはバッチ内のメッセージ数と同じ数のリンクを持つ場合があります。 詳細は互換性を参照してください。

SQSメッセージ

SQSメッセージスパンについて、名前は<event source> processでなければなりません(MUST)。親は、SQSイベントに対応するCONSUMERスパンでなければなりません(MUST)。(ユーザーが提供するメッセージ属性ではなく)メッセージシステム属性AWSTraceHeaderキーを確認すべきです(SHOULD)。存在する場合、その属性の値からAWS X-Ray Propagatorを使ってOpenTelemetryのContextを解析し、スパンへのリンクとして追加すべきです(SHOULD)。 詳細は互換性を参照してください。

メッセージングスパン向けに定義されているその他の属性は、SQSメッセージイベント内で利用可能な情報に基づいて設定されるべきです(SHOULD)。

AWSTraceHeaderは、他のソースとの競合を避けるため、SQS計装でContextを伝搬するための唯一のサポートされた仕組みであることに注意してください。特に、(システムではなく)ユーザーが提供するメッセージ属性はサポートされていません。リンクされたコンテキストは、常にメッセージの発生元となったSQS.SendMessageリクエストのHTTPヘッダーとして送信されていることが期待されます。これはLambda計装の機能ではなく、AWS SDK計装の機能です。

AWSTraceHeaderを使用することで、たとえばS3 -> SNS -> SQS -> Lambdaというフローのように、SQSを介してLambdaに統合されうるAWSサービス間で伝搬が機能することが保証されます。AWSTraceHeaderはコンテキストを伝搬する手段の一つに過ぎず、特定のオブザーバビリティバックエンドに紐づいたものではありません。特に、これを使用することはAWS X-Rayの使用を意味しません。どのオブザーバビリティバックエンドでも、この伝搬機構を使って完全に機能します。

API Gatewayリクエストプロキシ(Lambdaトレーシング パッシブ)

プロセスCが、Lambda関数Fのために設定されたパス/pets/{petId}のAPI Gatewayエンドポイントに、HTTPリクエストを送信する場合を考えます。

Process C: | Span Client        |
--
Function F:    | Span Function |
Field or AttributeSpan ClientSpan Function
Span nameHTTP GET/pets/{petId}
ParentSpan Client
SpanKindCLIENTSERVER
StatusOkOk
faas.invocation_id79104EXAMPLEB723
faas.triggerhttp
cloud.account.id12345678912
server.addressfoo.execute-api.us-east-1.amazonaws.com
server.port413
http.request.methodGETGET
user_agent.originalokhttp 3.0okhttp 3.0
url.schemehttps
url.path/pets/10
http.route/pets/{petId}
http.response.status_code200200

API Gatewayリクエストプロキシ(Lambdaトレーシング アクティブ)

Lambdaのアクティブトレーシングとは、API GatewayのスパンSpan APIGWとLambdaランタイムの呼び出しスパンSpan Lambdaが、(計装ではなく)インフラストラクチャによってAWS X-Rayにエクスポートされることを意味します。上記のすべての属性は同じですが、この場合、APIGWの親はSpan Clientであり、Span Functionの親はSpan Lambdaである点が異なります。つまり、階層は次のようになります。

Span Client --> Span APIGW --> Span Lambda --> Span Function

SQS(Lambdaトレーシング パッシブ)

プロセスPが、SQS上のキューQに2つのメッセージを送信し、Lambda関数Fが、その両方を1つのバッチで処理する(Span ProcBatch)とともに、各メッセージに対して個別に処理スパンを生成する(Span Proc1とSpan Proc2)場合を考えます。

Process P: | Span Prod1 | Span Prod2 |
--
Function F:                      | Span ProcBatch |
                                        | Span Proc1 |
                                               | Span Proc2 |
Field or AttributeSpan Prod1Span Prod2Span ProcBatchSpan Proc1Span Proc2
Span namesend Qsend Qprocess Qprocess Qprocess Q
ParentSpan ProcBatchSpan ProcBatch
LinksSpan Prod1Span Prod2
SpanKindPRODUCERPRODUCERCONSUMERCONSUMERCONSUMER
StatusOkOkOkOkOk
messaging.systemaws_sqsaws_sqsaws_sqsaws_sqsaws_sqs
messaging.destination.nameQQQQQ
messaging.operation.namesendsendprocessprocessprocess
messaging.operation.typepublishpublishprocessprocessprocess
messaging.message.id"a1""a2"

Span Prod1とSpan Prod2が異なるキューに送信された場合、Span ProcBatchは複数のキューに対応することになるため、messaging.destination.nameは設定されないことに注意してください。

上記のSpan Proc1Span Proc2を作成するには、ユーザーコードの変更が必要です。Javaでは、これらを有効にするために、ユーザーはLambdaの標準のRequestHandlerではなくTracingSqsMessageHandlerを継承します。そうしなければ、これら2つのスパンは存在しません。

SQS(Lambdaトレーシング アクティブ)

Lambdaのアクティブトレーシングとは、Lambdaランタイムの呼び出しスパンSpan Lambdaが、(計装ではなく)インフラストラクチャによってX-Rayにエクスポートされることを意味します。この場合、Span ProcBatchの親がSpan Lambdaになる点を除いて、上記のすべてが同じです。つまり、階層は次のようになります。

Span Lambda --> Span ProcBatch --> Span Proc1 (links to Span Prod1 and Span Prod2)
                               \-> Span Proc2 (links to Span Prod1 and Span Prod2)

リソース検出器

AWS Lambdaのリソース情報は、ランタイムが提供する環境変数として利用可能です。

  • cloud.providerawsに設定しなければなりません(MUST)。
  • cloud.regionAWS_REGION環境変数の値に設定しなければなりません(MUST)。
  • faas.nameAWS_LAMBDA_FUNCTION_NAME環境変数の値に設定しなければなりません(MUST)。
  • faas.versionAWS_LAMBDA_FUNCTION_VERSION環境変数の値に設定しなければなりません(MUST)。

cloud.resource_idは、関数呼び出しまで利用できないため、現時点ではリソースとして設定できないことに注意してください。