tsimbalar
tsimbalar

Reputation: 6000

How can I add a named property that is not part of the message template?

In some cases, I would like to add contextual information to a message (for instance currently authenticated user), without having to include it in the message template.

I would like to accomplish this :

logger.Information("Doing stuff {Foo} with the thing {Bar}. {User}", foo, bar, user)

but without the {User} in the template.

I already know about LogContext but that seems overkill when adding contextual information to just one event.

I also know I can use the low-level API logger.Write(LogEvent evnt) to actually control which properties are included, but that seems like a bit too much code for what I am trying to accomplish.

I'm pretty sure there is a short and elegant way that is super obvious, but I haven't found it :)

UPDATE :

I found out only afterwards that this question is more or less similar : Add custom properties to Serilog

Upvotes: 16

Views: 8345

Answers (2)

Josh
Josh

Reputation: 3622

If you're using the generic Microsoft ILogger you can use BeginScope;

using (_logger.BeginScope(new Dictionary<string, object> { { "LogEventType", logEventType }, { "UserName",  userName } }))
{
    _logger.LogInformation(message, args);
}

This is discussed here; https://blog.rsuter.com/logging-with-ilogger-recommendations-and-best-practices/

Upvotes: 17

tsimbalar
tsimbalar

Reputation: 6000

I could figure it out on my own!

You can use the fluent method .ForContext(propertyName, propertyValue) on a single call to one of the .LogXXX() methods.

For instance :

logger.ForContext("User", user)
      .Information("Doing stuff {Foo} with the thing {Bar}", foo, bar)

The property added to the event only apply to the event, and they are no longer present on the next call to the logger.LogXXX() method

UPDATE

The article by Nicholas Blumhardt explains it quite well : Context and correlation – structured logging concepts in .NET (5)

Upvotes: 13

Related Questions