【问题标题】:Serilog only logs first element of arraySerilog 只记录数组的第一个元素
【发布时间】:2021-02-22 14:21:01
【问题描述】:

我正在使用 Serilog 2.10.0 登录 .NET 5 上的 ASP.NET Core 应用程序。在尝试记录只有一个参数且此参数是数组的事件时遇到问题.以下是一些示例代码和带有 JSON 文件接收器的日志输出:

var myArray = new string[] { "foo", "bar" };
logger.LogInformation("Log stuff: {@MyArray}", myArray);
{"@t":"2021-02-22T14:09:46.8673482Z","@mt":"Log stuff: {@MyArray}","MyArray":"foo","SourceContext":"MyNamespace.MyClass"}

logger 是通过依赖注入注入的 ILogger。记录的事件仅包含我的字符串数组的第一个元素。如果我添加另一个参数,则会正确记录字符串数组。我尝试了使用和不使用@ 以及不同的接收器。

这是一个带有附加参数的修改示例,它可以按我的预期工作:

var myArray = new string[] { "foo", "bar" };
logger.LogInformation("Log stuff: {baz} {@MyArray}", "baz", myArray);
{"@t":"2021-02-22T14:19:21.3580354Z","@mt":"Log stuff: {baz} {@MyArray}","baz":"baz","MyArray":["foo","bar"],"SourceContext":"MyNamespace.MyClass"}

我怀疑我在这里误解了可变参数函数如何确定模板字符串中参数和变量之间的映射。但是我想不出在不添加不相关的附加参数的情况下让它正常工作的方法。

如何让 Serilog 正确处理以单个数组为参数的日志消息?

【问题讨论】:

  • 不确定Serilog.Log.Information 是否存在同样的问题?如果您直接针对该问题工作,我怀疑它会被github.com/Suchiman/SerilogAnalyzer 标记
  • @RubenBartelink:我认为现在最好的做法是注入ILogger,但我也经历过在整个代码中都依赖于 Serilog 的项目。 BR
  • Serilog 的记录器试图避免这种情况 - github.com/serilog/serilog/blob/dev/src/Serilog/Core/… - 但从 MEL 传递事件时无法检测到这种情况。

标签: c# asp.net-core serilog microsoft-extensions-logging


【解决方案1】:

我能够重现您的问题。 Resharper 已标记问题,如下面的屏幕截图所示。

如果我们输入 LoggerExtensions#LogInformation 的来源,它具有以下签名:

public static void LogInformation(this ILogger logger, string message, params object[] args)

最后一个参数是params object[] args,当传入单个数组时,该方法认为该数组是参数列表并将数组强制转换为object[],而您的意图是将数组作为参数传入.这可以通过像这样更改模板来确认:

_logger.LogInformation("Log stuff: {FirstElement} {SecondElement}", myArray); 

这将输出Log stuff: foo bar。上面的代码具有与此相同的逻辑和行为:

_logger.LogInformation("Log stuff: {FirstElement} {SecondElement}", "foo", "bar");

将数组更改为例如一个列表,或者正如@IharYakimush 所建议的,只需将数组转换为object,就可以解决问题,因为该集合现在将被视为一个参数,而不是参数列表。

_logger.LogInformation("Log stuff: {MyArray}", (object)myArray);

【讨论】:

  • 不需要执行不必要的列表创建。使用以下方法:_logger.LogInformation("Log stuff: {MyArray}", (object)myArray);
  • @IharYakimush:谢谢,用你的建议改写了我的回答。 BR
【解决方案2】:

也许您可以将日志语句更改为类似

logger.LogInformation("Log stuff: {baz} {myArrayString}", "baz",  String.Join(", ", myArray));

【讨论】:

    猜你喜欢
    • 2020-04-07
    • 2011-07-12
    • 2019-03-26
    • 1970-01-01
    • 2013-06-16
    • 2019-09-12
    • 2014-01-02
    • 2021-09-14
    相关资源
    最近更新 更多