如何让NLog的Info方法将自定义对象以JSON格式写入日志?
解决NLog输出自定义对象仅显示类型名的问题
核心原因
直接将自定义对象传入_logger.Info(object)时,NLog默认仅调用对象的ToString()方法,因此日志中只会显示类型全称而非属性数据。要输出对象的JSON结构化内容,需使用NLog的结构化日志特性,并配合正确的配置。
解决方案
1. 修改日志写入代码(结构化日志方式)
在NlogCustom类的WriteMessage方法中,使用NLog的结构化日志语法(通过@标记需要序列化的对象):
public void WriteMessage(string message) { var tstlogentry = new TestLogEntry { Id = 1, Name = "Alexander" }; // 使用@符号告知NLog序列化对象属性 _logger.Info("请求日志详情: {@TestLogEntry}", tstlogentry); }
2. 调整NLog配置(确保属性被序列化输出)
你的nlog.config中已开启includeAllProperties="true",只需确保JsonLayout正确包含结构化属性。可以保留现有配置,或显式添加属性来单独输出对象:
<layout xsi:type="JsonLayout" includeAllProperties="true"> <attribute name="date" layout="${longdate}" /> <attribute name="message" layout="${message}" /> <!-- 可选:单独指定输出自定义对象,encode="false"避免JSON被转义 --> <attribute name="logEntry" layout="${event-properties:TestLogEntry}" encode="false" /> </layout>
3. 可选:通过WithProperty添加对象属性
如果不想修改日志消息内容,也可以直接将对象添加到日志事件的属性集合中:
public void WriteMessage(string message) { var tstlogentry = new TestLogEntry { Id = 1, Name = "Alexander" }; // 将对象添加到日志属性,配合includeAllProperties输出 _logger.WithProperty("TestLogEntry", tstlogentry).Info(message); }
验证结果
修改后,日志文件将输出包含对象属性的JSON内容,示例如下:
{ "date": "2024-01-23 13:17:30.8058", "message": "请求日志详情: TestNlog.TestLogEntry", "TestLogEntry": {"Id":1,"Name":"Alexander"} }
额外注意事项
- 确保NLog及NLog.Web.AspNetCore NuGet包为最新稳定版,避免版本兼容问题
- 若自定义对象包含复杂嵌套属性,NLog会自动递归序列化(默认深度限制为5层,可通过配置调整)
内容的提问来源于stack exchange,提问作者alienavatar
相关产品推荐
相关产品推荐

