Lambdaトレーシングのサブセクション セットアップ
前提条件 Observability ワークショップインスタンス Observabilityワークショップは、多くの場合、Splunkが提供する事前設定済みのUbuntu EC2インスタンス上で実施されます。
ワークショップのインストラクターから、割り当てられたワークショップインスタンスの認証情報が提供されます。
インスタンスには以下の環境変数が既に設定されているはずです
ACCESS_TOKEN REALM これらはワークショップ用の Splunk Observability Cloud の Access Token と Realm です。 これらは OpenTelemetry Collector によって、データを正しい Splunk Observability Cloud 組織に転送するために使用されます。 また、Multipass を使用してローカルの Observability ワークショップインスタンスをデプロイすることもできます。
AWS Command Line Interface (awscli) AWS Command Line Interface、または awscli は、AWSリソースと対話するために使用されるAPIです。このワークショップでは、特定のスクリプトがデプロイするリソースと対話するために使用されます。
Splunkが提供するワークショップインスタンスには、既に awscli がインストールされているはずです。
Terraformは、リソースを構成ファイルで定義することで、デプロイ、管理、破棄するためのInfrastructure as Code(IaC)プラットフォームです。TerraformはHCLを使用してこれらのリソースを定義し、さまざまなプラットフォームやテクノロジのための複数のプロバイダーをサポートしています。
このワークショップでは、コマンドラインでTerraformを使用して、以下のリソースをデプロイします
AWS API Gateway Lambda関数 Kinesis Stream CloudWatchロググループ S3バケット Splunkが提供するワークショップインスタンスには、既に terraform がインストールされているはずです。
ワークショップディレクトリ (o11y-lambda-workshop) ワークショップディレクトリ o11y-lambda-workshop は、今日使用する例のLambdaベースのアプリケーションの自動計装と手動計装の両方を完了するための、すべての設定ファイルとスクリプトを含むリポジトリです。
git clone https://github.com/gkono-splunk/o11y-lambda-workshop.git AWS AWSのCLIでは、サービスによってデプロイされたリソースにアクセスし管理するための認証情報が必要です。このワークショップでは、TerraformとPythonスクリプトの両方がタスクを実行するためにこれらの変数を必要とします。
Terraformでは、機密情報や動的データを.tf設定ファイルにハードコーディングさせない、またはそれらの値をリソース定義全体で再利用できるようにするため、変数の受け渡しをサポートしています。
このワークショップでは、OpenTelemetry Lambda layerの適切な値でLambda関数をデプロイするため、Splunk Observability Cloudの取り込み値のため、そして環境とリソースを独自で即座に認識できるようにするための変数をTerraformで必要とします。
Terraform変数(variable)は以下の方法で定義されます
変数を main.tf ファイルまたは variables.tf に定義する 以下のいずれかの方法で変数の値を設定するホストレベルで環境変数を設定し、その定義と同じ変数名を使用して、接頭辞として TF_VAR をつける terraform.tfvars ファイルに変数の値を設定するterraform apply実行時に引数として値を渡す このワークショップでは、variables.tf と terraform.tfvars ファイルの組み合わせを使用して変数を設定します。
vi または nano のいずれかを使用して、auto または manual ディレクトリにある terraform.tfvars ファイルを開きます
vi ~/o11y-lambda-workshop/auto/terraform.tfvars 変数に値を設定します。CHANGEME プレースホルダーをインストラクターから提供された値に置き換えてください。
o11y_access_token = "CHANGEME"
o11y_realm = "CHANGEME"
otel_lambda_layer = [ "CHANGEME" ]
prefix = "CHANGEME" 引用符(")や括弧 ( [ ] ) はそのまま残し、プレースホルダーCHANGEME のみを変更してください。 prefix は、他の参加者のリソースと区別するため、任意の文字列で設定する固有の識別子です。氏名やメールアドレスのエイリアスを使用することをお勧めします。prefix には小文字のみを使用してください。S3 のような特定の AWS リソースでは、大文字を使用するとエラーが発生します。ファイルを保存してエディタを終了します。
最後に、編集した terraform.tfvars ファイルを他のディレクトリにコピーします。
cp ~/o11y-lambda-workshop/auto/terraform.tfvars ~/o11y-lambda-workshop/manual これは、自動計装と手動計装の両方の部分で同じ値を使用するためです ファイル権限 他のすべてのファイルはそのままでよいですが、auto と manual の両方にあるsend_message.py スクリプトは、ワークショップの一部として実行する必要があります。そのため、期待通りに実行するには、適切な権限が必要です。以下の手順に従って設定してください。
これで前提条件が整いましたので、ワークショップを始めることができます!
自動計装 ワークショップの最初の部分では、OpenTelemetryによる自動計装がどのようにしてOpenTelemetry Collectorに関数がどの言語で書かれているかを自動検出させ、それらの関数のトレースの取得を開始させるかを示します。
自動計装ワークショップディレクトリとコンテンツ まず、o11y-lambda-workshop/auto ディレクトリとそのファイルの一部を見てみましょう。ここにはワークショップの自動計装部分のすべてのコンテンツがあります。
auto ディレクトリmain.tf ファイル
ワークショップの質問このテンプレートによってどのAWSリソースが作成されているか特定できますか? OpenTelemetry計装がどこでセットアップされているか特定できますか?ヒント: Lambda 関数の定義を調べてください 以前に設定した環境変数によってどの計装情報が提供されているか判断できますか? 各Lambda関数の環境変数が設定されているセクションが見つかるはずです。
environment {
variables = {
SPLUNK_ACCESS_TOKEN = var.o11y_access_token
SPLUNK_REALM = var.o11y_realm
OTEL_SERVICE_NAME = "producer-lambda"
OTEL_RESOURCE_ATTRIBUTES = "deployment.environment= ${ var .prefix } -lambda-shop"
AWS_LAMBDA_EXEC_WRAPPER = "/opt/nodejs-otel-handler"
KINESIS_STREAM = aws_kinesis_stream.lambda_streamer.name
}
} これらの環境変数を使用することで、いくつかの方法で自動計装を構成しています
環境変数を設定して、データのエクスポート先となるSplunk Observability Cloud組織をOpenTelemetry collectorに伝えています。
SPLUNK_ACCESS_TOKEN = var.o11y_access_token
SPLUNK_ACCESS_TOKEN = var.o11y_realmまた、OpenTelemetryが関数/サービスを識別し、それが属する環境/アプリケーションを認識するのに役立つ変数も設定しています。
OTEL_SERVICE_NAME = "producer-lambda" # consumer関数の場合はconsumer-lambda
OTEL_RESOURCE_ATTRIBUTES = "deployment.environment= ${ var .prefix } -lambda-shop" コード言語に基づいて、関数のハンドラーに自動的にトレースデータを取得するために適用する必要があるラッパーをOpenTelemetryに知らせる環境変数を設定しています。
AWS_LAMBDA_EXEC_WRAPPER - "/opt/nodejs-otel-handler" producer-lambda 関数の場合、レコードを配置するKinesisストリームを関数に知らせるための環境変数を設定しています。
KINESIS_STREAM = aws_kinesis_stream.lambda_streamer.nameこれらの値は、「前提条件」セクションで設定した環境変数、および、このTerraform構成ファイルの一部としてデプロイされるリソースから取得されます。
また、各関数にSplunk OpenTelemetry Lambda layerを設定する引数も確認できるはずです
layers = var.otel_lambda_layerproducer.mjs ファイル次に、producer-lambda 関数のコードを見てみましょう
Lambda 関数のデプロイとトレースデータの生成 auto ディレクトリの内容に慣れたところで、ワークショップ用のリソースをデプロイし、Lambda関数からトレースデータを生成していきます。
main.tf ファイルで定義されたリソースをデプロイするには、まずTerraformがそのファイルと同じフォルダで初期化されていることを確認する必要があります。
Lambda 関数とその他の AWS リソースをデプロイする このディレクトリでTerraformを初期化したら、リソースのデプロイに進むことができます。
producer-lambda URL (base_url) にトラフィックを送信するデプロイしたLambda関数からトレースを取得し始めるには、トラフィックを生成する必要があります。producer-lambda 関数のエンドポイントにメッセージを送信し、それをKinesisストリームにレコードとして配置し、その後 consumer-lambda 関数によってストリームから取得されるようにします。
send_message.py スクリプトは、コマンドラインで入力を受け取り、JSONディクショナリに追加し、whileループの一部として producer-lambda 関数のエンドポイントに繰り返し送信するPythonスクリプトです。
重要この場合は、ワークショップ進行役の一人に支援を求めてください。
Lambda 関数のログを表示する 次に、Lambda関数のログを確認しましょう。
ログを注意深く調べてください。
ワークショップの質問OpenTelemetryが読み込まれているのが見えますか?splunk-extension-wrapper のある行に注目してくださいsplunk-extension-wrapper が読み込まれているのを見るために head -n 50 producer.logs または head -n 50 consumer.logs の実行を検討してください。 Splunk APM、Lambda関数およびトレース Lambda関数は相当量のトレースデータを生成しているはずで、それを確認する必要があります。Lambda関数のリソース定義で構成された環境変数とOpenTelemetry Lambda layerの組み合わせにより、Splunk APMで関数とトレースを表示する準備が整いました。
Splunk APM 概要で環境名を確認する まず、Splunk APMが受信しているトレースデータから Environment を認識していることを確認しましょう。これは main.tf のLambda関数定義で設定した OTEL_RESOURCE_ATTRIBUTES 変数の一部として設定した deployment.name です。これは先ほど実行した terraform apply コマンドの出力の1つでもありました。
Splunk Observability Cloudで
メモトレースが Splunk APM に表示されるまで数分かかる場合があります。環境のリストにあなたの環境名が表示されるまで、ブラウザの更新ボタンを押してみてください
環境のサービスマップを表示する Environmentドロップダウンから環境名を選択したら、Lambda関数のサービスマップを確認できます。
APM概要ページの右側にある Service Map ボタンをクリックします。これによりサービスマップビューに移動します。
producer-lambda 関数とそのレコードを配置するためにKinesisストリームに対して行っている呼び出しが表示されるはずです。
ワークショップの質問あなたの consumer-lambda 関数はどうなっていますか?
Lambda 関数からのトレースを調査する Traces ボタンをクリックしてトレースアナライザーを表示します。
このページでは、producer-lambda 関数のOpenTelemetry Lambda layerから取り込まれたトレースを確認できます。
リストからハイパーリンクされた Trace ID をクリックして、調査するトレースを選択します。
producer-lambda 関数がKinesisストリームにレコードを配置しているのが確認できます。しかし、consumer-lambda 関数のアクションが見当たりません!
これはトレースコンテキストが伝播されていないためです。このワークショップの時点では、Kinesisサービスはトレースコンテキスト伝播をすぐには対応していません。分散トレースはKinesisサービスで止まっており、そのコンテキストがストリームを通じて自動的に伝播されないため、それ以上先を見ることができません。
少なくとも、今はまだ…
次のセクションでこの問題にどう対処するか見ていきましょう。しかしその前に、後片付けをしましょう!
クリーンアップ この自動計装演習の一部としてデプロイしたリソースはクリーンアップする必要があります。同様に、producer-lambda エンドポイントに対してトラフィックを生成していたスクリプトも、まだ実行中であれば停止する必要があります。以下の手順に従ってクリーンアップを行ってください。
send_message の停止全ての AWS リソースを破棄する Terraformは個々のリソースの状態をデプロイメントとして管理するのに優れています。定義に変更があっても、デプロイされたリソースを更新することもできます。しかし、一からやり直すために、リソースを破棄し、このワークショップの手動計装部分の一部として再デプロイします。
以下の手順に従ってリソースを破棄してください
このプロセスにより、私たちの活動の結果として作成されたファイルとディレクトリは残ります。それらについては心配する必要はありません。
手動計装 ワークショップの第2部では、OpenTelemetryによる手動計装が計測データ収集を強化する方法を実演することに焦点を当てます。より具体的には、今回のケースでは、producer-lambda 関数から consumer-lambda 関数にトレースコンテキストデータを伝播させることができるようになります。これにより、現在は自動コンテキスト伝播をサポートしていないKinesisストリームを介しても、2つの関数間の関係を見ることができるようになります。
手動計装ワークショップディレクトリとコンテンツ 再度、作業ディレクトリとそのファイルの一部を確認することから始めます。今回は o11y-lambda-workshop/manual ディレクトリです。ここにはワークショップの手動計装部分のすべてのコンテンツがあります。
manual ディレクトリ
ワークショップの質問このディレクトリと最初に始めたautoディレクトリに何か違いがありますか?
auto と manual のファイルを比較する見た目が同じように見えるこれらのファイルが実際に同じかどうか確認しましょう。
auto と manual ディレクトリの main.tf ファイルを比較します
diff ~/o11y-lambda-workshop/auto/main.tf ~/o11y-lambda-workshop/manual/main.tf 違いはありません!(違いがあるはずはありません。もし違いがあれば、ワークショップ進行役に支援を求めてください) 次に、producer.mjs ファイルを比較してみましょう
diff ~/o11y-lambda-workshop/auto/handler/producer.mjs ~/o11y-lambda-workshop/manual/handler/producer.mjs ファイル全体を表示してその内容を調べたい場合は以下を実行します
cat ~/o11y-lambda-workshop/handler/producer.mjs 必要な手動計装タスクを処理するために、いくつかのOpenTelemetryオブジェクトを関数に直接インポートしていることに注目してください。 import { context , propagation , trace } from "@opentelemetry/api" ; 最後に、consumer.mjs ファイルを比較します
diff ~/o11y-lambda-workshop/auto/handler/consumer.mjs ~/o11y-lambda-workshop/manual/handler/consumer.mjs プロデューサー関数からのトレースコンテキスト伝播 以下のコードはプロデューサー関数内で次のステップを実行します
このトレース用のトレーサーを取得する コンテキストキャリアオブジェクトを初期化する アクティブスパンのコンテキストをキャリアオブジェクトに注入する Kinesisストリームに配置しようとしているレコードを修正し、アクティブスパンのコンテキストをコンシューマーに運ぶキャリアを含める ...
import { context , propagation , trace , } from "@opentelemetry/api" ;
...
const tracer = trace . getTracer ( 'lambda-app' );
...
return tracer . startActiveSpan ( 'put-record' , async ( span ) => {
let carrier = {};
propagation . inject ( context . active (), carrier );
const eventBody = Buffer . from ( event . body , 'base64' ). toString ();
const data = "{\"tracecontext\": " + JSON . stringify ( carrier ) + ", \"record\": " + eventBody + "}" ;
console . log (
`Record with Trace Context added:
${ data } `
);
try {
await kinesis . send (
new PutRecordCommand ({
StreamName : streamName ,
PartitionKey : "1234" ,
Data : data ,
}),
message = `Message placed in the Event Stream: ${ streamName } `
)
...
span . end (); コンシューマー関数でのトレースコンテキスト抽出 以下のコードはコンシューマー関数内で次のステップを実行します
producer-lambda から取得したコンテキストをキャリアオブジェクトに抽出する現在のコンテキストからトレーサーを抽出する 抽出したコンテキスト内でトレーサーを使用して新しいスパンを開始する ボーナス:メッセージからの値を含むカスタム属性など、追加の属性をスパンに追加する! 完了したら、スパンを終了する import { propagation , trace , ROOT_CONTEXT } from "@opentelemetry/api" ;
...
const carrier = JSON . parse ( message ). tracecontext ;
const parentContext = propagation . extract ( ROOT_CONTEXT , carrier );
const tracer = trace . getTracer ( process . env . OTEL_SERVICE_NAME );
const span = tracer . startSpan ( "Kinesis.getRecord" , undefined , parentContext );
span . setAttribute ( "span.kind" , "server" );
const body = JSON . parse ( message ). record ;
if ( body . name ) {
span . setAttribute ( "custom.tag.name" , body . name );
}
if ( body . superpower ) {
span . setAttribute ( "custom.tag.superpower" , body . superpower );
}
...
span . end (); これでどのような違いが生まれるか見てみましょう!
Lambda関数のデプロイとトレースデータの生成 トレースデータを収集したい関数やサービスに手動計装を適用する方法がわかったので、Lambda関数を再度デプロイして、producer-lambda エンドポイントに対するトラフィックを生成していきましょう。
新しいディレクトリにいるので、ここでもう一度Terraformを初期化する必要があります。
Lambda 関数とその他の AWS リソースをデプロイする それでは、これらのリソースを再度デプロイしましょう!
見ての通り、base_urlの最初の部分とログループARN以外は、このワークショップの自動計装部分をこの同じ時点まで実行したときと出力は概ね同じはずです。
producer-lambda エンドポイント (base_url) にトラフィックを送信するもう一度、name と superpower をメッセージとしてエンドポイントに送信します。これはトレースコンテキストとともに、Kinesisストリーム内のレコードに追加されます。
manual ディレクトリにいることを確認します
予想される出力は ~/o11y-lambda-workshop/manual です manual ディレクトリにいない場合は、次のコマンドを実行します
cd ~/o11y-lambda-workshop/manualsend_message.py スクリプトをバックグラウンドプロセスとして実行します
nohup ./send_message.py --name CHANGEME --superpower CHANGEME & 次に、response.logsファイルの内容を確認して、producer-lambda エンドポイントへの呼び出しが成功しているか確認します
重要これが発生した場合は、ワークショップ進行役の一人に支援を求めてください。
Lambda 関数のログの確認 ログがどのようになっているか見てみましょう。
ログを注意深く調べてください。
ワークショップの質問 違いに気づきましたか?
consumer-lambda ログからのトレース ID のコピー今回は、consumer-lambdaのロググループが、我々が伝播した tracecontext とともに、メッセージを record としてログに記録しているのが確認できます。
トレースIDをコピーするには
Kinesis Message ログの1つを見てみましょう。その中には data ディクショナリがありますネストされた tracecontext ディクショナリを見るために、data をより詳しく見てください tracecontext ディクショナリ内には、traceparent というキーと値のペアがありますtraceparent キーと値のペアには、私たちが探しているトレースIDが含まれています- で区切られた4つの値のグループがあります。トレースIDは2番目の文字グループですトレース ID をコピーして保存してください。 このワークショップの後のステップで必要になります
Splunk APM、Lambda関数とトレース、再び! ログの外部でコンテキスト伝播の結果を確認するために、もう一度Splunk APM UI を参照します。
Splunk APM サービスマップで Lambda 関数を表示する もう一度APMで環境のサービスマップを確認してみましょう。
Splunk Observability Cloudで
メインメニューの APM ボタンをクリックします。
Environment: ドロップダウンからあなたのAPM環境を選択します。
APM概要ページの右側にある Service Map ボタンをクリックします。これによりサービスマップビューに移動します。
> 注意:トレースが Splunk APM に表示されるまで数分かかる場合があります。環境のリストにあなたの環境名が表示されるまで、ブラウザの更新ボタンを押してみてください
ワークショップの質問今回は、伝播されたコンテキストによってリンクされた producer-lambda と consumer-lambda 関数が見えるはずです!
トレース ID で Lambda トレースを調査する 次に、環境に関連するトレースをもう一度確認します。
コンシューマー関数のログからコピーしたトレースIDを、Traces下の View Trace ID 検索ボックスに貼り付け、Go をクリックします
メモトレース ID は、私たちが伝播したトレースコンテキストの一部でした。
最も一般的な2つの伝播規格について読むことができます
W3C B3
ワークショップの質問私たちはどちらを使用していますか?
私たちの NodeJS 関数をサポートする Splunk Distribution of Opentelemetry JS は、デフォルト で W3C 標準を使用しています
ワークショップの質問ボーナス質問:W3CヘッダーとB3ヘッダーを混在させるとどうなりますか?
consumer-lambda スパンをクリックしてください。
ワークショップの質問あなたのメッセージからの属性を見つけることができますか?
クリーンアップ いよいよワークショップの最後に来ました。後片付けをしましょう!
send_message の停止すべての AWS リソースを破棄する Terraformは個々のリソースの状態をデプロイメントとして管理するのに優れています。定義に変更があっても、デプロイされたリソースを更新することもできます。しかし、一からやり直すために、リソースを破棄し、このワークショップの手動計装部分の一部として再デプロイします。
以下の手順に従ってリソースを破棄してください
結論 Lambda Tracingワークショップを終えたことをおめでとうございます!自動計装を手動のステップで補完して、producer-lambda 関数のコンテキストをKinesisストリーム内のレコードを介して consumer-lambda 関数に送信する方法を見てきました。これにより、期待される分散トレースを構築し、Splunk APMで両方の関数間の関係をコンテキスト化することができました。
これで、2つの異なる関数を手動でリンクしてトレースを構築することができます。これは、自動計装や第三者のシステムがコンテキスト伝播を標準でサポートしていない場合や、より関連性の高いトレース分析のためにカスタム属性をトレースに追加したい場合に役立ちます。