分布式跟踪提供业务流程执行的端到端可见性。 使用 Durable Task Scheduler 启用 OpenTelemetry 时,每个编排、活动和子编排都会生成关联的跨度,显示整个工作流中的计时、排序和错误。 可以将这些跟踪导出到任何与 OpenTelemetry 兼容的后端,例如 Azure Monitor Application Insights、Jaeger 或 Zipkin。
Durable Functions 和独立的 Durable Task SDK 在使用 Durable Task Scheduler 作为后端时,均支持 OpenTelemetry 分布式跟踪。
工作原理
Durable Task SDKs 使用 OpenTelemetry span 自动为业务流程和活动提供检测。 SDK 为每个业务流程创建一个父范围,为每个活动调用、子业务流程和计时器创建子范围。 跟踪上下文会在所有这些操作中自动传播,因此可以获得整个工作流程的单一关联的跟踪。
生成的跟踪树如下所示:
create_orchestration (client)
└─ orchestration (server)
├─ activity:Step1
├─ activity:Step2
└─ activity:Step3
无需将自定义仪表添加到协调器或活动代码中。 将 Microsoft.DurableTask 活动源注册到 OpenTelemetry 配置,SDK 将处理其余内容。
先决条件
- 具有 Durable Functions 扩展 2.13.0 或更高版本的 Azure Functions 项目。
- 配置为函数应用的存储后端的持久任务计划程序。
- 用于查看跟踪的 OpenTelemetry 兼容后端(Application Insights、Jaeger 或其他 OTLP 收集器)。
- .NET 8 SDK 或更高版本。
-
Microsoft.DurableTask.Worker.AzureManaged和Microsoft.DurableTask.Client.AzureManagedNuGet 包。 -
OpenTelemetry、OpenTelemetry.Extensions.Hosting和OpenTelemetry.Exporter.OpenTelemetryProtocolNuGet 包。
- 与 OpenTelemetry 兼容的后端,用于查看跟踪,例如用于生产的 Application Insights 或用于本地开发的 Jaeger。
启用分布式跟踪
若要在 Durable Functions 中启用分布式跟踪,请更新 host.json 并配置与 OpenTelemetry 兼容的遥测后端。
更新 host.json
在 tracing 下的 durableTask 文件中添加 节:
{
"version": "2.0",
"extensions": {
"durableTask": {
"tracing": {
"DistributedTracingEnabled": true,
"Version": "V2"
}
}
}
}
配置 Application Insights
在 APPLICATIONINSIGHTS_CONNECTION_STRING 函数应用中设置环境变量。
对于本地开发,请将其添加到 local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"APPLICATIONINSIGHTS_CONNECTION_STRING": "<your-connection-string>"
}
}
对于Azure托管的应用,请在 Azure 门户中的 Configuration 下将其添加为应用程序设置。
注意
如果您之前使用过 APPINSIGHTS_INSTRUMENTATIONKEY,请切换到 APPLICATIONINSIGHTS_CONNECTION_STRING 以获得最新功能。
减少遥测干扰
若要防止 Application Insights 采样跟踪数据,请从 Request中的采样规则中排除:
{
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
}
}
将 Microsoft.DurableTask 活动源注册到 OpenTelemetry 配置。 当您注册此源时,Durable Task SDK 会自动为协调和活动创建时间跨度。
在工作进程的 Program.cs 中,使用持久任务活动源添加 OpenTelemetry 跟踪:
using Microsoft.DurableTask;
using Microsoft.DurableTask.Worker;
using Microsoft.DurableTask.Worker.AzureManaged;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = Host.CreateApplicationBuilder(args);
// Configure OpenTelemetry tracing
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService("durable-worker"))
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddOtlpExporter(opts =>
{
opts.Endpoint = new Uri(
Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")
?? "http://localhost:4317");
});
});
// Build connection string from environment variables
string endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:8080";
string taskHub = Environment.GetEnvironmentVariable("TASKHUB") ?? "default";
string connectionString = endpoint.Contains("localhost")
? $"Endpoint={endpoint};TaskHub={taskHub};Authentication=None"
: $"Endpoint={endpoint};TaskHub={taskHub};Authentication=DefaultAzure";
// Configure Durable Task worker
builder.Services.AddDurableTaskWorker()
.AddTasks(tasks =>
{
tasks.AddOrchestratorFunc<string, string>(
"OrderProcessingOrchestration", async (ctx, input) =>
{
var validated = await ctx.CallActivityAsync<string>("ValidateOrder", input);
var payment = await ctx.CallActivityAsync<string>("ProcessPayment", validated);
var shipment = await ctx.CallActivityAsync<string>("ShipOrder", payment);
var result = await ctx.CallActivityAsync<string>("SendNotification", shipment);
return result;
});
tasks.AddActivityFunc<string, string>("ValidateOrder", (ctx, input) =>
Task.FromResult($"Validated({input})"));
tasks.AddActivityFunc<string, string>("ProcessPayment", (ctx, input) =>
Task.FromResult($"Paid({input})"));
tasks.AddActivityFunc<string, string>("ShipOrder", (ctx, input) =>
Task.FromResult($"Shipped({input})"));
tasks.AddActivityFunc<string, string>("SendNotification", (ctx, input) =>
Task.FromResult($"Notified({input})"));
})
.UseDurableTaskScheduler(connectionString);
var host = builder.Build();
await host.RunAsync();
关键行是 .AddSource("Microsoft.DurableTask"),这告诉 OpenTelemetry 捕获 Durable Task SDK 发出的 span。
在 Application Insights 中查看跟踪
对于生产工作负荷, 建议使用 Application Insights 遥测后端。
当在DistributedTracingEnabled中将true设置为Version并将V2设置为host.json之后,Durable Functions 应用程序会向 Application Insights 发出相关的跨度。 若要查看 Azure 门户中的完整编排跟踪,请进行以下操作:
- 请在 Azure 门户中访问您的 Application Insights 资源。
- 打开 事务搜索 ,按名字或实例标识搜索编排。
- 选择一条追踪以查看端到端事务及其所有关联跨度。
跟踪显示编排为父跨度,子跨度对应于每个活动调用、子编排和计时器等待。 以下模式生成不同的跟踪形状:
| Pattern | 跟踪形状 |
|---|---|
| 函数链式调用 | 顺序活动在协调器范围下嵌套。 |
| 扇出/扇入 | 并行活动在时间上重叠。 |
| 人际互动 | 一个执行协调的跨度,需要长时间等待外部事件。 |
| Monitor | 活动重复周期,计时器在各次迭代之间进行等待。 |
将 OTLP 导出程序配置为使用 Azure Monitor OpenTelemetry 导出程序将追踪数据发送到 Application Insights,或者通过 OTLP 将其导出到一个 OpenTelemetry 收集器,然后再转发到 Application Insights。
安装 Azure.Monitor.OpenTelemetry.Exporter NuGet 包,并将 OTLP 导出程序替换为:
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService("durable-worker"))
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddAzureMonitorTraceExporter(opts =>
{
opts.ConnectionString = Environment.GetEnvironmentVariable(
"APPLICATIONINSIGHTS_CONNECTION_STRING");
});
});
使用 Jaeger 在本地查看跟踪
若要进行本地开发,请使用持久任务计划程序模拟器及 Jaeger 来查看跟踪。 使用一个 docker-compose.yml 来启动两个服务:
services:
dts-emulator:
image: mcr.microsoft.com/dts/dts-emulator:latest
ports:
- "8080:8080" # gRPC
- "8082:8082" # Dashboard
jaeger:
image: jaegertracing/jaeger:latest
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
启动基础结构:
docker compose up -d
运行应用程序后,在 http://localhost:16686 打开 Jaeger UI,并搜索您的服务名称(例如,durable-worker)以查看跟踪。
对于使用 Durable Functions 进行本地开发,分布式跟踪数据将发送到 Application Insights。 若要查看 Application Insights 中的跟踪,请转到 Azure 门户中的 Transaction 搜索或 Application Map。
对于本地可见性,你还可以通过向函数应用的 Program.cs 添加适当的 OpenTelemetry 包和导出器配置,在 Application Insights 旁边设置 OTLP 导出器。
跟踪数据的显示内容
持久任务 SDK 生成的跟踪数据包括:
| 范围类型 | Description |
|---|---|
create_orchestration |
当安排新编排时发出的客户端追踪跨度 |
orchestration |
涵盖完整执行生命周期的服务器端编排跨度 |
activity:<name> |
每个活动调用的时间间隔,显示计时和结果 |
sub_orchestration:<name> |
每个子编排调用的跨度 |
timer |
持久计时器等待的时间段 |
每个范围包括属性,例如durabletask.type,durabletask.task.name和durabletask.task.instance_iddurabletask.task.task_id。 失败的活动和编排流程包含在跨度状态和事件中的错误详细信息。
故障排除
| 問题 | 解决方案 |
|---|---|
| 没有任何痕迹出现 | 检查是否已注册 Microsoft.DurableTask 活动源并可访问导出器终结点。 |
| 跟踪日志不完整 | 请确保在初始化 Durable Task SDK(尤其是在 JavaScript/TypeScript 中)之前初始化 OpenTelemetry SDK。 |
| Application Insights 中缺少时间段 | 禁用或调整 采样设置 ,以防止删除跟踪数据。 |
| 跟踪信息不相关 | 检查是否使用持久任务计划程序作为后端。 跟踪上下文传播需要调度器。 |