TT Lab
开始
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

所有 Span 都以 unknown_service 的名义进来了

在 TT Lab 中继续学习

目标

用真实的 SDK 确认资源(Resource)在默认值、环境变量和代码中按什么优先级确定;用代码遵循 OTLP 中资源的分组结构和稳定的 HTTP 语义约定(semantic conventions);最后安全地合并 schema 不同的资源。

为什么重要

遥测用资源来说明“数据来自哪里”。service.name 以 unknown_service 进入时,仪表板的服务列表会挤成一项;环境变量和代码给出不同的值时,不弄清谁赢了就找不到原因。语义约定是后端和仪表板对属性名称与状态含义的约定,因此把 404 标记为错误,或把路径原文放进 span 名称,都会让错误率和基数(cardinality)同时出错。

已准备的环境

/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 两行。查看 /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 的结果,以 service_name=、service_version=、environment= 的形式写入 /root/otca-resource/03-code.txt。
  4. 在 /root/otca-resource/04-otel.env 中写入一行 OTEL_RESOURCE_ATTRIBUTES。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 的 tracer 创建并结束 2 个 span,用 provider_b 创建并结束 1 个 span。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 5 会显示把两个 provider(service.name 分别为 frontend、orders-db)的 span 编码为 OTLP 之后的结果。在 /root/otca-resource/05-grouping.txt 中写入 resource_spans=、spans=、service_name_on_spans=(span 属性中是否有 service.name,true/false)。
  6. 修改 /root/otca-resource/server.py 中的 handle(tracer, request),让它按稳定(stable)的 HTTP 语义约定为一个请求创建服务端 span。评分器会用 201、404、503 三个请求来确认:类型为 SERVER,名称为 {메서드} {경로 템플릿}(占位符依次为 HTTP 方法与路由模板),属性为 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 查看所创建的 span。
  7. /opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 7 会显示用 merge 把配置的资源(schema 1.26.0,service.name checkout)合并到检测到的资源(schema 1.21.0,service.name unknown_service)之后的结果。在 /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 也会自己生成。

两个环境变量都在指定名称时

在 /root/otca-resource/02-otel.env 中写入 OTEL_RESOURCE_ATTRIBUTES=service.name=cart,deployment.environment.name=staging 和 OTEL_SERVICE_NAME=checkout 两行。查看 /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 的结果,以 service_name=、service_version=、environment= 的形式写入 /root/otca-resource/03-code.txt。

Resource.create 会在由检测器和环境变量生成的资源之上,覆盖作为参数传入的属性。参数中没有的键,会保留环境变量的值。Resource(...) 构造函数不会读取环境变量。

含有逗号的值

在 /root/otca-resource/04-otel.env 中写入一行 OTEL_RESOURCE_ATTRIBUTES。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 的 tracer 创建并结束 2 个 span,用 provider_b 创建并结束 1 个 span。/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 5 会显示把两个 provider(service.name 分别为 frontend、orders-db)的 span 编码为 OTLP 之后的结果。在 /root/otca-resource/05-grouping.txt 中写入 resource_spans=、spans=、service_name_on_spans=(span 属性中是否有 service.name,true/false)。

OTLP 会把拥有相同资源的 span 分为一组,资源只写一次。每个 span 自身并没有资源。

404 不是服务端的错误

修改 /root/otca-resource/server.py 中的 handle(tracer, request),让它按稳定(stable)的 HTTP 语义约定为一个请求创建服务端 span。评分器会用 201、404、503 三个请求来确认:类型为 SERVER,名称为 {메서드} {경로 템플릿}(占位符依次为 HTTP 方法与路由模板),属性为 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 查看所创建的 span。

对服务端来说,4xx 是请求方的问题,所以不标记为错误状态。在 span 名称里使用路径原文,每个请求的名称都会不同。

schema URL 不同,合并悄悄失败了

/opt/otel-lab/bin/python /opt/fixtures/otca_resource_lab.py show 7 会显示用 merge 把配置的资源(schema 1.26.0,service.name checkout)合并到检测到的资源(schema 1.21.0,service.name unknown_service)之后的结果。在 /root/otca-resource/07-merge.txt 中写入 naive_service_name=,然后修改 /root/otca-resource/merge.py 中的 combine(detected, configured),让它返回新资源:以配置的值为准,保留检测到的 host.name,schema_url 沿用配置的资源。不要修改输入的资源。

按规范,合并 schema URL 互不相同的两个资源属于错误;此 SDK 会记录错误,然后原样返回原来的资源。资源是不可变的,所以请创建新资源再合并。