LogStash -> Elasti-6ren">
gpt4 book ai didi

serilog - 如何在 Serilog 中将对象序列化为字符串?

转载 作者:行者123 更新时间:2023-12-02 16:31:45 40 4
gpt4 key购买 nike

我有很多这样的日志:

Log.Information("Submitting order {@order}", order);

此日志通过 RabbitMq -> LogStash -> Elastic 并最终生成大量字段(我假设每个属性一个字段)。最终我在 Elastic 中有成千上万个字段,这带来了各种各样的问题。

如果我将整个对象指定为参数,这通常意味着我不太关心它的所有字段是否都被解析,如果它被存储为单个字符串对象(但仍然序列化为JSON)。有没有办法在 Serilog 中自定义它?

最佳答案

@flaxel's answer如果您乐于更改对象的 ToString() 表示,则效果很好。如果您已经重写了 ToString() 或者您不希望它返回 JSON 字符串,请考虑以下选项之一。


如果您不想一直将类型记录为 JSON ,请考虑在记录消息时只序列化对象。这是最明确的方法,允许您挑选哪些消息具有序列化形式,哪些消息具有解构形式,但它可能会使您的日志语句非常冗长:

// Using Newtonsoft.Json to serialize.
Log.Information("Submitting order {Order}", JsonConvert.SerializeObject(order));

如果您总是想要将一个类型序列化为 JSON,您可以为该特定类型注册一个解构策略。这使您的日志语句简洁明了,并确保类型始终以相同的方式序列化:

// When configuring your logger.
Log.Logger = new LoggerConfiguration()
.Destructure.ByTransforming<Order>(order => JsonConvert.SerializeObject(order))
// ...

// This will use the destructurer registered above, so will convert to a JSON string.
Log.Information("Submitting order {@Order}", order);

// These will still use the ToString() method.
Log.Information("Submitting order {Order}", order);
Log.Information("Submitting order {$Order}", order);

这种方法的另一个优点是,如果你想改变你代表那种类型的对象的方式,或者如果你想恢复到默认的解构方法,你只需要改变配置记录器时使用的策略(即上面代码片段中的 lambda)。

如果您的序列化方法太复杂而无法放入 lambda 中,或者您想对大量类型使用相同的序列化方法,您可以定义自己的 IDestructuringPolicy 然后将其注册到类似的方式:

class SerializationPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
// Check type of `value` and serialize if required.
}
}

// When configuring your logger.
Log.Logger = new LoggerConfiguration()
.Destructure.With<SerializationPolicy>()
// ...

关于serilog - 如何在 Serilog 中将对象序列化为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63379034/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com