如果您愿意更改对象的ToString() 表示,@flaxel's answer 效果很好。如果您已经覆盖 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);
这种方法的另一个优点是,如果您想更改表示该类型对象的方式,或者如果您想恢复到默认的解构方法,您只需更改配置记录器时使用的策略(即上面sn-p中的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>()
// ...