如何将Serilog日志中的ExceptionDetail结构转换为字符串?
解决Serilog ExceptionDetail扁平化存储到数据库的问题
要把Serilog生成的ExceptionDetail复杂对象扁平化为单个字符串存入数据库,你可以通过自定义JSON格式化器改写日志属性的输出逻辑,具体步骤如下:
1. 实现自定义JSON格式化器
继承Serilog默认的JsonFormatter,重写WriteProperties方法,识别ExceptionDetail属性并将其序列化为完整的JSON字符串,替换原有的嵌套属性结构:
using Serilog.Formatting.Json; using Serilog.Events; using Newtonsoft.Json; // 或使用System.Text.Json,按需选择 public class FlatExceptionJsonFormatter : JsonFormatter { protected override void WriteProperties( IReadOnlyDictionary<string, LogEventPropertyValue> properties, TextWriter output) { var modifiedProps = new Dictionary<string, LogEventPropertyValue>(properties); // 检查并处理ExceptionDetail属性 if (modifiedProps.TryGetValue("ExceptionDetail", out var exceptionValue)) { // 将嵌套的ExceptionDetail对象序列化为JSON字符串 var exceptionJson = JsonConvert.SerializeObject(exceptionValue); // 替换为字符串类型的属性值 modifiedProps["ExceptionDetail"] = new ScalarValue(exceptionJson); } // 调用基类方法输出处理后的属性 base.WriteProperties(modifiedProps, output); } }
如果项目使用System.Text.Json而非Newtonsoft.Json,替换序列化代码即可:
var exceptionJson = System.Text.Json.JsonSerializer.Serialize(exceptionValue);
2. 配置Http Sink使用自定义格式化器
在Serilog初始化配置中,为WriteTo.Http指定自定义格式化器:
Log.Logger = new LoggerConfiguration() .Enrich.WithExceptionDetails() .WriteTo.Http( requestUri: "http://你的日志服务器地址", formatter: new FlatExceptionJsonFormatter() ) // 保留原有的控制台/文件日志配置 .WriteTo.Console() .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day) .CreateLogger();
3. 日志服务器端处理
此时日志服务器收到的ExceptionDetail字段是一个完整的JSON字符串,只需将其存入数据库的长文本类型字段(比如SQL Server的NVARCHAR(MAX)、MySQL的TEXT)即可。后续需要查看异常详情时,可直接解析该JSON字符串获取所有属性。
内容的提问来源于stack exchange,提问作者Ivan Debono
相关产品推荐
相关产品推荐

