.NET7中使用Serilog格式化XML字符串并实现日志换行显示求助
解决Serilog日志中XML格式化显示换行的问题
问题根源
核心问题是字符串插值导致Serilog转义了XML中的换行符。使用$""拼接日志消息时,XML里的换行符会被当作普通字符串处理,Serilog输出时会显示转义后的\r\n而非实际换行。同时原有的XML格式化方法可进一步简化优化。
解决方案步骤
1. 优化XML格式化方法
用XDocument简化逻辑,更高效易维护:
public static string FormatXml(string xml) { try { var doc = XDocument.Parse(xml); return doc.ToString(Formatting.Indented); } catch (XmlException ex) { // 格式化失败返回原XML,可按需记录错误日志 _log?.LogWarning(ex, "XML格式化失败"); return xml; } }
若需序列化对象为格式化XML,修改Serialize方法:
public static string Serialize<T>(this T value) { if (value == null) return string.Empty; var serializer = new XmlSerializer(typeof(T)); var settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = false }; using var sw = new StringWriter(); using var writer = XmlWriter.Create(sw, settings); serializer.Serialize(writer, value); return sw.ToString(); }
2. 修改Serilog日志写法
禁止使用字符串插值,改用Serilog结构化消息模板,通过@标记保留原始格式:
public string ProcessVerificationRequest(string requestXmlString) { var formattedXml = XmlSerializationHelper.FormatXml(requestXmlString); // @符号告诉Serilog保留XML的换行和缩进 _log.LogInformation("验证请求XML:\n{@Xml}", formattedXml); XDocument responseDocument = ReadXmlFile(); // 响应日志同理处理 var formattedResponse = XmlSerializationHelper.FormatXml(responseDocument.ToString()); _log.LogInformation("验证响应XML:\n{@Xml}", formattedResponse); // 后续业务逻辑... return formattedResponse; }
3. 确保Serilog输出模板配置正确
检查Serilog配置,确保输出模板支持换行,例如控制台日志配置:
Log.Logger = new LoggerConfiguration() .WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message:lj}{NewLine}{Exception}") .CreateLogger();
其中{Message:lj}表示消息左对齐并保留换行,{NewLine}确保每条日志后换行。
验证效果
修改后日志会显示格式化后的XML,每个标签单独一行:
2024-05-20 14:30:00 [Information] 验证请求XML: <FPEnvelope xmlns="urn:iso:std:iso:20022:tech:xsd:verification_request" xmlns:document="urn:iso:std:iso:20022:tech:xsd:acmt.023.001.03" xmlns:header="urn:iso:std:iso:20022:tech:xsd:head.001.001.03"> <header:AppHdr> <header:Fr> <header:FIId> <header:FinInstnId> <header:Othr> <header:Id>10000091</header:Id> </header:Othr> </header:FinInstnId> </header:FIId> </header:Fr> <!-- 后续标签... --> </header:AppHdr> </FPEnvelope>
内容的提问来源于stack exchange,提问作者Sylla
相关产品推荐
相关产品推荐

