Serilog 只记录数组的第一个元素

Serilog only logs first element of array

我正在使用 Serilog 2.10.0 登录 .NET 5 上的 ASP.NET 核心应用程序。我 运行 在尝试记录只有一个参数,这个参数是一个数组。以下是一些示例代码和带有 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 正确处理以单个数组作为参数的日志消息?

我能够重现您的问题。 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: {baz} {myArrayString}", "baz",  String.Join(", ", myArray));