Serilog OpenTelemetrySink在Aspire Dashboard中复杂对象显示为kvlistValue问题排查
问题核心
用.NET原生OpenTelemetry包记录复杂结构化对象时,Aspire Dashboard里显示的是正常的JSON字符串;但换成Serilog的OpenTelemetrySink来记录,相同对象就变成kvlistValue格式显示。已知OpenTelemetry规范要求用这个格式传输,但预期Collector能将其解码为对象或转成JSON字符串,现在需要确认是配置错误还是Sink本身的bug。
先排查配置遗漏点
你当前的Serilog配置里没有指定复杂对象的序列化方式——Serilog OpenTelemetrySink默认会把复杂对象转成OTLP规范要求的kvlistValue格式,这是符合协议的正常行为。而.NET原生OpenTelemetry包之所以能显示JSON,是因为它针对Aspire Dashboard做了适配处理,直接把对象序列化成了JSON字符串。
可尝试的解决方向
手动序列化复杂对象
写日志时先把复杂对象转成JSON字符串再传入:var complexObj = new { Name = "测试", Details = new { Id = 1, Value = "示例" } }; Log.Information("收到复杂对象: {ComplexObj}", JsonSerializer.Serialize(complexObj));也可以全局配置Serilog的解构规则,自动把指定类型转成JSON:
LoggerConfiguration loggingConfiguration = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .Destructure.ByTransforming<你的复杂类型>(obj => JsonSerializer.Serialize(obj));调整OpenTelemetry Collector配置
如果想让Collector自动把kvlistValue转成JSON,需要在Collector的日志处理管道中添加对应处理器(比如attributes处理器),将结构化的kvlistValue字段转换为JSON格式。升级Serilog Sink版本
检查你使用的Serilog.Sinks.OpenTelemetry是否为最新版本,旧版本可能存在序列化逻辑问题,升级后或许能解决显示差异。
结论
当前的显示差异并非配置错误,而是Serilog OpenTelemetrySink严格遵循OTLP协议的kvlistValue格式,而.NET原生OpenTelemetry包针对Aspire Dashboard做了适配性的JSON序列化。要统一显示为JSON字符串,可通过自定义序列化、调整Collector配置或升级Sink版本尝试解决。
内容的提问来源于stack exchange,提问作者Richard Collette

