Closed Andreas-Hjortland closed 6 years ago
Could you achieve this by decorating the existing logger?
public class LogCountLoggerDecorator : ILogger
{
private readonly ILogger _logger;
private readonly LogCounter _logCounter;
public LogCountLoggerDecorator(ILogger logger, LogCounter logCounter)
{
_logger = logger;
_logCounter = logCounter;
}
public void Log<TState>(
LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
_logCounter.Increment();
using (_logger.BeginScope(("count", _logCounter.Count)))
{
_logger.Log(logLevel, eventId, state, exception, formatter);
}
}
public bool IsEnabled(LogLevel logLevel)
{
return _logger.IsEnabled(logLevel);
}
public IDisposable BeginScope<TState>(TState state)
{
return _logger.BeginScope(state);
}
}
LogCounter
would be a singleton that you could inject where needed. There would be a bit of plumbing required to replace the GelfLogger
, but essentially you would need to replace the registration here.
I think that would work... I guess I have to create my own logger provider which then calls back to the GelfLoggerProvider
like this:
public class CountingGelfLoggerProvider : ILoggerProvider
{
private readonly GelfLoggerProvider _innerProvider;
private readonly LogCounter _counter;
public CountingGelfLoggerProvider(IOptions<GelfLoggerOptions> options)
{
_innerProvider = new GelfLoggerProvider(options);
_counter = new LogCounter();
}
public ILogger CreateLogger(string name)
{
var gelflogger = _innerProvider.CreateLogger(name);
return new LogCountLoggerDecorator(gelflogger, _counter);
}
public void Dispose()
{
_innerProvider.Dispose();
}
}
Then I could use builder.Services.AddSingleton<ILoggerProvider, CountingGelfLoggerProvider>();
in ConfigureServices
instead of builder.AddGelf()
Yep I think that should do it. Bear in mind that Increment()
above may be called from different threads so you probably want to use Interlocked.Increment()
.
Yup. Thank you for the help :-)
We have an issue where we want to have a global counter for each log statement so that we can ensure that the logs are displayed in the correct order (the millisecond resolution of graylog is not granular enough for us) and I wondered if it is possible to support a Func callback in the AdditionalField dictionary which is executed every time we log something.
I am thinking we could support something like this
Where the gelf output would be: something like
Could this be in scope for this project? I can create a pull request if you think this should be supported