Search code examples
c#serilog

How can I see the MessageTemplate when using Serilog WriteTo.Console?


I'm using Serilog for logging and am using the Console writer to send logs to standard output to be picked up by Filebeat and sent to Elastic. The configuration of the logger includes the following:

.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{Properties:j}{NewLine}{Exception}")

This is all fine, the structured properties are output and rendered in JSON format correctly, however, it's missing the MessageTemplate property value which would output something similar to:

"MessageTemplate":"User {Username} logged in successfully"

This is a problem because it would be useful to be able to run queries in Kibana to show the number of times users are logging in by searching for the message template rather than the rendered message which would be specific to a single user, for example:

"Message":"User "Joe Bloggs" logged in successfully"

I can see that I can use the JsonFormatter object to write to the console using:

.WriteTo.Console(new JsonFormatter(renderMessage: true))

Using this method outputs both the Message and the MessageTemplate properties, but it does so in an ugly blob of JSON which is really hard to read when a person is viewing the logs on the command line.

Does anyone know if it's possible for the Serilog Console Output template to include the MessageTemplate?


Solution

  • Serilog.Expressions can do this.

    dotnet add package Serilog.Expressions
    

    then:

      .WriteTo.Console(new ExpressionTemplate(
        "[{@t:HH:mm:ss} {@l:u3}] {@m} { {..@p, MessageTemplate: @mt} }\n{@x}"))