使用多个参数在 NLog 中将对象打印为 JSON
Print object as JSON in NLog with multiple arguments
我开始使用 NLog,只有一个简单的文件输出:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target
name="logFile"
xsi:type="File"
layout="${longdate} ${callsite} ${message} ${exception:format=tostring}"
fileName="${basedir}/logs/Log.txt"
archiveFileName="${basedir}/logs/Log.{#}.txt"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="60"
concurrentWrites="true"
keepFileOpen="false"
encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logFile" />
</rules>
</nlog>
我发现我可以 serialise objects in JSON form 进行日志记录,使用 @
前缀,例如:
Logger.Debug("Request: {@0}", request);
这很好用,只要我只有一个参数。但后来我开始在我的日志中发现未格式化的占位符:
Processing purchase order {0}/{1} for user {@2}
经过一些调查,这似乎与我使用的是命名索引还是编号索引以及 JSON-格式前缀 @
的位置有关。我写了一个快速测试:
User user = new User("Bill", "Gates", "12345");
Logger.Info("All numbered");
Logger.Info("0: {@0}, 1: {1}", user, 1); // 0: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, 1: 1
Logger.Info("0: {0}, 1: {@1}", 1, user); // 0: {0}, 1: {@1}
Logger.Info("Object named, int numbered");
Logger.Info("User: {@user}, 1: {1}", user, 1); // User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, 1: 1
Logger.Info("0: {0}, User: {@user}", user, 1); // 0: {0}, User: {@user}
Logger.Info("Object numbered, int named");
Logger.Info("0: {@0}, n: {n}", user, 1); // 0: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, n: 1
Logger.Info("n: {n}, 1: {@1}", 1, user); // n: 1, 1: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}
Logger.Info("All named");
Logger.Info("User: {@user}, n: {n}", user, 1); // User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, n: 1
Logger.Info("n: {n}, User: {@user}", 1, user); // n: 1, User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}
我做错了什么?当然规则不是“如果使用 @
它必须是第一个参数,或者它必须遵循命名参数”。我意识到有关 @
前缀的详细信息在结构化日志记录部分下,但我并不完全理解。我不允许将它与平面文件一起使用吗?
NLog“作弊”并且仅在看到第一个时激活其 message-template-parser
place-holder 使用 message-template-logic(就像使用名字或 @
)。
NLog 在不需要使用 message-template-parser 时回退到标准 string.Format
。这既是为了提高性能,也是为了减少因未按预期使用 string.Format
而导致更改中断的可能性。
我开始使用 NLog,只有一个简单的文件输出:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target
name="logFile"
xsi:type="File"
layout="${longdate} ${callsite} ${message} ${exception:format=tostring}"
fileName="${basedir}/logs/Log.txt"
archiveFileName="${basedir}/logs/Log.{#}.txt"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="60"
concurrentWrites="true"
keepFileOpen="false"
encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logFile" />
</rules>
</nlog>
我发现我可以 serialise objects in JSON form 进行日志记录,使用 @
前缀,例如:
Logger.Debug("Request: {@0}", request);
这很好用,只要我只有一个参数。但后来我开始在我的日志中发现未格式化的占位符:
Processing purchase order {0}/{1} for user {@2}
经过一些调查,这似乎与我使用的是命名索引还是编号索引以及 JSON-格式前缀 @
的位置有关。我写了一个快速测试:
User user = new User("Bill", "Gates", "12345");
Logger.Info("All numbered");
Logger.Info("0: {@0}, 1: {1}", user, 1); // 0: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, 1: 1
Logger.Info("0: {0}, 1: {@1}", 1, user); // 0: {0}, 1: {@1}
Logger.Info("Object named, int numbered");
Logger.Info("User: {@user}, 1: {1}", user, 1); // User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, 1: 1
Logger.Info("0: {0}, User: {@user}", user, 1); // 0: {0}, User: {@user}
Logger.Info("Object numbered, int named");
Logger.Info("0: {@0}, n: {n}", user, 1); // 0: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, n: 1
Logger.Info("n: {n}, 1: {@1}", 1, user); // n: 1, 1: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}
Logger.Info("All named");
Logger.Info("User: {@user}, n: {n}", user, 1); // User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}, n: 1
Logger.Info("n: {n}, User: {@user}", 1, user); // n: 1, User: {"FirstName":"Bill", "LastName":"Gates", "Id":"12345"}
我做错了什么?当然规则不是“如果使用 @
它必须是第一个参数,或者它必须遵循命名参数”。我意识到有关 @
前缀的详细信息在结构化日志记录部分下,但我并不完全理解。我不允许将它与平面文件一起使用吗?
NLog“作弊”并且仅在看到第一个时激活其 message-template-parser
place-holder 使用 message-template-logic(就像使用名字或 @
)。
NLog 在不需要使用 message-template-parser 时回退到标准 string.Format
。这既是为了提高性能,也是为了减少因未按预期使用 string.Format
而导致更改中断的可能性。