How do I render a template and its arguments manually in Serilog?

1.5k Views Asked by At

How do I implement the following method?

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

The arguments are the same as the ones accepted by ILogger.Debug etc.

The reason why I want this is because I want to preserve template/values in an intermediate exception which needs to have single string Message as well. It is basically something like this:

// 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

There are 1 best solutions below

1
On

There's an example in the Akka.NET repo of this being done, though only scalar values are supported in the arguments.

The basic notion is to use MessageTemplateParser to get the template:

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

Then zip the tokens from the template up with the arguments:

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

Finally rendering:

var rendered = template.Render(properties);

(Apologies in advance for the bits that may not compile here.)