1 - 分布式跟踪概述

使用跟踪获取应用程序可见性的概述

Dapr 使用 Open Telemetry (OTEL) 和 Zipkin 协议进行分布式跟踪。OTEL 是行业标准,是推荐的跟踪协议。

大多数可观测性工具都支持 OTEL,包括:

下图演示了 Dapr(使用 OTEL 和 Zipkin 协议)如何与多个可观测性工具集成。

使用 Dapr 的分布式跟踪

场景

跟踪与服务调用和发布订阅 API 一起使用。你可以在使用这些 API 的服务之间流转跟踪上下文。跟踪的使用有两种场景:

  1. Dapr 生成跟踪上下文,你将跟踪上下文传播到另一个服务。
  2. 你生成跟踪上下文,Dapr 将跟踪上下文传播到服务。

场景 1:Dapr 生成跟踪上下文头

传播顺序服务调用

Dapr 负责创建跟踪头。但是,当有两个以上服务时,你需要负责在它们之间传播跟踪头。让我们通过示例来了解这些场景:

单次服务调用调用

例如,service A -> service B

Dapr 在 service A 中生成跟踪头,然后从 service A 传播到 service B。不需要进一步传播。

多次顺序服务调用调用

例如,service A -> service B -> 传播跟踪头到 -> service C,依此类推到其他启用 Dapr 的服务。

Dapr 在请求开始时在 service A 中生成跟踪头,然后传播到 service B。你现在需要负责获取这些头并将它们传播到 service C,因为这是特定于你的应用程序的。

换句话说,如果应用程序调用 Dapr 并希望使用现有跟踪头(span)进行跟踪,它必须始终传播到 Dapr(在本示例中从 service Bservice C)。Dapr 始终将跟踪 span 传播到应用程序。

请求来自外部端点

例如,从网关服务到启用 Dapr 的服务 A

外部网关入口调用 Dapr,Dapr 生成跟踪头并调用 service AService A 然后调用 service B 和其他启用 Dapr 的服务。

你必须将头从 service A 传播到 service B。例如:Ingress -> service A -> 传播跟踪头 -> service B。这类似于情况 2

发布订阅消息

Dapr 在发布的消息主题中生成跟踪头。对于 rawPayload 消息,可以指定 traceparent 头来传播跟踪信息。这些跟踪头被传播到监听该主题的任何服务。

传播多个不同的服务调用

在以下场景中,Dapr 会为你完成部分工作,然后由你创建或传播跟踪头。

从单个服务到不同服务的多次服务调用

当你从单个服务调用多个服务时,需要传播跟踪头。例如:

service A -> service B
[ .. 一些代码逻辑 ..]
service A -> service C
[ .. 一些代码逻辑 ..]
service A -> service D
[ .. 一些代码逻辑 ..]

在这种情况下:

  1. service A 首次调用 service B 时,Dapr 在 service A 中生成跟踪头。
  2. service A 中的跟踪头被传播到 service B
  3. 这些跟踪头在 service B 的响应中作为响应头的一部分返回。
  4. 然后你需要将返回的跟踪上下文传播到下一个服务,比如 service Cservice D,因为 Dapr 不知道你想重用同一个头。

场景 2:你从非 Dapr 应用程序生成自己的跟踪上下文头

生成自己的跟踪上下文头不太常见,并且在调用 Dapr 时通常不需要。

但是,有些场景你可能会选择在服务调用中添加 W3C 跟踪头。例如,你有一个不使用 Dapr 的现有应用程序。在这种情况下,Dapr 仍然会为你传播跟踪上下文头。

如果你决定自己生成跟踪头,可以通过三种方式完成:

  1. 标准 OpenTelemetry SDK

    你可以使用行业标准 OpenTelemetry SDK 生成跟踪头,并将这些跟踪头传递给启用 Dapr 的服务。这是首选方法

  2. 供应商 SDK

    你可以使用提供生成 W3C 跟踪头方法的供应商 SDK,并将它们传递给启用 Dapr 的服务。

  3. W3C 跟踪上下文

    你可以按照 W3C 跟踪上下文规范 手工制作跟踪上下文,并将它们传递给启用 Dapr 的服务。

    阅读跟踪上下文概述以获取有关 W3C 跟踪上下文和头的更多背景信息和示例。

Baggage 支持

