如何在Serilog中手动渲染模板及其参数?

时间:2014-11-11 22:30:46

标签: .net serilog

如何实施以下方法?

string BuildSerilogMessage(string messageTemplate, params object[] propertyValues);

参数与ILogger.Debug等接受的参数相同。

我想要这个的原因是因为我想在中间异常中保留模板/值,这也需要单个字符串Message。它基本上是这样的:

// this exception is designed to be easily loggable by serilog
[Serializable]
public class StructuredException : Exception {
    public string MessageTemplate { get; private set; }
    public object[] PropertyValues { get; private set; }

    public StructuredException(string messageTemplate, params object[] propertyValues)
        : base(BuildMessage(messageTemplate, propertyValues))
    {
        MessageTemplate = messageTemplate;
        PropertyValues = propertyValues;
    }

    public StructuredException(Exception inner, string messageTemplate, params object[] propertyValues)
        : base(BuildMessage(messageTemplate, propertyValues), inner)
    {
        MessageTemplate = messageTemplate;
        PropertyValues = propertyValues;
    }

    private static string BuildMessage(string messageTemplate, object[] propertyValues) {
        // ???
    }
}

1 个答案:

答案 0 :(得分:4)

这样做an example in the Akka.NET repo,但参数中只支持标量值。

基本概念是使用MessageTemplateParser来获取模板:

var parser = new MessageTemplateParser();
var template = parser.Parse(messageTemplate);

然后使用参数从模板中压缩标记:

var properties = template.Tokens
    .OfType<PropertyToken>()
    .Zip(propertyValues, Tuple.Create)
    .ToDictionary(
        p => p.Item1.PropertyName,
        p => new ScalarValue(p.Item2));

最后呈现:

var rendered = template.Render(properties);

(事先为这里可能无法编译的位道歉。)