.NET 7 WebAPI集成OpenTelemetry报错:JaegerExportProtocol不存在
解决OpenTelemetry Jaeger导出器配置错误:“JaegerExportProtocol不存在”及类型转换问题
问题概述
在.NET 7 WebAPI应用中使用OpenTelemetry实现链路追踪时,默认Jaeger配置可正常生成追踪数据,但自定义Jaeger实例配置时出现两个编译错误:string无法隐式转换为System.Uri,以及JaegerExportProtocol名称不存在于当前上下文。
错误日志
C:\Users\user\..\src\Program.cs(79,26): error CS0029: Cannot implicitly convert type 'string' to 'System.Uri' [C:\Users\user\..\src\CustomerAPI.csproj] C:\Users\user\..\src\Program.cs(80,26): error CS0103: The name 'JaegerExportProtocol' does not exist in the current context [C:\Users\user\..\src\CustomerAPI.csproj] The build failed. Fix the build errors and run again.
正常运行的配置
代码配置
// Program.cs using System.Reflection; using OpenTelemetry; using OpenTelemetry.Trace; using OpenTelemetry.Resources; using OpenTelemetry.Metrics; using OpenTelemetry.Instrumentation.Http; using OpenTelemetry.Exporter.Jaeger; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; var appBuilder = WebApplication.CreateBuilder(args); appBuilder.Services.AddOpenTelemetry() .ConfigureResource(builder => builder.AddService(serviceName: "CustomerAPI")) .WithTracing(builder => builder .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddConsoleExporter() .AddJaegerExporter()) .WithMetrics(builder => builder.AddConsoleExporter()); appBuilder.Services.AddControllers(); appBuilder.Services.AddHttpClient(); appBuilder.Services.AddEndpointsApiExplorer(); appBuilder.Services.AddSwaggerGen(); var app = appBuilder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
开发环境Jaeger部署命令
docker run -d --name jaeger -p 16686:16686 -p 6831:6831/udp jaegertracing/all-in-one:1.22
问题配置(无法运行)
Kubernetes环境Jaeger服务信息
执行命令:
kubectl -n jaeger get services
输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP,5778/TCP 8d jaeger-collector ClusterIP 10.XX.XXX.XX <none> 14267/TCP,14268/TCP,9411/TCP 8d jaeger-query LoadBalancer 10.XXX.XXX.XXX 10.X.XX.XX 80:XXXXX/TCP 8d zipkin ClusterIP None <none> 9411/TCP 8d
自定义配置代码
using System.Reflection; using OpenTelemetry; using OpenTelemetry.Trace; using OpenTelemetry.Resources; using OpenTelemetry.Metrics; using OpenTelemetry.Instrumentation.Http; using OpenTelemetry.Exporter.Jaeger; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; var appBuilder = WebApplication.CreateBuilder(args); var url = "http://localhost:14268"; var endpoint = Convert.ToString(url); appBuilder.Services.AddOpenTelemetry() .ConfigureResource(builder => builder.AddService(serviceName: "CustomerAPI")) .WithTracing(builder => builder .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddConsoleExporter() .AddJaegerExporter(o => { o.AgentHost = "localhost"; o.AgentPort = 6831; o.Endpoint = endpoint; o.Protocol = JaegerExportProtocol.UdpCompactThrift; })) .WithMetrics(builder => builder.AddConsoleExporter()); appBuilder.Services.AddControllers(); appBuilder.Services.AddHttpClient(); appBuilder.Services.AddEndpointsApiExplorer(); appBuilder.Services.AddSwaggerGen(); var app = appBuilder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
依赖包配置
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" /> <PackageReference Include="OpenTelemetry" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.5.0" /> <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.0-beta.1" /> <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.0-beta.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> <PackageReference Include="System.Net.Http" Version="4.3.4" /> </ItemGroup> </Project>
解决方案
- 修正
Endpoint类型错误JaegerExporterOptions.Endpoint属性的类型是Uri,不能直接赋值字符串。需要创建Uri实例:
// 替换原有的endpoint变量定义 var endpoint = new Uri("http://localhost:14268");
- 替换
JaegerExportProtocol为正确枚举
在OpenTelemetry.Exporter.Jaeger 1.5.0版本中,原JaegerExportProtocol枚举已被重命名为JaegerExportProtocolType,需修改配置:
o.Protocol = JaegerExportProtocolType.UdpCompactThrift;
- 避免Agent与Endpoint配置冲突
UDP协议使用AgentHost和AgentPort,HTTP协议使用Endpoint,两者不要同时配置:
- 若使用UDP(对应Jaeger Agent的6831端口),保留
AgentHost、AgentPort和UDP类型的Protocol,移除Endpoint - 若使用HTTP(对应Jaeger Collector的14268端口),配置
Endpoint和JaegerExportProtocolType.HttpBinaryThrift,移除AgentHost和AgentPort
修正后的配置示例
.AddJaegerExporter(o => { // UDP协议配置(对应开发环境Jaeger Agent) o.AgentHost = "localhost"; o.AgentPort = 6831; o.Protocol = JaegerExportProtocolType.UdpCompactThrift; // 若使用Kubernetes集群内的Jaeger Collector HTTP接口,替换为: // o.Endpoint = new Uri("http://jaeger-collector.jaeger.svc.cluster.local:14268"); // o.Protocol = JaegerExportProtocolType.HttpBinaryThrift; })
内容的提问来源于stack exchange,提问作者Golide
相关产品推荐
相关产品推荐