Dapr 支持两种不同的机制来传播 W3C Baggage 以及跟踪上下文:

  1. Context Baggage(OpenTelemetry)

    • 遵循 OpenTelemetry 约定,使用解码值
    • 在使用 OpenTelemetry 上下文传播时使用
    • 值以其原始、未编码的形式存储和传输
    • 推荐用于 OpenTelemetry 集成以及在使用应用程序上下文时
  2. Header/Metadata Baggage

    • 在设置头/元数据 baggage 时,必须对特殊字符进行 URL 编码(例如,空格使用 %20,斜杠使用 %2F
    • 值根据 W3C Baggage 规范的要求在传输中保持百分号编码
    • 在检查原始头/元数据时值保持编码
    • 只有 OpenTelemetry API 会解码这些值
    • 示例:在设置头 baggage 时使用 serverNode=DF%2028(而不是 serverNode=DF 28

出于安全目的,上下文 baggage 和头 baggage 严格分离,永远不会在域之间合并。这确保 baggage 值保持其预期的格式和安全属性。

在 Dapr 中使用 Baggage

你可以根据用例使用任一机制传播 baggage。

  1. 在你的应用程序代码中:在进行 Dapr API 调用之前在上下文中设置 baggage
  2. 调用 Dapr 时:将上下文传递给任何 Dapr API 调用
  3. 在 Dapr 内部:Dapr 运行时自动获取 baggage
  4. 传播:Dapr 自动将 baggage 传播到下游服务,为每种机制维护适当的编码

以下是这两种机制的示例:

1. 使用 Context Baggage (OpenTelemetry)

使用 OpenTelemetry SDK 时:

import 	otelbaggage "go.opentelemetry.io/otel/baggage"

// Set baggage in context (values remain unencoded)
baggage, err = otelbaggage.Parse("userId=cassie,serverNode=DF%2028")
...
ctx := otelbaggage.ContextWithBaggage(t.Context(), baggage)
)

// Pass this context to any Dapr API call
client.InvokeMethodWithContent(ctx, "serviceB", ...)

2. 使用 Header/Metadata Baggage

使用 gRPC 元数据时:

import "google.golang.org/grpc/metadata"

// Set URL-encoded baggage in context
ctx = metadata.AppendToOutgoingContext(ctx,
    "baggage", "userId=cassie,serverNode=DF%2028",
)

// Pass this context to any Dapr API call
client.InvokeMethodWithContent(ctx, "serviceB", ...)

3. 在目标服务中接收 Baggage

在目标服务中,你可以访问传播的 baggage:

// Using OpenTelemetry (values are automatically decoded)
import "go.opentelemetry.io/otel/baggage"

bag := baggage.FromContext(ctx)
userID := bag.Member("userId").Value()  // "cassie"
// Using raw gRPC metadata (values remain percent-encoded)
import "google.golang.org/grpc/metadata"

md, _ := metadata.FromIncomingContext(ctx)
if values := md.Get("baggage"); len(values) > 0 {
    // values[0] contains the percent-encoded string you set: "userId=cassie,serverNode=DF%2028"
    // Remember: You must URL encode special characters when setting baggage
    
    // To decode the values, use OpenTelemetry APIs:
    bag, err := baggage.Parse(values[0])
    ...
    userID := bag.Member("userId").Value()  // "cassie"
}

HTTP 示例(URL 编码):

curl -X POST http://localhost:3500/v1.0/invoke/serviceB/method/hello \
  -H "Content-Type: application/json" \
  -H "baggage: userID=cassie,serverNode=DF%2028" \
  -d '{"message": "Hello service B"}'

gRPC 示例(URL 编码):

ctx = grpcMetadata.AppendToOutgoingContext(ctx,
    "baggage", "userID=cassie,serverNode=DF%2028",
)

常见用例

Baggage 适用于:

  • 跨服务传播用户 ID 或关联 ID
  • 传递租户或环境信息
  • 跨服务边界维护一致的上下文
  • 调试和故障排除分布式事务

最佳实践

  1. 选择正确的机制

    • 在使用 OpenTelemetry 时使用 Context Baggage
    • 在直接使用 HTTP/gRPC 时使用 Header Baggage
  2. 安全考虑

    • 注意 baggage 会跨服务边界传播
    • 不要在 baggage 中包含敏感信息
    • 记住上下文 baggage 和头 baggage 保持分离

相关链接

2 - W3C 追踪上下文概述

在 Dapr 中使用 W3C 追踪上下文和标头的背景与场景

Dapr 使用 Open Telemetry 协议,而该协议又使用 W3C 追踪上下文进行分布式追踪,涵盖服务调用和发布订阅消息。Dapr 生成并传播追踪上下文信息,可将其发送到可观测性工具以进行可视化和查询。

背景

分布式追踪是追踪工具实现的一种方法论,用于跟踪、分析和调试跨越多个软件组件的事务。

通常,分布式追踪会跨越多个服务,因此需要能够唯一标识。追踪上下文传播会传递这一唯一标识。

过去,追踪上下文传播由各个追踪供应商单独实现。在多供应商环境中,这会导致互操作性问题,例如:

  • 不同追踪供应商收集的追踪无法关联,因为没有共享的唯一标识符。
  • 跨越不同追踪供应商边界的追踪无法传播,因为没有转发统一约定的标识符集。
  • 特定于供应商的元数据可能会被中间设备丢弃。
  • 云平台供应商、中间设备和服务提供商无法保证支持追踪上下文传播,因为没有可遵循的标准。

以前,大多数应用程序由单个追踪供应商监控,并保持在单个平台供应商的边界内,因此这些问题没有产生重大影响。

如今,越来越多的应用程序是分布式的,并利用多个中间件服务和云平台。现代应用程序的这一转变需要一个分布式追踪上下文传播标准。

W3C 追踪上下文规范定义了交换追踪上下文传播数据(称为追踪上下文)的通用约定格式。追踪上下文通过提供以下功能解决了上述问题:

  • 为单个追踪和请求提供唯一标识符,允许多个提供商的追踪数据链接在一起。
  • 约定的机制转发特定于供应商的追踪数据,并在多个追踪工具参与单个事务时避免追踪中断。
  • 中间设备、平台和硬件提供商可以支持的行业标准。

这种统一的追踪数据传播方法提高了对分布式应用程序行为的可见性,便于进行问题和性能分析。

W3C 追踪上下文和标头格式

W3C 追踪上下文

Dapr 使用标准的 W3C 追踪上下文标头。

  • 对于 HTTP 请求,Dapr 使用 traceparent 标头。
  • 对于 gRPC 请求,Dapr 使用 grpc-trace-bin 标头。

当请求到达时没有追踪 ID,Dapr 会创建一个新的。否则,它会将追踪 ID 沿调用链传递。

W3C 追踪标头

以下是 Dapr 为 HTTP 和 gRPC 生成和传播的特定追踪上下文标头。

在将追踪上下文标头从 HTTP 响应传播到 HTTP 请求时,复制这些标头:

Traceparent 标头

traceparent 标头以通用格式表示追踪系统中的传入请求,所有供应商都能理解:

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

了解有关 traceparent 字段详细信息

Tracestate 标头

tracestate 标头以可能特定于供应商的格式包含父级:

tracestate: congo=t61rcWkgMzE

了解有关 tracestate 字段详细信息

Baggage 支持

Dapr 支持 W3C Baggage,通过两种不同的机制传播键值对以及追踪上下文:

  1. 上下文 Baggage(OpenTelemetry)

    • 遵循 OpenTelemetry 约定,使用解码值
    • 通过应用程序上下文传播 baggage 时使用
    • 值以其原始的、未编码的形式存储
    • 使用 OpenTelemetry API 打印的示例:
      baggage: userId=cassie,serverNode=DF 28,isVIP=true
      
  2. HTTP 标头 Baggage

    • 设置标头 baggage 时必须对特殊字符进行 URL 编码(例如,空格用 %20,斜杠用 %2F
    • 值根据 W3C Baggage 规范的要求,在 HTTP 标头中保持百分比编码
    • 在 Dapr 中检查原始标头时,值保持编码状态
    • 只有像 otelbaggage.Parse() 这样的 OpenTelemetry API 会解码值
    • 示例(注意 URL 编码的空格 %20):
      curl -X POST http://localhost:3500/v1.0/invoke/serviceB/method/hello \
        -H "Content-Type: application/json" \
        -H "baggage: userId=cassie,serverNode=DF%2028,isVIP=true" \
        -d '{"message": "Hello service B"}'
      

出于安全目的,上下文 baggage 和标头 baggage 严格分离,永不跨域合并。这确保 baggage 值在每个域中保持其预期的格式和安全属性。

支持多个 baggage 标头,将根据 W3C 规范进行组合。Dapr 在服务调用之间自动传播 baggage,同时为每个域维护适当的编码。

在 gRPC API 调用中,追踪上下文通过 grpc-trace-bin 标头传递。

Baggage 支持

Dapr 支持 W3C Baggage,通过两种不同的机制传播键值对以及追踪上下文:

  1. 上下文 Baggage(OpenTelemetry)

    • 遵循 OpenTelemetry 约定,使用解码值
    • 通过 gRPC 上下文传播 baggage 时使用
    • 值以其原始的、未编码的形式存储
    • 使用 OpenTelemetry API 打印的示例:
      baggage: userId=cassie,serverNode=DF 28,isVIP=true
      
  2. gRPC 元数据 Baggage

    • 设置元数据 baggage 时必须对特殊字符进行 URL 编码(例如,空格用 %20,斜杠用 %2F
    • 值在 gRPC 元数据中保持百分比编码
    • 示例(注意 URL 编码的空格 %20):
      baggage: userId=cassie,serverNode=DF%2028,isVIP=true
      

出于安全目的,上下文 baggage 和元数据 baggage 严格分离,永不跨域合并。这确保 baggage 值在每个域中保持其预期的格式和安全属性。

支持多个 baggage 元数据条目,将根据 W3C 规范进行组合。Dapr 在服务调用之间自动传播 baggage,同时为每个域维护适当的编码。

相关链接

3 - 配置 Dapr 发送分布式追踪数据

设置 Dapr 发送分布式追踪数据

配置

Configuration 规范下的 tracing 部分包含以下属性:

spec:
  tracing:
    samplingRate: "1"
    otel: 
      endpointAddress: "myendpoint.cluster.local:4317"
      headers:
        - name: "x-api-key"
          secretKeyRef:
            name: "my-secret-store"
            key: "otel-api-key"
      timeout: "30s"
    zipkin:
      endpointAddress: "https://..."
    

下表列出了追踪的属性:

属性类型描述
samplingRatestring设置追踪的采样率以启用或禁用。
stdoutboolTrue 向追踪写入更详细的信息
otel.endpointAddressstring设置 Open Telemetry (OTEL) 目标主机名和可选端口。如果使用此选项,则不需要指定 ‘zipkin’ 部分。
otel.isSecurebool到端点地址的连接是否加密。
otel.protocolstring设置为 httpgrpc 协议。
otel.headersarray要包含在 OTLP 导出器请求中的标头。每个条目都有一个 name 和明文 valuesecretKeyRef(用于引用 Kubernetes secret)。
otel.timeoutstringOTLP 导出器请求的超时时间(例如 30s5m)。
zipkin.endpointAddressstring设置 Zipkin 服务器 URL。如果使用此选项,则不需要指定 otel 部分。

要启用追踪,请使用配置文件(在自托管模式下)或 Kubernetes 配置对象(在 Kubernetes 模式下)。例如,以下配置对象将采样率更改为 1(每个 span 都被采样),并使用 OTEL 协议将追踪发送到位于 localhost:4317 的 OTEL 服务器

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: tracing
spec:
  tracing:
    samplingRate: "1"
    otel:
      endpointAddress: "localhost:4317"
      isSecure: false
      protocol: grpc
      headers:
        - name: "x-api-key"
          value: "my-api-key"
        - name: "x-secret-header"
          secretKeyRef:
            name: "my-secret"
            key: "header-value"
      timeout: "30s"

采样率

Dapr 使用概率采样。采样率定义了追踪 span 被采样的概率,其值可以在 0 到 1 之间(含)。默认采样率为 0.0001(即每 10,000 个 span 中采样 1 个)。

samplingRate 更改为 0 会完全禁用追踪。

环境变量

OpenTelemetry (otel) 端点也可以通过环境变量进行配置。存在 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量时 会为边车启用追踪。

环境变量描述
OTEL_EXPORTER_OTLP_ENDPOINT设置 Open Telemetry (OTEL) 服务器主机名和可选端口,启用追踪
OTEL_EXPORTER_OTLP_INSECURE将到端点的连接设置为未加密(true/false)
OTEL_EXPORTER_OTLP_PROTOCOL传输协议(grpchttp/protobufhttp/json
OTEL_EXPORTER_OTLP_TRACES_HEADERSOTLP 追踪导出器的逗号分隔的 key=value 标头列表
OTEL_EXPORTER_OTLP_TRACES_TIMEOUTOTLP 追踪导出器的超时时间(以毫秒为单位,例如 30000

下一步

了解如何使用以下工具之一设置追踪:

4 - OpenTelemetry Collector

如何设置可观测性工具以接收应用程序跟踪

4.1 - 使用 OpenTelemetry Collector 收集追踪数据

如何使用 Dapr 通过 OpenTelemetry Collector 推送追踪事件。

Dapr 使用 OpenTelemetry (OTLP) 协议直接写入追踪数据,这是推荐的方法。对于直接支持 OTLP 的可观测性工具,建议使用 OpenTelemetry Collector,因为它允许应用程序快速卸载数据,并包含重试、批处理和加密等功能。更多信息,请阅读 OpenTelemetry Collector 文档

Dapr 也可以使用 Zipkin 协议写入追踪数据。在支持 OTLP 协议之前,Zipkin 协议与 OpenTelemetry Collector 一起使用,将追踪数据发送到 AWS X-Ray、Google Cloud Operations Suite 和 Azure Monitor 等可观测性工具。两种协议方法都是有效的,但 OpenTelemetry 协议是推荐的选择。

使用 OpenTelemetry Collector 与多个后端集成

前提条件

设置 OTEL Collector 以推送到您的追踪后端

  1. 查看 open-telemetry-collector-generic.yaml

  2. <your-exporter-here> 部分替换为您的追踪 exporter 的正确设置。

  3. 使用以下命令应用配置:

    kubectl apply -f open-telemetry-collector-generic.yaml
    

设置 Dapr 以将追踪数据发送到 OTEL Collector

设置一个 Dapr 配置文件来启用追踪,并部署一个使用 OpenTelemetry Collector 的追踪 exporter 组件。

  1. 使用此 collector-config.yaml 文件创建您自己的配置。

  2. 使用以下命令应用配置:

    kubectl apply -f collector-config.yaml
    

使用追踪功能部署您的应用

通过在要参与分布式追踪的容器上添加 dapr.io/config 注解来应用 appconfig 配置,如下例所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    metadata:
      ...
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "MyApp"
        dapr.io/app-port: "8080"
        dapr.io/config: "appconfig"

您可以同时注册多个追踪 exporter,追踪日志会转发到所有已注册的 exporter。

就这样!无需包含任何 SDK 或检测您的应用程序代码。Dapr 会自动为您处理分布式追踪。

查看追踪数据

部署并运行一些应用程序。等待追踪数据传播到您的追踪后端,然后在那里查看它们。

相关链接

4.2 - 使用 OpenTelemetry Collector 收集追踪数据并发送到 Application Insights

如何使用 OpenTelemetry Collector 将追踪事件推送到 Azure Application Insights。

Dapr 使用 OpenTelemetry 协议 (OTLP) 与 OpenTelemetry (OTEL) Collector 集成。本指南通过一个示例演示如何使用 Dapr 通过 OpenTelemetry Collector 将追踪数据推送到 Azure Application Insights。

前置条件

设置 OTEL Collector 将数据推送到你的 Application Insights 实例

要将追踪数据推送到你的 Application Insights 实例,请在 Kubernetes 集群上安装 OpenTelemetry Collector。

  1. 下载并查看 open-telemetry-collector-appinsights.yaml 文件。

  2. <CONNECTION_STRING> 占位符替换为你的 Application Insights 连接字符串。

  3. 将 OpenTelemetry Collector 部署到运行 Dapr 应用的同一命名空间:

    kubectl apply -f open-telemetry-collector-appinsights.yaml
    

设置 Dapr 将追踪数据发送到 OpenTelemetry Collector

创建 Dapr 配置文件以启用追踪,并通过 OTLP 将追踪数据发送到 OpenTelemetry Collector。

  1. 下载并查看 collector-config-otel.yaml。更新 namespaceotel.endpointAddress 值,使其与部署 Dapr 应用和 OpenTelemetry Collector 的命名空间一致。

  2. 使用以下命令应用配置:

    kubectl apply -f collector-config-otel.yaml
    

部署启用追踪的应用

通过向要包含在分布式追踪中的 Dapr 应用添加 dapr.io/config 注解来应用 tracing 配置,如下例所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    metadata:
      ...
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "MyApp"
        dapr.io/app-port: "8080"
        dapr.io/config: "tracing"

你可以同时注册多个追踪导出器,追踪日志将转发到所有已注册的导出器。

就是这样!无需包含任何 SDK 或对应用程序代码进行插桩。Dapr 会自动为你处理分布式追踪。

查看追踪数据

部署并运行一些应用程序。几分钟后,你应该会看到追踪日志出现在你的 Application Insights 资源中。你还可以使用 Application Map 来检查服务的拓扑,如下所示:

Application map

相关链接

4.3 - 使用 Dynatrace OpenTelemetry Collector 收集追踪信息并发送到 Dynatrace

如何使用 Dynatrace OpenTelemetry Collector 将追踪事件推送到 Dynatrace。

Dapr 使用 OpenTelemetry 协议(OTLP)与 Dynatrace Collector 集成。本指南将通过一个示例演示如何使用 Dapr 通过 Dynatrace 版本的 OpenTelemetry Collector 向 Dynatrace 推送追踪信息。

前置条件

  • 在 Kubernetes 上安装 Dapr
  • 访问 Dynatrace 租户以及具有 openTelemetryTrace.ingestmetrics.ingestlogs.ingest 作用域的 API 令牌
  • Helm

设置 Dynatrace OpenTelemetry Collector 以推送到您的 Dynatrace 实例

要将追踪信息推送到您的 Dynatrace 实例,请在您的 Kubernetes 集群上安装 Dynatrace OpenTelemetry Collector。

  1. 使用您的 Dynatrace 凭证创建 Kubernetes secret:

    kubectl create secret generic dynatrace-otelcol-dt-api-credentials \
      --from-literal=DT_ENDPOINT=https://YOUR_TENANT.live.dynatrace.com/api/v2/otlp \
      --from-literal=DT_API_TOKEN=dt0s01.YOUR_TOKEN_HERE
    

    YOUR_TENANT 替换为您的 Dynatrace 租户 ID,将 YOUR_TOKEN_HERE 替换为您的 Dynatrace API 令牌。

  2. 使用 Dynatrace OpenTelemetry Collector 发行版以获得比开源版本更好的默认值和支持。下载并检查 collector-helm-values.yaml 文件。这基于 k8s enrichment demo,并包含 Kubernetes 元数据增强以获得适当的 pod/namespace/cluster 上下文。

  3. 使用 Helm 部署 Dynatrace Collector。

    helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
    helm repo update
    helm upgrade -i dynatrace-collector open-telemetry/opentelemetry-collector -f collector-helm-values.yaml
    

设置 Dapr 以将追踪信息发送到 Dynatrace Collector

创建 Dapr 配置文件以启用追踪,并通过 OTLP 将追踪信息发送到 OpenTelemetry Collector。

  1. 更新以下文件以确保 endpointAddress 指向 Kubernetes 集群中的 Dynatrace OpenTelemetry Collector 服务。如果在 default 命名空间中部署,通常是 dynatrace-collector.default.svc.cluster.local

    重要提示: 确保 endpointAddress 不包含 http:// 前缀,以避免 URL 编码问题:

     apiVersion: dapr.io/v1alpha1
     kind: Configuration
     metadata:
       name: tracing
     spec:
       tracing:
         samplingRate: "1"
         otel:
           endpointAddress: "dynatrace-collector.default.svc.cluster.local:4318" # 使用您的 collector 服务地址更新
    
  2. 应用配置:

    kubectl apply -f collector-config-otel.yaml
    

使用追踪部署应用

通过向要包含在分布式追踪中的 Dapr 应用添加 dapr.io/config 注解来应用 tracing 配置,如以下示例所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    metadata:
      ...
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "MyApp"
        dapr.io/app-port: "8080"
        dapr.io/config: "tracing"

您可以同时注册多个追踪导出器,追踪日志将转发到所有已注册的导出器。

就是这样!无需包含任何 SDK 或对应用代码进行检测。Dapr 会自动为您处理分布式追踪。

查看追踪

部署并运行一些应用。几分钟后,您应该会看到追踪信息出现在您的 Dynatrace 租户中:

  1. 在 Dynatrace UI 中导航到 Search > Distributed tracing
  2. 按服务名称筛选以查看您的 Dapr 应用及其关联的追踪 span。
Dynatrace 显示追踪数据。

相关链接

4.4 - 使用 OpenTelemetry 向 Jaeger V2 发送 traces

如何使用 OpenTelemetry 协议将 trace 事件推送到 Jaeger V2 分布式追踪平台。

Dapr 支持使用 OpenTelemetry (OTLP) 协议写入 traces,而 Jaeger V2 原生支持 OTLP,允许 Dapr 直接向 Jaeger V2 实例发送 traces。这种方法推荐用于生产环境,以利用 Jaeger V2 的分布式追踪能力。

在自托管模式下配置 Jaeger V2

本地设置

启动 Jaeger 最简单的方式是运行发布到 DockerHub 的预构建 all-in-one Jaeger 镜像并暴露 OTLP 端口:

注意: 端口 9411 通常由 Zipkin 使用。如果你正在运行 Zipkin(运行 dapr init 时默认启动),请先停止 dapr_zipkin 容器以避免端口冲突:docker stop dapr_zipkin

docker run -d --rm --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 5778:5778 \
  -p 9411:9411 \
  cr.jaegertracing.io/jaegertracing/jaeger:2.11.0

你也可以使用以下命令查看 jaeger 容器的日志:

docker logs jaeger

配置 Dapr 追踪

你有两个选项来配置 Dapr 向 Jaeger V2 发送 traces:

选项 1:使用自定义配置文件

创建一个包含以下内容的 config.yaml 文件:

注意: 由于你使用 OpenTelemetry 协议与 Jaeger 通信,你需要填写追踪配置的 otel 部分,并将 endpointAddress 设置为 Jaeger 容器的地址。

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: tracing
  namespace: default
spec:
  tracing:
    samplingRate: "1"
    stdout: true
    otel:
      endpointAddress: "localhost:4317"
      isSecure: false
      protocol: grpc 

要启动引用新 YAML 配置文件的应用程序,请使用 --config 选项。例如:

dapr run --app-id myapp --app-port 3000 node app.js --config config.yaml

选项 2:更新默认 Dapr 配置(开发环境)

或者,在你的开发环境中,导航到你的本地 Dapr 组件目录并使用上述 OTLP 配置更新默认的 config.yaml 文件。这样,所有 Dapr 应用程序将默认使用 Jaeger V2 追踪配置,无需每次指定 --config 标志。

查看 traces

要在浏览器中查看 traces,请访问 http://localhost:16686 以查看 Jaeger UI。

在 Kubernetes 上配置 Jaeger V2

以下步骤展示了如何配置 Dapr 将分布式追踪数据直接发送到使用 OpenTelemetry Operator 部署的 Jaeger V2 实例,该实例使用内存存储。

前提条件

使用 OpenTelemetry Operator 设置 Jaeger V2

Jaeger V2 可以使用 OpenTelemetry Operator 部署,以简化管理并获得原生 OTLP 支持。以下示例配置了使用内存存储的 Jaeger V2。

存储后端说明: 此示例使用内存存储(memstore)以简化操作,适用于开发或测试环境,因为它在内存中最多存储 100,000 条 traces。对于生产环境,请考虑配置持久化存储后端(如 Cassandra 或 Elasticsearch)以确保 trace 数据的持久性。

安装

注意: 为了使 API 服务器与 Operator 的 webhook 组件通信,webhook 需要 API 服务器配置为信任的 TLS 证书。你可以使用几种不同的方式来生成/配置所需的 TLS 证书,详细信息见 otel operator chart 文档

为简化操作,你可以使用 Helm 创建自动生成的自签名证书。

  1. 安装 OpenTelemetry Operator

    helm install opentelemetry-operator open-telemetry/opentelemetry-operator -n opentelemetry-operator-system --create-namespace \
     --set "manager.collectorImage.repository=ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-k8s" \
     --set admissionWebhooks.certManager.enabled=false \
     --set admissionWebhooks.autoGenerateCert.enabled=true
    

    确认 opentelemetry-operator-system 命名空间中的所有资源已就绪。

  2. 部署使用内存存储的 Jaeger V2 实例: 创建一个名为 jaeger-inmemory.yaml 的文件,包含以下配置:

    apiVersion: opentelemetry.io/v1beta1
    kind: OpenTelemetryCollector
    metadata:
      name: jaeger-inmemory-instance
      namespace: observability
    spec:
      image: jaegertracing/jaeger:latest
      ports:
      - name: jaeger
        port: 16686
      config:
        service:
          extensions: [jaeger_storage, jaeger_query]
          pipelines:
            traces:
              receivers: [otlp]
              exporters: [jaeger_storage_exporter]
        extensions:
          jaeger_query:
            storage:
              traces: memstore
          jaeger_storage:
            backends:
              memstore:
                memory:
                  max_traces: 100000
        receivers:
          otlp:
            protocols:
              grpc:
                endpoint: 0.0.0.0:4317
              http:
                endpoint: 0.0.0.0:4318
        exporters:
          jaeger_storage_exporter:
            trace_storage: memstore
    

    使用以下命令应用它:

    kubectl apply -f jaeger-inmemory.yaml -n observability
    

设置 Dapr 向 Jaeger V2 发送 traces

创建一个 Dapr 配置文件以启用追踪,并将边车 traces 直接导出到 Jaeger V2 实例。

  1. 创建一个配置文件(例如 tracing.yaml),包含以下内容,更新 namespaceotel.endpointAddress 以匹配你的 Jaeger V2 实例:

    apiVersion: dapr.io/v1alpha1
    kind: Configuration
    metadata:
      name: tracing
      namespace: order-system
    spec:
      tracing:
        samplingRate: "1"
        otel:
          endpointAddress: "jaeger-inmemory-instance-collector.observability.svc.cluster.local:4317"
          isSecure: false
          protocol: grpc
    
  2. 应用配置:

    kubectl apply -f tracing.yaml -n order-system
    

启用追踪部署应用

通过在要启用分布式追踪的应用程序部署中添加 dapr.io/config 注解来应用 tracing Dapr 配置,如以下示例所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...
  template:
    metadata:
      ...
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "MyApp"
        dapr.io/app-port: "8080"
        dapr.io/config: "tracing"

你可以同时注册多个追踪导出器,追踪日志将转发到所有已注册的导出器。

就是这样!无需包含 OpenTelemetry SDK 或检测应用程序代码。Dapr 会自动为你处理分布式追踪。

查看 traces

要查看 Dapr 边车 traces,请转发 Jaeger V2 服务的端口并打开 UI:

kubectl port-forward svc/jaeger-inmemory-instance-collector 16686:16686 -n observability

在浏览器中,访问 http://localhost:16686 以查看 Jaeger V2 UI。

jaeger

参考

5 - 操作指南:设置 New Relic 进行分布式追踪

设置 New Relic 进行分布式追踪

前置条件

  • 永久免费的 New Relic 账户,每月 100 GB 免费数据接入,1 个免费全权限用户,无限免费基础用户

配置 Dapr 追踪

Dapr 原生捕获可以直接发送到 New Relic 的指标和链路。最简单的导出方式是将 Dapr 配置为使用 Zipkin 追踪格式将链路发送到 New Relic 的 Trace API

为了让集成将数据发送到 New Relic 遥测数据平台,你需要一个 New Relic Insights Insert API 密钥

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: appconfig
  namespace: default
spec:
  tracing:
    samplingRate: "1"
    zipkin:
      endpointAddress: "https://trace-api.newrelic.com/trace/v1?Api-Key=<NR-INSIGHTS-INSERT-API-KEY>&Data-Format=zipkin&Data-Format-Version=2"

查看追踪

New Relic 分布式追踪概览 New Relic Kubernetes Cluster Explorer App

New Relic 分布式追踪详情 New Relic Kubernetes Cluster Explorer App

(可选)New Relic Instrumentation

为了让集成将数据发送到 New Relic 遥测数据平台,你需要一个 New Relic 许可证密钥New Relic Insights Insert API 密钥

OpenTelemetry instrumentation

利用不同语言的特定 OpenTelemetry 实现,例如 New Relic Telemetry SDK 和 OpenTelemetry 对 .NET 的支持。在这种情况下,使用 OpenTelemetry Trace Exporter。参见示例

New Relic 语言代理

与 OpenTelemetry instrumentation 类似,你也可以利用 New Relic 语言代理。例如,New Relic 代理对 .NET Core 的 instrumentation是 Dockerfile 的一部分。参见示例

(可选)启用 New Relic Kubernetes 集成

如果 Dapr 和你的应用程序在 Kubernetes 环境中运行,你可以启用额外的指标和日志。

安装 New Relic Kubernetes 集成的最简单方法是使用自动化安装程序生成清单。它不仅打包了集成 DaemonSets,还包含其他 New Relic Kubernetes 配置,如 Kubernetes 事件Prometheus OpenMetricsNew Relic 日志监控

New Relic Kubernetes Cluster Explorer

New Relic Kubernetes Cluster Explorer为 Kubernetes 集成收集的整个数据和部署提供了独特的可视化。

这是观察所有数据并深入了解应用程序或微服务内部发生的任何性能问题或事件的良好起点。

New Relic Kubernetes Cluster Explorer App

自动化关联是 New Relic 可视化功能的一部分。

Pod 级别详情

New Relic K8s Pod Level Details

Logs in Context

New Relic K8s Logs In Context

New Relic 仪表板

Kubernetes 概览

New Relic Dashboard Kubernetes Overview

Dapr 系统服务

New Relic Dashboard Dapr System Services

Dapr 指标

New Relic Dashboard Dapr Metrics 1

New Relic Grafana 集成

New Relic 与 Grafana Labs合作,你可以将遥测数据平台用作 Prometheus 指标的数据源,并在现有仪表板中查看它们,无缝利用 New Relic 提供的可靠性、规模和安全性。

用于监控 Dapr 系统服务和边车的 Grafana 仪表板模板无需任何更改即可轻松使用。New Relic 提供了用于 Grafana 的 Prometheus 指标原生端点。可以轻松设置数据源:

New Relic Grafana Data Source

并且可以从 Dapr 导入完全相同的仪表板模板来可视化 Dapr 系统服务和边车。

New Relic Grafana Dashboard

New Relic 告警

从 Dapr、Kubernetes 或其上运行的任何服务收集的所有数据都可以用于在您选择的首选渠道中设置告警和通知。参见告警和 Applied Intelligence

相关链接/参考

6 - 操作指南:设置 Zipkin 进行分布式追踪

设置 Zipkin 进行分布式追踪

配置自托管模式

对于自托管模式,在运行 dapr init 时:

  1. 默认情况下,会在 $HOME/.dapr/config.yaml(Linux/Mac 上)或 %USERPROFILE%\.dapr\config.yaml(Windows 上)创建以下 YAML 文件,并且在 dapr run 调用时会默认引用该文件,除非被覆盖:
  • config.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: daprConfig
  namespace: default
spec:
  tracing:
    samplingRate: "1"
    zipkin:
      endpointAddress: "http://localhost:9411/api/v2/spans"
  1. 在运行 dapr init 时,会启动 openzipkin/zipkin docker 容器,或者可以使用以下代码启动它。

使用 Docker 启动 Zipkin:

docker run -d -p 9411:9411 openzipkin/zipkin
  1. 使用 dapr run 启动的应用程序默认引用 $HOME/.dapr/config.yaml%USERPROFILE%\.dapr\config.yaml 中的配置文件,并可以通过使用 --config 参数的 Dapr CLI 覆盖它:
dapr run --app-id mynode --app-port 3000 node app.js

查看追踪

要查看追踪,请在浏览器中打开 http://localhost:9411,您将看到 Zipkin UI。

配置 Kubernetes

以下步骤向您展示如何配置 Dapr 将分布式追踪数据发送到在 Kubernetes 集群中作为容器运行的 Zipkin,以及如何查看它们。

设置

首先,部署 Zipkin:

kubectl create deployment zipkin --image openzipkin/zipkin

为 Zipkin pod 创建 Kubernetes 服务:

kubectl expose deployment zipkin --type ClusterIP --port 9411

接下来,在本地创建以下 YAML 文件:

  • tracing.yaml 配置
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: tracing
  namespace: default
spec:
  tracing:
    samplingRate: "1"
    zipkin:
      endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"

现在,部署 Dapr 配置文件:

kubectl apply -f tracing.yaml

为了为您的 Dapr 边车启用此配置,请将以下注解添加到您的 pod 规范模板中:

annotations:
  dapr.io/config: "tracing"

就是这样!您的边车现在已配置为向 Zipkin 发送追踪数据。

查看追踪数据

要查看追踪数据,请连接到 Zipkin 服务并打开 UI:

kubectl port-forward svc/zipkin 9411:9411

在浏览器中,打开 http://localhost:9411,您将看到 Zipkin UI。

zipkin

参考

7 - 操作指南:设置 Dash0 进行分布式追踪

设置 Dash0 进行分布式追踪

Dapr 可捕获指标、链路追踪和日志,并可以通过 OpenTelemetry Collector 直接发送到 Dash0。Dash0 是一个原生 OpenTelemetry 可观测性平台,为分布式应用程序提供全面的监控能力。

配置 Dapr 追踪:使用 OpenTelemetry Collector 和 Dash0

通过使用带有 OTLP 导出器的 OpenTelemetry Collector 向 Dash0 发送数据,你可以配置 Dapr 为 Kubernetes 集群中的每个应用程序创建链路追踪,并在 Dash0 中收集它们进行分析和监控。

前置条件

  • 运行中的 Kubernetes 集群,已安装 kubectl
  • Helm v3+
  • 集群中已安装 Dapr
  • Dash0 账户(开始 14 天免费试用
  • 你的 Dash0 Auth TokenOTLP/gRPC endpoint(可在 Settings → Auth TokensSettings → Endpoints 下找到)

配置 OpenTelemetry Collector

  1. 为 Collector 创建命名空间
kubectl create namespace opentelemetry
  1. 使用你的 Dash0 Auth TokenEndpoint 创建 Secret
kubectl create secret generic dash0-secrets \
  --from-literal=dash0-authorization-token="<your_auth_token>" \
  --from-literal=dash0-endpoint="<your_otlp_grpc_endpoint>" \
  --namespace opentelemetry
  1. 添加 OpenTelemetry Helm 仓库(仅需执行一次)
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
  1. 为 Collector 创建 values.yaml

此配置:

  • 通过环境变量从 Secret 中读取 token + endpoint
  • 启用 OTLP 接收器(gRPC + HTTP)
  • 通过 OTLP/gRPC 使用 Bearer 认证将 链路追踪、指标和日志 发送到 Dash0
mode: deployment
fullnameOverride: otel-collector
replicaCount: 1

image:
  repository: otel/opentelemetry-collector-k8s

extraEnvs:
  - name: DASH0_AUTHORIZATION_TOKEN
    valueFrom:
      secretKeyRef:
        name: dash0-secrets
        key: dash0-authorization-token
  - name: DASH0_ENDPOINT
    valueFrom:
      secretKeyRef:
        name: dash0-secrets
        key: dash0-endpoint

config:
  receivers:
    otlp:
      protocols:
        grpc: {}
        http: {}

  processors:
    batch: {}

  exporters:
    otlp/dash0:
      auth:
        authenticator: bearertokenauth/dash0
      endpoint: ${env:DASH0_ENDPOINT}

  extensions:
    bearertokenauth/dash0:
      scheme: Bearer
      token: ${env:DASH0_AUTHORIZATION_TOKEN}
    health_check: {}

  service:
    extensions:
      - bearertokenauth/dash0
      - health_check
    pipelines:
      traces:
        receivers: [otlp]
        processors: [batch]
        exporters: [otlp/dash0]
      metrics:
        receivers: [otlp]
        processors: [batch]
        exporters: [otlp/dash0]
      logs:
        receivers: [otlp]
        processors: [batch]
        exporters: [otlp/dash0]
  1. 使用 Helm 安装/升级 Collector
helm upgrade --install otel-collector open-telemetry/opentelemetry-collector \
  --namespace opentelemetry \
  -f values.yaml

配置 Dapr 向 Collector 发送遥测数据

  1. 创建配置

创建 dapr-config.yaml

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: tracing
  namespace: default
spec:
  tracing:
    samplingRate: "1"  
    otel:
      endpointAddress: "otel-collector.opentelemetry.svc.cluster.local:4317"
      isSecure: false
      protocol: grpc

应用配置:

kubectl apply -f dapr-config.yaml
  1. 为你的应用程序添加注解

在每个需要 Dapr 追踪的 Deployment/Pod 中添加:

metadata:
  annotations:
    dapr.io/config: "tracing"

验证设置

  1. 检查 OpenTelemetry Collector 是否正在运行:
kubectl get pods -n opentelemetry
  1. 检查 collector 日志以确保它正在接收和转发遥测数据:
kubectl logs -n opentelemetry deployment/otel-collector
  1. 部署一个启用了 Dapr 追踪的示例应用程序并生成一些流量,以验证链路追踪是否正在发送到 Dash0。你可以使用 Dapr Kubernetes 快速入门教程 进行测试。

查看链路追踪

完成设置且遥测数据开始流动后,你可以在 Dash0 中查看链路追踪:

  1. 导航到你的 Dash0 账户
  2. 进入 Traces 部分
  3. 你应该能看到来自 Dapr 应用程序的分布式链路追踪
  4. 使用过滤器按服务名称、操作或时间范围筛选链路追踪
Dash0 Trace Overview Dash0 Trace Details

清理

helm -n opentelemetry uninstall otel-collector
kubectl -n opentelemetry delete secret dash0-secrets
kubectl delete ns opentelemetry

相关链接

8 - 操作指南:为分布式追踪设置 Datadog

为分布式追踪设置 Datadog

Dapr 可以捕获指标和链路追踪数据,并通过 OpenTelemetry Collector 的 Datadog 导出器直接发送到 Datadog。

使用 OpenTelemetry Collector 和 Datadog 配置 Dapr 追踪

使用 OpenTelemetry Collector 的 Datadog 导出器,你可以配置 Dapr 为 Kubernetes 集群中的每个应用创建链路追踪,并在 Datadog 中收集它们。

在开始之前,先设置 OpenTelemetry Collector

  1. 将你的 Datadog API 密钥添加到 ./deploy/opentelemetry-collector-generic-datadog.yaml 文件的 datadog 导出器配置部分中:

    data:
      otel-collector-config:
        ...
        exporters:
          ...
          datadog:
            api:
              key: <YOUR_API_KEY>
    
  2. 通过运行以下命令来应用 opentelemetry-collector 配置。

    kubectl apply -f ./deploy/open-telemetry-collector-generic-datadog.yaml
    
  3. 创建一个 Dapr 配置文件,用于启用追踪并部署一个使用 OpenTelemetry Collector 的追踪导出器组件。

    kubectl apply -f ./deploy/collector-config.yaml
    
  4. 通过向希望参与分布式追踪的容器添加 dapr.io/config 注解来应用 appconfig 配置。

    annotations:
       dapr.io/config: "appconfig"
    
  5. 创建并配置应用程序。一旦运行,遥测数据将发送到 Datadog,并可在 Datadog APM 中查看。

Datadog APM showing telemetry data.

相关链接/参考