Serilog:如何在 enricher 中记录对象?

Serilog: How to log object in enricher?

我们使用 Serilog 生成 json 日志(即每个日志条目都是 json,而不是文本)。好处是它们可以包含对象。例如,我使用它来记录 C# 异常对象,如下所示:

ILogger.Error("Something bad happened. {@exception}", exception);

这会将 exception 对象的所有属性发送到日志中。 (此处变量exception的类型为Exception。)

现在我很困惑为什么没有简单的类比如何在 enricher 中做到这一点。目前,我们添加异常以这种方式登录enricher:

LogEvent.AddPropertyIfAbsent(new LogEventProperty("exception", new ScalarValue(exception));

当然, ScalarValue 将异常转换为字符串。它看起来像双引号内的 json 对象("stringified json")。

现在,问题是当我们将其放入 ELK(一种用于监视日志并让我们在其中进行搜索的软件)时,它会抱怨 exception 字段具有不同的类型并表示它应该像以前一样是对象,而不是字符串。 (这是另一个话题 - 我发现很多重复的问题如何在 ELK 中 "solve" 它。但显然,它不能在 ELK 中 "fixed" ,它应该始终以相同的格式生成。所以这就是为什么我问这个问题。)

我在 Serilog 中看不到 ScalarValue 的任何基于对象的类比。 AddPropertyIfAbsent不直接接受对象,它要LogEventPropertyLogEventPropertyValue。这个抽象 class 有一些实现,包括简单值、数组和字典,但其中 none 似乎以与 @exception 相同的方式发出对象。所以我想知道这个非常常见和基本的场景是否没有被 Serilog 涵盖,或者我只是盲目?

您的扩充器接受 ILogEventPropertyFactory。你可以做到

logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("User", userDetails, 
                                                            destructureObjects: true));

这将用自定义对象丰富它。