Reputation: 780
How do I use the ForContext
method for a Serilog logger using the ILogger
interface from Microsoft.Extensions.Logging
?
Here's the code:
private readonly ILogger<UserService> _logger;
//DI code here
....
//inside some method
_logger.ForContext("CorrelationId", correlationId); // Ilogger doesn't contain ForContext extension method
_logger.LogInformation("message");
I don't really want to use the ILogger
interface from the Serilog as I don't want it to be Serilog-specific and it's not generic.
Upvotes: 10
Views: 5684
Reputation: 1549
ForContext
with Microsoft.Extensions.Logging
The Microsoft ILogger
interface does not have the ForContext
property, however, according to several readings I could find on the topic, the proper way to pass additional context information via this interface is to use its BeginScope
method to pass a dictionary of values and then call your Logging method.
using (logger.BeginScope(new Dictionary<string, object>{ { "ParameterName", 999 } }))
{
logger.LogInformation(
"This log entry and any other ones wrapped within this using statement will" +
"have context added similar to .ForContext with Serilog");
}
ILogger
I found myself preferring to write an extension method for this purpose to avoid having using
statements everywhere and make the intention more clear in my code when I want to add context information to my structured logging:
public static void LogWithContext(this ILogger logger, Action LogAction,
params KeyValuePair<string, object>[] contextDataParam)
{
Dictionary<string, object> contextData = new Dictionary<string, object>();
foreach (KeyValuePair<string,object> kvp in contextDataParam)
{
contextData.TryAdd(kvp.Key, kvp.Value);
}
using (logger.BeginScope(contextData))
{
LogAction.Invoke();
};
}
And this can be called like this:
logger.LogWithContext(
() => logger.LogError("Error with {Database}", _options.database),
new KeyValuePair<string, object>("CallingFunction", nameof(thisFunction)),
new KeyValuePair<string, object>("UserErrorType", "DB"))
Upvotes: 12