TT Lab
はじめる
学ぶ 学習パス コース

OTCA — OpenTelemetry認定アソシエイト

すべてのスパンが unknown_service として届いた

TT Labで続きを見る

目標

リソースがデフォルト値・環境変数・コードの間でどのような優先順位で決まるかを実際のSDKで確認し、OTLPでリソースがまとめられる構造と安定版のHTTPセマンティック規約をコードで守ったうえで、スキーマが異なるリソースを安全にマージします。

なぜ重要なのか

テレメトリは、「どこから来たか」をリソースで表します。service.nameがunknown_serviceで入ってくると、ダッシュボードのサービス一覧が1つにまとまってしまいます。また、環境変数とコードが別々の値を与えた場合は、どちらが勝ったかがわからないと原因を探せません。セマンティック規約は、バックエンドとダッシュボードが属性名と状態の意味を取り決めたものなので、404をエラーとして表示したり、パスの原文をスパン名に入れたりすると、エラー率とカーディナリティがどちらも狂います。

用意されている環境

/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py initが、/root/otca-resource/にresource.py・grouping.py・server.py・merge.pyの開始ファイルを置きます。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py probe [env파일](プレースホルダーはenvファイルです)は、OTEL_で始まる環境変数をすべて消した新しいプロセスにenvファイルの値だけを入れて、Resource.create({})を呼びます。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show Nは、ステップNの実験結果を表示します。lab-devイメージのOpenTelemetry Python SDK 1.44.0(/opt/otel-lab)を使い、ネットワークは使いません。採点は、同じSDKで皆さんのファイルを再実行し、動作と書かれた値を照合します。

ステップ

  1. /opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py initで材料を作成してから、/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py probeを実行してください。OTEL_で始まる環境変数をすべて消した新しいプロセスでの、Resource.create({})の結果が表示されます。/root/otca-resource/01-default.txtに、service_name=、sdk_language=(telemetry.sdk.language)、has_instance_id=(service.instance.idがあるかどうかをtrue/false)を書いてください。
  2. /root/otca-resource/02-otel.envに、OTEL_RESOURCE_ATTRIBUTES=service.name=cart,deployment.environment.name=stagingとOTEL_SERVICE_NAME=checkoutの2行を書いてください。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py probe /root/otca-resource/02-otel.envの結果を見て、/root/otca-resource/02-env.txtに、service_name=、environment=、winner=(service.nameを決めた環境変数の名前)を書いてください。
  3. /root/otca-resource/resource.pyのmake_resource()が、Resource.createでservice.nameをcheckout-api、service.versionを2.4.1に決めて返すように直してください。採点では、OTEL_SERVICE_NAME=checkoutとOTEL_RESOURCE_ATTRIBUTES=service.version=0.0.1,deployment.environment.name=prodを与えたプロセスでこの関数を呼びます。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 3の結果を、/root/otca-resource/03-code.txtにservice_name=、service_version=、environment=として書いてください。
  4. /root/otca-resource/04-otel.envにOTEL_RESOURCE_ATTRIBUTESを1行書いてください。team.ownerの値はpayments,riskで、cloud.region=ap-northeast-2も一緒に入れます。カンマはパーセントエンコード(%2C)します。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 4は、エンコードした値と、同じ値をエンコードしなかった場合の結果をあわせて表示します。/root/otca-resource/04-encoding.txtに、team_owner=とunencoded_team_owner=を書いてください。
  5. /root/otca-resource/grouping.pyのemit(provider_a, provider_b)が、provider_aのトレーサーでスパンを2つ、provider_bでスパンを1つ作って終了するように直してください。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 5は、2つのプロバイダー(service.nameがfrontendとorders-db)のスパンをOTLPでエンコードした結果を表示します。/root/otca-resource/05-grouping.txtに、resource_spans=、spans=、service_name_on_spans=(スパンの属性にservice.nameがあるかどうかをtrue/false)を書いてください。
  6. /root/otca-resource/server.pyのhandle(tracer, request)が、1つのリクエストのサーバースパンを安定版(stable)のHTTPセマンティック規約どおりに作るように直してください。採点では、201・404・503の3つのリクエストで確認します。確認項目は、種類がSERVER、名前が{메서드} {경로 템플릿}(プレースホルダーはメソッドとパステンプレートです)、属性がhttp.request.method・url.path・http.route・http.response.status_code(整数)、古い名前(http.method・http.target・http.status_code)がないこと、5xxなら状態がERRORでerror.type(ステータスコードの文字列)があること、それ以外は状態を空にしておくことです。{RS} show 6で、作ったスパンを確認できます。
  7. /opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 7は、検出されたリソース(schema 1.21.0、service.nameがunknown_service)に、設定したリソース(schema 1.26.0、service.nameがcheckout)をmergeした結果を表示します。/root/otca-resource/07-merge.txtにnaive_service_name=を書き、/root/otca-resource/merge.pyのcombine(detected, configured)が、設定した値が優先され、検出されたhost.nameは残り、schema_urlは設定したリソースに従う新しいリソースを返すように直してください。入力のリソースは変更しません。

