huorswords / Microsoft.Extensions.Logging.Log4Net.AspNetCore

Allows to configure Log4net as Microsoft Extensions Logging handler on any ASP.NET Core application. Original code proposal by @anuraj --> https://dotnetthoughts.net/how-to-use-log4net-with-aspnetcore-for-logging/
Apache License 2.0
249 stars 123 forks source link

Logging latest scope value #141

Open andreycha opened 8 months ago

andreycha commented 8 months ago

Hi,

Currently, the library preserves log4net behavior when it comes to having same property with different values in the log scopes. Values are concatenated with space.

using (_logger.BeginScope(("Prop", 123_)))
{
    _logger.LogInformation("Log 1"); // has "123" in the log property

    using (_logger.BeginScope(("Prop", 456)))
    {
        _logger.LogInformation("Log 2"); // has "123 456" in the log property

        using (_logger.BeginScope(("Prop", 789)))
        {
            _logger.LogInformation("Log 3"); // has "123 456 789" in the log property
        }
    }
}

However, when using Serilog as ILogger implementation, it always adds the latest value to the log properties:

using (_logger.BeginScope(("Prop", 123_)))
{
    _logger.LogInformation("Log 1"); // has "123" in the log property

    using (_logger.BeginScope(("Prop", 456)))
    {
        _logger.LogInformation("Log 2"); // has "456" in the log property

        using (_logger.BeginScope(("Prop", 789)))
        {
            _logger.LogInformation("Log 3"); // has "789" in the log property
        }
    }
}

This behavior better suits our case. We have code paths spread across applications and a shared library where same property might be added multiple times in the library and in the apps. All code uses ILogger abstraction, but different services use different logging frameworks (log4net and Serilog). We'd like to have a consistent behavior in this case. We can plug in custom implementation of ILog4NetLoggingEventFactory but would really like to avoid taking care and maintaining any extra code.

Would it make sense to have a setting which controls whether all values or latest value is written to the logs? Something like:

loggerFactory.AddLog4Net(new Log4NetProviderOptions {
    UseLatestScopeValue = true
});

If this is sensible, I can take care of the PR once we agree on the design and naming.

Thank you!