MitchBodmer / serilog-sinks-testcorrelator

A Serilog sink that correlates log events with the code that produced them, enabling unit testing of log output.
MIT License
85 stars 9 forks source link

String parameters rendered with quotes #69

Closed elimarkov closed 1 year ago

elimarkov commented 1 year ago
void Main()
{
    Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.TestCorrelator()
    .CreateLogger();

    using (TestCorrelator.CreateContext())
    {
        Log.Information("My log message {Text}!", "my text");

        TestCorrelator.GetLogEventsFromCurrentContext()
        .Select(e => e.RenderMessage())
        .ToList()
        .ForEach(m => Console.WriteLine("From TestCorrelator: " + m));
    }
}

the output is: [12:31:33 INF] My log message my text! From TestCorrelator: My log message "my text"!

How do I resolve this?

MitchBodmer commented 1 year ago

This is the expected behavior for Serilog. Please refer to their documentation on how to prevent this.

(Serilog renders string values in double quotes to more transparently indicate the underlying data type, and to make the property value stand out from the surrounding message text.)

elimarkov commented 1 year ago

As you can see from the sample code the Console Sink is not writing with double quotes. I have added a File Sink (.WriteTo.File(@"c:\temp\test_log.txt")) and it also outputs a message without double quotes. Here is the output:

2023-04-11 15:00:33.449 +01:00 [INF] My log message my text!

It looks like that TestCorrelator is the only one that adds the double quotes by default. The default outputTemplate in Console and File sinks uses {Message:lj}. Also, I don't see a way to pass outputTemplate to the TestCorrelator.

MitchBodmer commented 1 year ago

As I said, the TestCorrelator doesn't add quotes, Serilog does by default when it renders a message. The TestCorrelator doesn't have an outputTemplate because it does not render LogEvents. It simply captures the LogEvents emitted to it and stores them in a way that allows you to access them easily later.

When you call e.RenderMessage() with no arguments you are telling Serilog to return a string rendered representation of the LogEvent in the default way, which has quotes around string values.

If you need to render the log message a different way, you can find documentation on how to accomplish that in the Serilog wiki. If you need to test that your log events will render in a particular way for a particular sink, the TestCorrelator cannot help you. Sinks handle their own output formatting and the TestCorrelator does not know what showed up on your console or in your file.

The point of the TestCorrelator is to allow you to see that the LogEvents you expected were emitted by the logger to its sinks, not to verify what happened to those LogEvents after they were emitted.