如何覆盖Serilog对Guid等内置基元类型默认调用ToString的日志输出行为?
配置不生效的原因
Destructure.ByTransforming<T>仅针对需要解构的非原生复杂类型生效,Guid是.NET原生值类型,Serilog处理时会直接调用其默认ToString()方法,不会触发解构转换逻辑,因此你的原有配置无效。
最优解决方案(全局生效,兼容所有Sink)
实现IScalarConversionPolicy接口自定义标量转换规则,无需修改任何业务代码,所有Sink(Console/File/Slack等)会自动共用该转换规则:
- 首先实现自定义标量转换器:
using Serilog.Core; using Serilog.Events; public class GuidScalarConverter : IScalarConversionPolicy { public bool TryConvertToScalar(object value, out ScalarValue result) { if (value is Guid guid) { // 直接调用你已实现的ShortForm扩展方法 result = new ScalarValue(guid.ShortForm()); return true; } result = null; return false; } }
- 在LoggerConfiguration中注册转换器:
Log.Logger = new LoggerConfiguration() // 新增这行注册自定义标量转换器 .Destructure.With<GuidScalarConverter>() // 其余原有配置保持不变,原有Destructure.ByTransforming<Guid>的配置可以删除 .WriteTo.Console(formatter: _consoleExpression) .CreateLogger();
备选方案(仅特定Sink输出短Guid)
如果你只需要部分Sink输出短Guid,其余Sink保留完整Guid,可以通过给ExpressionTemplate注册自定义函数实现:
// 将GuidExtensions替换为你定义ShortForm扩展方法的静态类名 var nameResolver = new StaticMemberNameResolver(typeof(GuidExtensions)); var _consoleExpression = new ExpressionTemplate( // 模板中对应Guid的位置直接调用ShortForm方法 "[{@t:HH:mm:ss} {@l:u3}] {ShortForm(Guid)} {@m}\n{@x}", theme: TemplateTheme.Literate, nameResolver: nameResolver);
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

