如何配置NLog将结构化日志保存为标准JSON数组格式?
解决NLog输出JSON数组并包含指定字段的问题
一、问题本质
默认NLog使用JsonLayout配合File目标时,每次日志会追加单个独立JSON对象到文件,导致输出文件并非合法的JSON数组。添加indentJson="true"仅能格式化单个对象的缩进,无法改变整体结构。
二、配置修改实现合法JSON数组输出
方法1:使用NLog官方JsonArrayLayout(推荐,NLog 4.6+支持)
直接用JsonArrayLayout替代JsonLayout,它会自动将所有日志条目包裹在数组中,处理逗号分隔符,生成合法JSON结构。
修改后的NLog.config示例:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="jsonFile" xsi:type="File" fileName="log.json" keepFileOpen="true" encoding="utf-8"> <!-- 使用JsonArrayLayout生成JSON数组 --> <layout xsi:type="JsonArrayLayout" indentJson="true"> <!-- 配置你需要的字段 --> <attribute name="DateTime" layout="${date:format=yyyy-MM-dd HH:mm:ss.fff}" /> <attribute name="ProjectName" layout="${assembly-name}" /> <attribute name="ClassName" layout="${callsite-class}" /> <attribute name="MethodName" layout="${callsite-method}" /> <attribute name="LineNumber" layout="${callsite-linenumber}" /> <attribute name="ExecutionDurationMs" layout="${duration:format=ms}" /> <!-- 可选:添加日志级别等额外字段 --> <attribute name="LogLevel" layout="${level}" /> </layout> </target> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="jsonFile" /> </rules> </nlog>
关键配置说明:
JsonArrayLayout:自动处理数组包裹、条目间逗号分隔,无需手动维护首尾字符keepFileOpen="true":避免频繁IO操作,同时确保逗号正确添加(不会在最后一条日志后留多余逗号)indentJson="true":格式化输出的JSON,提升可读性- 字段对应布局:
${assembly-name}:获取当前项目名称${callsite-class}/${callsite-method}/${callsite-linenumber}:获取触发日志的类名、方法名、行号(需项目编译时生成PDB调试文件)${duration:format=ms}:输出步骤执行时长(单位毫秒,需代码中调用logger.StartTimer()启动计时)
方法2:旧版本NLog兼容方案(无JsonArrayLayout时)
如果使用NLog 4.6以下版本,可通过File目标的header/footer配合JsonLayout实现,但需注意最后一条日志的逗号问题:
<target name="jsonFile" xsi:type="File" fileName="log.json" header="[" footer="]" encoding="utf-8"> <layout xsi:type="JsonLayout" indentJson="true" separator=","> <!-- 同上述字段配置 --> </layout> </target>
⚠️ 注意:此方案会在最后一条日志后保留多余逗号,导致JSON不合法,需手动清理或使用BufferingWrapper批量写入(批量写入时需设置bufferSize控制写入时机)。
三、代码中启用计时功能
要正确获取ExecutionDurationMs字段,需在业务代码中启动NLog计时器:
// 示例:在Form1或Logger1类中 private static readonly Logger logger = LogManager.GetCurrentClassLogger(); public void ExecuteStep() { // 启动计时器 logger.StartTimer(); // 执行你的业务逻辑 // ... // 记录日志,自动带上时长 logger.Info("业务步骤执行完成"); }
四、Excel中分析JSON日志
生成合法JSON数组后,可直接在Excel中解析为表格:
- 打开Excel,切换到「数据」选项卡
- 点击「获取数据」→「来自文件」→「来自JSON」
- 选择生成的
log.json文件,Excel会自动将JSON数组转换为结构化表格,支持筛选、排序、统计等分析操作
内容的提问来源于stack exchange,提问作者eusataf
相关产品推荐
相关产品推荐

