In my project I often add prefixes to my log messages.
Currently I am doing this with
logger.LogDebug(prefix + " some message");
I thought it would be a good way to implement a custom logger where I set the prefix and the logger itself attaches it every time it logs something.
So I created my custom logger class and implemented the ILogger interface. But I do not understand how to use the
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
method to add the prefix (which is a member of the custom logger class).
My full code is:
public class CustomLogger : ILogger
{
private readonly ILogger _logger;
private string _logPrefix;
public CustomLogger(ILogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_logPrefix = null;
}
public ILogger SetLogPrefix(string logPrefix)
{
_logPrefix = logPrefix;
return this;
}
public IDisposable BeginScope<TState>(TState state)
{
return _logger.BeginScope(state);
}
public bool IsEnabled(LogLevel logLevel)
{
return _logger.IsEnabled(logLevel);
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
_logger.Log(logLevel, eventId, state, exception, formatter);
}
}
I think you should not call a _logger in a custom logger.
It would be a circular call on runtime and the result would be "prefix: prefix: prefix: prefix: prefix: prefix: prefix: prefix: ..."
Simply, you can create a simple logger and implement a log writter such as Console, database writter, log4net, ...
Now first, you should change your custom logger like below:
public class CustomLogger : ILogger
{
private readonly string CategoryName;
private readonly string _logPrefix;
public CustomLogger(string categoryName, string logPrefix)
{
CategoryName = categoryName;
_logPrefix = logPrefix;
}
public IDisposable BeginScope<TState>(TState state)
{
return new NoopDisposable();
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
string message = _logPrefix;
if (formatter != null)
{
message += formatter(state, exception);
}
// Implement log writter as you want. I am using Console
Console.WriteLine($"{logLevel.ToString()} - {eventId.Id} - {CategoryName} - {message}");
}
private class NoopDisposable : IDisposable
{
public void Dispose()
{
}
}
}
The second step, create a logger provider:
public class LoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new CustomLogger(categoryName, "This is prefix: ");
}
public void Dispose()
{
}
}
The third step, in Configure from Startup.cs:
loggerFactory.AddProvider(new MicroserviceLoggerProvider());