什么是OpenTelemetry?
OpenTelemetry合并了OpenTracing和OpenCensus项目,提供了一组API和库来标准化遥测数据的采集和传输
使用OpenTelemetry SDK
OpenTelemetry .NET https://github.com/open-telemetry/opentelemetry-dotnet
1. 打开VS2019(Version 16.9.7)创建项目Demo.OpenTelemetry,使用模板 ASP.NET Core Web APP
2. 安装OpenTelemetry.Instrumentation.AspNetCore、OpenTelemetry.Extensions.Hosting和OpenTelemetry.Exporter.Console三个包,目前还是 prerelease版本
3. 修改startup.cs文件
public void ConfigureServices(IServiceCollection services)
{
services.AddOpenTelemetryTracing(builder =>
{
builder
.AddAspNetCoreInstrumentation()
.AddConsoleExporter();
});
services.AddRazorPages();
}
4. 创建项目Demo.Opentelemetry.WebAPI,使用模板 ASP.NET Core Web API
5. 同样安装OpenTelemetry.Instrumentation.AspNetCore、OpenTelemetry.Extensions.Hosting和OpenTelemetry.Exporter.Console三个包
6. 修改startup.cs文件
public void ConfigureServices(IServiceCollection services)
{
services.AddOpenTelemetryTracing(builder =>
{
builder
.AddAspNetCoreInstrumentation()
.AddConsoleExporter();
});
services.AddControllers();
}
7. 在Demo.OpenTelemetry项目中修改Index.cshtml.cs文件,在OnGet时请求API
public async Task OnGetAsync()
{
var client = new HttpClient();
var res = await client.GetAsync("http://localhost:21900/weatherforecast");
}
8. 运行,可以看到output输出
先看Demo.OpenTelemetry项目输出,这里可以看到 Activity.Id=00-d26c0a8b065dc44891c00cf25add992d-4b88086aa4e62a4e-01
再查看Demo.Opentelemetry.WebAPI,可以看到 Activity.ParentId 正好等于Demo.OpenTelemetry项目的 Activity.Id
Log是如何进行关联的?
第一个项目发出Http GET请求后,第二个API项目是如何知道ParentId,我们打开QuickWatch来看一下http请求中包含的信息
在headers中多了一个 request-Id 信息,值是"|a8b97100-4e3e140edec3548f.",查看对应的log信息可以看到这次请求在API的日志中,ParentId就是刚才request-Id的值。
但是我们随后请求中,header中没有了request-Id,而是多了一个traceparent。查看API对应的日志,traceparent的值成了对应的ParentId
检查了一下文档,traceparent是W3C Trace-Context 协议的属性名称,而request-Id是 HttpCorrelationProtocol(https://github.com/dotnet/runtime/blob/main/src/libraries/System.Diagnostics.DiagnosticSource/src/HttpCorrelationProtocol.md)的属性名称,并且即将弃用。
查看微软官网的解释 https://docs.microsoft.com/zh-cn/dotnet/core/compatibility/core-libraries/5.0/default-activityidformat-changed
.NET Core 3.0 中引入了 W3C 活动 ID 格式,作为分层 ID 格式的替代格式。 但是,为了保持兼容性,直到 .NET 5.0 才将 W3C 格式设置为默认格式。 .NET 5 中更改了默认格式,原因是 W3C 格式已获得批准,并广泛用于多种语言实现。
这里我没有按微软文档推荐的做法,而是简单的加了一句,这样第一次请求也会是traceparent了。
System.Diagnostics.Activity.DefaultIdFormat = System.Diagnostics.ActivityIdFormat.W3C;
W3C TraceContext 的关联标头
此规范定义了标准 HTTP 标题和值格式,以传播支持分布式跟踪场景的上下文信息。该规范规范了服务之间如何发送和修改上下文信息。上下文信息在分布式系统中唯一识别单个请求,并定义了添加和传播特定于提供商的上下文信息的手段。该协议定义:
- traceparent:承载调用的全局唯一操作 ID 和唯一标识符。
- tracestate:承载系统特定的跟踪上下文。
协议详情:https://w3c.github.io/trace-context/