Serilog - ForContext 将字典值视为复杂对象

Serilog - ForContext treat dictionary value as complex object

我正在尝试通过执行以下操作来记录传递给控制器​​的模型:

        _log
            .ForContext("Id", "XXXXXX-XXXX-XXXX-XXXXXXXXX")
            .ForContext("Email", email)
            .ForContext("UserId", userId)
            .ForContext("Parameters", parameters)
            .ForContext("Errors", errors.ToArray())
            .ForContext("ActionArguments", actionArguments)
            .Information(message);

其中 actionArguments 的类型为 IDictionary<string, object> actionArguments。这被解释为

{
   someProperty: "Some.Namespace.Dtos.Something.MyTypeDto"
}

我真的希望 someProperty 能够扩展到复杂类型所代表的内容。可能吗?怎么做?

默认情况下,Serilog 将通过调用 ToString() 来序列化具有它不理解的类型(包括您自己的自定义类型)的对象以获得简单的表示。 ToString() 对象的默认实现只是 returns 类型的全名,这就是 DTO 的类型名称显示在日志上下文中的原因。

您所追求的在 Serilog 中称为 'destructuring'。在documentation中,这定义为:

Destructuring is the process of taking a complex .NET object and converting it into a structure, which may later be represented as say, a JSON object or XML blob

有一个可选参数 destructureObjects,您可以将其提供给 ILogger.ForContext 方法,告诉 Serilog 尝试从对象中提取附加信息:

    .ForContext("ActionArguments", actionArguments, destructureObjects: true)

默认情况下,它将使用反射递归地解构,有效地遍历对象的所有属性和这些属性的任何属性,等等,直到找到它知道如何格式化的类型。

请注意不要使用此方法记录任何敏感信息; Serilog 将尽最大努力包含它找到的每个值。