具有重复孔名称的 NLog 结构化日志记录
NLog structured logging with duplicate hole names
我正在尝试根据 NLog 中实现的 message templates syntax 来弄清楚捕获具有重复孔名的属性的正确行为是什么。
我们来看一个例子。
记录到控制台,孔名重复但参数个数少于名称个数。
// Targets where to log to: File and Console
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole);
// Apply config
NLog.LogManager.Configuration = config;
NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2);
输出为
2020-05-26 09:47:37.5013|INFO|A|hello from {a} {b} {a}
没有任何替换!
使用相同数量的参数将重复的孔名记录到控制台。
// Targets where to log to: File and Console
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole);
// Apply config
NLog.LogManager.Configuration = config;
NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2, 3);
输出为
2020-05-26 09:49:53.1436|INFO|A|hello from 1 2 3
换人适用。
因此,我希望在第一种情况下看到替换,但没有。 NLog 中关于 message templates syntax 的正确行为吗?
我已经检查了第一种情况下 Serilog 的行为。它进行替换。
根据 NLog 文档,这是正确的行为 - How to use structured logging 状态
The Names of the parameters should be unique
虽然捕获规则在messagetemplates.org不要对参数施加这样的限制:
If any of the property names are non-numeric, then all arguments are
captured by matching left-to-right with holes in the order in which
they appear
NLog 对从左到右的匹配有自己的解释 - 如果属性的数量与参数的数量不匹配,则格式不被视为有效的结构化消息模板(检查 ParseMessageTemplate 方法)。这给了你两个预期的结果
Logger.Info("{User} {Value}", "Bob", 42); // "Bob" 42
Logger.Info("{User} {Value} {User}", "Bob", 42); // invalid template
还有一个出乎意料(但 NLog 已警告您使用唯一属性):
Logger.Info("{User} {Value} {User}", "Bob", 42, "Joe"); // "Bob" 42 "Joe"
如果您希望在最后一个示例中获得 "Joe" 42 "Joe"
,那么您可以使用 Serilog 或在消息模板 "{0} {1} {0}"
中使用数字 属性 名称(不推荐) .
我正在尝试根据 NLog 中实现的 message templates syntax 来弄清楚捕获具有重复孔名的属性的正确行为是什么。
我们来看一个例子。
记录到控制台,孔名重复但参数个数少于名称个数。
// Targets where to log to: File and Console var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole); // Apply config NLog.LogManager.Configuration = config; NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2);
输出为
2020-05-26 09:47:37.5013|INFO|A|hello from {a} {b} {a}
没有任何替换!
使用相同数量的参数将重复的孔名记录到控制台。
// Targets where to log to: File and Console var logconsole = new NLog.Targets.ConsoleTarget("logconsole"); config.AddRule(global::NLog.LogLevel.Debug, global::NLog.LogLevel.Fatal, logconsole); // Apply config NLog.LogManager.Configuration = config; NLog.LogManager.GetLogger("A").Info("hello from {a} {b} {a}", 1, 2, 3);
输出为
2020-05-26 09:49:53.1436|INFO|A|hello from 1 2 3
换人适用。
因此,我希望在第一种情况下看到替换,但没有。 NLog 中关于 message templates syntax 的正确行为吗?
我已经检查了第一种情况下 Serilog 的行为。它进行替换。
根据 NLog 文档,这是正确的行为 - How to use structured logging 状态
The Names of the parameters should be unique
虽然捕获规则在messagetemplates.org不要对参数施加这样的限制:
If any of the property names are non-numeric, then all arguments are captured by matching left-to-right with holes in the order in which they appear
NLog 对从左到右的匹配有自己的解释 - 如果属性的数量与参数的数量不匹配,则格式不被视为有效的结构化消息模板(检查 ParseMessageTemplate 方法)。这给了你两个预期的结果
Logger.Info("{User} {Value}", "Bob", 42); // "Bob" 42
Logger.Info("{User} {Value} {User}", "Bob", 42); // invalid template
还有一个出乎意料(但 NLog 已警告您使用唯一属性):
Logger.Info("{User} {Value} {User}", "Bob", 42, "Joe"); // "Bob" 42 "Joe"
如果您希望在最后一个示例中获得 "Joe" 42 "Joe"
,那么您可以使用 Serilog 或在消息模板 "{0} {1} {0}"
中使用数字 属性 名称(不推荐) .