You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework下Activity.SpanId始终为全0的问题排查

.NET Framework(Mono运行时)下Activity SpanId未自动生成的原因及解决方案

问题重现

你的C#代码如下:

using System.Diagnostics;
using System.Runtime.InteropServices;

var listener = new ActivityListener()
{
    // This is only for internal Sentry events
    ShouldListenTo = (source) => source.Name.StartsWith("ConsoleApp9"),
    Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
    ActivityStarted = activity => Console.WriteLine($"Started activity {activity.SpanId}"),
    ActivityStopped = _ => { }
};
ActivitySource.AddActivityListener(listener);

var tracer = new ActivitySource("ConsoleApp9");

Console.WriteLine("Framework: {0}", RuntimeInformation.FrameworkDescription);
Console.WriteLine("Starting activity...");
var data = tracer.StartActivity("foo");
Console.WriteLine($"Stopping activity {data?.SpanId}");
data?.Stop();

已显式引用System.Diagnostics.DiagnosticSource 8.0.0 NuGet包以兼容.NET Framework 4.8:

  • 在.NET 8.0环境运行时,输出正常生成SpanId
  • 在.NET Framework 4.8 + Mono 6.12.0.199环境运行时,SpanId始终为0000000000000000

原因分析

核心问题在于旧版本Mono对DiagnosticSource的特性支持不完善:

  • .NET Framework原生并不包含Activity相关的完整实现,依赖NuGet包System.Diagnostics.DiagnosticSource提供兼容层
  • Mono 6.12.0属于较旧的版本,其CLR底层没有实现Activity自动生成TraceId/SpanId的逻辑,而NuGet包的兼容代码无法在该运行时环境中触发自动ID生成逻辑
  • 采样策略设置为ActivitySamplingResult.AllData仅控制是否保留Activity数据,不负责ID的生成

解决方案

方案1:升级Mono版本

更新到较新的Mono版本(推荐Mono 6.12以上的稳定版,或直接使用.NET 5+的Mono运行时),新版本对DiagnosticSource的支持更完善,能自动生成Activity的ID。

方案2:手动生成ID

如果无法升级Mono,可以手动初始化TraceId和SpanId,确保ID正常生成:

// 生成随机的TraceId和SpanId
var traceId = ActivityTraceId.CreateRandom();
var spanId = ActivitySpanId.CreateRandom();
var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.None);

// 使用带上下文的重载启动Activity
var data = tracer.StartActivity("foo", ActivityKind.Internal, activityContext);

或者在ActivityListener的ActivityStarted事件中补全默认ID:

ActivityStarted = activity => 
{
    // 检查ID是否为默认值,若则手动生成
    if (activity.SpanId == default)
    {
        activity.SetIdFormat(ActivityIdFormat.W3C);
        activity.SetTraceId(ActivityTraceId.CreateRandom());
        activity.SetSpanId(ActivitySpanId.CreateRandom());
    }
    Console.WriteLine($"Started activity {activity.SpanId}");
};

补充说明

在.NET Framework环境下,System.Diagnostics.DiagnosticSource包的功能受限于底层运行时的支持,旧版Mono缺少自动ID生成的底层实现,因此需要通过上述方式手动补全或升级运行时来解决问题。

内容的提问来源于stack exchange,提问作者James Crosswell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:08:21