参考

何も設定していないサービスの名前

/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py initで材料を作成してから、/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py probeを実行してください。OTEL_で始まる環境変数をすべて消した新しいプロセスでの、Resource.create({})の結果が表示されます。/root/otca-resource/01-default.txtに、service_name=、sdk_language=(telemetry.sdk.language)、has_instance_id=(service.instance.idがあるかどうかをtrue/false)を書いてください。

service.nameは必須属性なので、空の場合はSDKがデフォルト値を埋めます。一部の属性は、設定しなくてもSDKが自分で作ります。

環境変数2つが同じ名前を指定したとき

/root/otca-resource/02-otel.envに、OTEL_RESOURCE_ATTRIBUTES=service.name=cart,deployment.environment.name=stagingとOTEL_SERVICE_NAME=checkoutの2行を書いてください。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py probe /root/otca-resource/02-otel.envの結果を見て、/root/otca-resource/02-env.txtに、service_name=、environment=、winner=(service.nameを決めた環境変数の名前)を書いてください。

どちらの変数もリソースを作りますが、優先順位が決まっています。結果に残ったservice.nameを見て判断してください。

コードで決めた値と環境変数

/root/otca-resource/resource.pyのmake_resource()が、Resource.createでservice.nameをcheckout-api、service.versionを2.4.1に決めて返すように直してください。採点では、OTEL_SERVICE_NAME=checkoutとOTEL_RESOURCE_ATTRIBUTES=service.version=0.0.1,deployment.environment.name=prodを与えたプロセスでこの関数を呼びます。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 3の結果を、/root/otca-resource/03-code.txtにservice_name=、service_version=、environment=として書いてください。

Resource.createは、検出器と環境変数で作ったリソースの上に、引数で受け取った属性を上書きします。引数にないキーは、環境変数の値が残ります。Resource(...)コンストラクターは環境変数を読みません。

カンマを含む値

/root/otca-resource/04-otel.envにOTEL_RESOURCE_ATTRIBUTESを1行書いてください。team.ownerの値はpayments,riskで、cloud.region=ap-northeast-2も一緒に入れます。カンマはパーセントエンコード(%2C)します。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 4は、エンコードした値と、同じ値をエンコードしなかった場合の結果をあわせて表示します。/root/otca-resource/04-encoding.txtに、team_owner=とunencoded_team_owner=を書いてください。

この変数では、カンマは属性の区切り文字です。値の中のカンマと等号は、エンコードする必要があります。エンコードしなかった側のSDKの警告も読んでみてください。

OTLPでリソースはどこに付くのか

/root/otca-resource/grouping.pyのemit(provider_a, provider_b)が、provider_aのトレーサーでスパンを2つ、provider_bでスパンを1つ作って終了するように直してください。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 5は、2つのプロバイダー(service.nameがfrontendとorders-db)のスパンをOTLPでエンコードした結果を表示します。/root/otca-resource/05-grouping.txtに、resource_spans=、spans=、service_name_on_spans=(スパンの属性にservice.nameがあるかどうかをtrue/false)を書いてください。

OTLPは、同じリソースを持つスパンをまとめて、リソースを1回だけ書きます。各スパンにはリソースがありません。

404はサーバーのエラーではない

/root/otca-resource/server.pyのhandle(tracer, request)が、1つのリクエストのサーバースパンを安定版(stable)のHTTPセマンティック規約どおりに作るように直してください。採点では、201・404・503の3つのリクエストで確認します。確認項目は、種類がSERVER、名前が{메서드} {경로 템플릿}(プレースホルダーはメソッドとパステンプレートです)、属性がhttp.request.method・url.path・http.route・http.response.status_code(整数)、古い名前(http.method・http.target・http.status_code)がないこと、5xxなら状態がERRORでerror.type(ステータスコードの文字列)があること、それ以外は状態を空にしておくことです。{RS} show 6で、作ったスパンを確認できます。

サーバーの立場では、4xxはリクエスト側の問題なので、エラー状態として表示しません。スパン名にパスの原文を使うと、リクエストごとに名前が変わってしまいます。

スキーマURLが違うため、マージが黙って失敗した

/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 7は、検出されたリソース(schema 1.21.0、service.nameがunknown_service)に、設定したリソース(schema 1.26.0、service.nameがcheckout)をmergeした結果を表示します。/root/otca-resource/07-merge.txtにnaive_service_name=を書き、/root/otca-resource/merge.pyのcombine(detected, configured)が、設定した値が優先され、検出されたhost.nameは残り、schema_urlは設定したリソースに従う新しいリソースを返すように直してください。入力のリソースは変更しません。

スキーマURLが互いに異なる2つのリソースのマージは、仕様上エラーであり、このSDKはエラーを記録したうえで元のリソースをそのまま返します。リソースは不変なので、新しいリソースを作ってマージしてください。