1

I am using the implementation suggested here for adding log4net to current dot net core project, https://thecodebuzz.com/log4net-file-logging-console-logging-asp-net-core/ (this is using Microsoft.Extensions.Logging.Log4Net.AspNetCore), how can log4net be set up to log all unhandled exceptions? I haven't figured out a way to do this. Any pointers please?

Later edit:

public class LogFilter : ExceptionFilterAttribute
{
    public readonly ILogger _logger;

    public LogFilter(ILogger logger)
    {
        _logger = logger;
    }

    // public Logger Logger { get; set; }
    public override void OnException(ExceptionContext Context)
    {
        //Log what you need here, the exception is in Context.Exception
        _logger.LogError(Context.Exception, null);

        Context.ExceptionHandled = true;
    }
}

I tried adding a LogFilter class like this, coupled with this change in Startup.cs:

services.AddMvc(o =>
{
    o.Filters.Add(new LogFilter(Logger));
});

in the ConfigureServices method as well as the public ILogger Logger { get; } property, but the error I get is about _logger being null in my LogFilter class.

Later update (side note):

In a controller, I can get _logger to work by adding a property: private readonly ILogger _logger; and passing it in the constructor: ILogger<MyController> logger but in the FilterClass following the same approach with ILogger<ControllerBase> logger in the constructor doesn't work. Error is the same as mentioned above.

Sami
  • 393
  • 8
  • 22
  • Does this answer your question? [log4net log all unhandled application errors](https://stackoverflow.com/questions/1367967/log4net-log-all-unhandled-application-errors) – Gusman Jun 11 '20 at 00:06
  • Thanks but doesn't seem to work the same in Dot net Core compared to the .net framework, we don't have Application_Error error in dot net core. I'm thinking about it... – Sami Jun 11 '20 at 00:09
  • Have you tried to debug the filter to check if it's executed? – Gusman Jun 11 '20 at 00:42
  • You are right. It's not executed. But this is returned to my page in the UI: `{ type: "https://tools.ietf.org/html/rfc7231#section-6.5.4", title: "Not Found", status: 404, traceId: "|a704a3ee-4d17438a72465c63." }` showing we did have an error... I think I know why, checking and will update. – Sami Jun 11 '20 at 00:45
  • a 404 response is not an unhandled exception, is a status code page, that doesn't raises an exception. Check this answer: https://stackoverflow.com/questions/56731883/asp-net-core-web-app-log-404-requests-as-warning – Gusman Jun 11 '20 at 00:48
  • Yes, it was because of that, I forced the code to throw an exception if no item is returned, and now I get System.ArgumentNullException: 'Value cannot be null. (Parameter 'logger')' in the Filter class that I added. It's because I am using an ILogger type.. but if I use a Logger type, it doesn't find it in the Microsoft.Extensions.Logging.Log4Net.AspNetCore namespace. Thinking about it. Maybe I can register ILogger, Logger in the startup. – Sami Jun 11 '20 at 00:53
  • Try `LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);` in the constructor of the filter instead of passing the instance to it as it may not have been instantiated at the time you call it. – Gusman Jun 11 '20 at 01:01
  • How amazing and how beautiful! This worked. Thank you so much! – Sami Jun 11 '20 at 01:08

1 Answers1

1

To log any unhandled exception in .net Core you must create an exception filter, something like this:

public class LogFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext Context)
    {
        //Log what you need here, the exception is in Context.Exception

        Context.ExceptionHandled = true;
    }
}

And register the filter:

public void ConfigureServices(IServiceCollection Services)
{
    // Add framework services.
    Services.AddMvc(o =>
    {
        o.Filters.Add(new LogFilter());
    });
}
Gusman
  • 14,905
  • 2
  • 34
  • 50
  • Thank you! I tried logging by doing _logger.LogError(Context.Exception, null); not sure what I am doing wrong. _logger is a variable of type ILogger where that is imported from Microsoft.Extensions.Logging, – Sami Jun 11 '20 at 00:32
  • Also this approach needed to pass ` services.AddMvc(o => { o.Filters.Add(new LogFilter(Logger)); }); ` (the Logger in Startup.cs, also defined as: `public ILogger Logger { get; }` in the same class). Am I overcomplicating it? – Sami Jun 11 '20 at 00:33
  • @Sami Don't add a class as a comment, it's unreadable. If you want to clarify something add an edit on your question. Also, you tell that you have tried logging but aren't telling if you had a problem or not and what problem in the case it happened. – Gusman Jun 11 '20 at 00:33