OpenTelemetry+Blazor Hybrid:Spans/Activities无法输出至控制台/文件
解决方案:.NET8 Blazor Hybrid中OpenTelemetry+NLog的正确配置
1. 修复ActivitySource.StartActivity返回null的核心问题
关键调整点
- 保证名称完全匹配:
TelemetryConstants.ActivitySource的Name必须和AddSource(TelemetryConstants.ServiceName)中的名称完全一致,否则OTel监听器无法识别自定义Activity。 - 避免无效Activity创建:在
Telemetry类中提前检查是否有活跃的监听器,防止创建无意义的Activity实例:
public Telemetry([CallerMemberName] string methodName = "") { _MethodName = methodName; // 先判断是否有监听器,再创建Activity if (TelemetryConstants.ActivitySource.HasListeners()) { _Activity = TelemetryConstants.ActivitySource.StartActivity(_MethodName); AddTag("operation.datetimeoffset.utcnow.begin", DateTimeOffset.UtcNow.ToString(_DateFormat)); } }
2. 过滤冗余日志并优化性能
当前大量无价值的Microsoft.AspNetCore.Components.RenderTree.Renderer日志、全局Trace级别是性能卡顿的主要原因,修改日志配置:
builder.Logging.ClearProviders(); // 降低全局最低日志级别为Debug,减少冗余输出 builder.Logging.SetMinimumLevel(LogLevel.Debug); // 直接屏蔽Blazor渲染树的日志 builder.Logging.AddFilter("Microsoft.AspNetCore.Components.RenderTree", LogLevel.None); builder.Logging.AddNLog();
3. 简化OpenTelemetry配置,避免重复导出
你当前的配置同时启用了追踪和日志的OTel导出,导致重复输出和性能损耗,调整为只保留自定义Activity的追踪配置:
builder.Services.AddOpenTelemetry() .ConfigureResource(resource => resource.AddService(serviceName: TelemetryConstants.ServiceName, serviceVersion: TelemetryConstants.ServiceVersion) ) .WithTracing(tracing => { tracing .AddSource(TelemetryConstants.ServiceName) // 仅采样自定义Activity,排除.NET默认库的追踪 .SetSampler(new AlwaysOnSampler()) .AddConsoleExporter(options => { options.Targets = OpenTelemetry.Exporter.ConsoleExporterOutputTargets.Debug; }); }); // 移除重复的Logging.AddOpenTelemetry()配置
4. 将Activity耗时等信息输出到NLog文件
方式一:在Telemetry类中直接记录日志
修改Telemetry类,注入ILogger并在Dispose时计算耗时写入日志:
private readonly ILogger<Telemetry> _logger; // 通过依赖注入获取Logger public Telemetry(ILogger<Telemetry> logger, [CallerMemberName] string methodName = "") { _logger = logger; _MethodName = methodName; if (TelemetryConstants.ActivitySource.HasListeners()) { _Activity = TelemetryConstants.ActivitySource.StartActivity(_MethodName); AddTag("operation.begin", DateTimeOffset.UtcNow.ToString(_DateFormat)); } } public void Dispose() { if (_Activity != null) { var endTime = DateTimeOffset.UtcNow; AddTag("operation.end", endTime.ToString(_DateFormat)); // 计算并记录耗时 var beginTime = DateTimeOffset.Parse(_Activity.Tags.First(t => t.Key == "operation.begin").Value); var duration = endTime - beginTime; _logger.LogInformation("Activity {ActivityName} finished, Duration: {Duration}ms", _MethodName, duration.TotalMilliseconds); _Activity.Dispose(); } GC.SuppressFinalize(this); }
使用时通过依赖注入获取Telemetry:
using (var telemetry = _serviceProvider.GetRequiredService<Telemetry>()) using (_Logger.BeginScope($"{nameof(DeleteTblEventChoice)}:{eventChoiceId}")) { _Logger.LogDebug($"Delete {nameof(tblEventChoices)} with ID: [{eventChoiceId}]"); return _TblEventChoicesRepository.DeleteTblEventChoice(eventChoiceId); }
方式二:使用OTel直接导出Activity到NLog
安装OpenTelemetry.Exporter.NLog包后,在Tracing配置中添加NLog导出器:
.WithTracing(tracing => { tracing .AddSource(TelemetryConstants.ServiceName) .AddNLogExporter(); });
同时在NLog.config中配置对应的日志目标,接收OTel追踪数据。
5. 完整MauiProgram.cs配置示例
var builder = MauiApp.CreateBuilder(); // 其他服务注册逻辑... // OpenTelemetry配置 builder.Services.AddOpenTelemetry() .ConfigureResource(resource => resource.AddService(serviceName: TelemetryConstants.ServiceName, serviceVersion: TelemetryConstants.ServiceVersion) ) .WithTracing(tracing => { tracing .AddSource(TelemetryConstants.ServiceName) .SetSampler(new AlwaysOnSampler()) .AddConsoleExporter(options => { options.Targets = OpenTelemetry.Exporter.ConsoleExporterOutputTargets.Debug; }); // 若使用NLog导出Activity,取消注释并安装对应包 // .AddNLogExporter(); }); // 日志配置 builder.Logging.ClearProviders(); builder.Logging.SetMinimumLevel(LogLevel.Debug); builder.Logging.AddFilter("Microsoft.AspNetCore.Components.RenderTree", LogLevel.None); builder.Logging.AddNLog(); // 注册Telemetry为瞬态服务 builder.Services.AddTransient<Telemetry>(); var app = builder.Build(); // 应用启动逻辑...
验证要点
StartActivity不再返回null- 控制台和NLog文件仅输出自定义Activity的耗时日志及必要业务日志
- 应用运行无明显卡顿
内容的提问来源于stack exchange,提问作者B-M
相关产品推荐
相关产品推荐

