Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET 5 Best practice to log exceptions in layers

I have a project using ASP.NET 5 and MVC 6. I have several layers :

  • My presentation layer
  • My domain model layer
  • My infrastructure layer
  • My business logic layer
  • And my data access layers.

For the moment, I log exceptions in my controllers methods using Dependency Injection.

private readonly ILogger<CustomerController> _logger;
public CustomerController(ILogger<CustomerController> logger)
{
     _logger = logger;
}

public bool TestLog()
{
     _logger.LogError((int)LoggingEvents.LIST_ITEMS, "Test info #543434");
     return true;
}

What is the best practice to use the logger in my others layers, like my data access layer ?

like image 991
AdrienTorris Avatar asked Jan 02 '26 05:01

AdrienTorris


2 Answers

Best is to use ILogger<T> only in your application layer (Controllers, application services - but not domain services).

If you want to add logging around your domain services/repositories, it'd be best to create decorators for it. This only works well if you have abstracted your interfaces from their implementations and use/inject interfaces everywhere).

However, there are limitations on what you can do with decorators. You can log before and after the call to a method defined in the public interface. Not inside the call.

Why avoid logging/injecting your logger into the service?

Coupling

You should avoid injecting ILogger<T> in your domain objects, as this couples your domain to ASP.NET Core logging framework/base classes. However, you can always define your own logger interface to use it within your domain and implement it as wrapper around ILogger<T>.

SOLID Principle

S in SOLID principle stand for SRP (Single Responsibility Principle) and says, one object should just have one and only one responsibility. Doing logging and persistence or businesses logic into one object violates this principle.

But in the end, you got to weight up costs of development with the benefits you gain with it. If it's a long living application (to be used for the next 10 years or so) and a complex one, logging as decorators makes sense for sure. If it's a small project with only a few weeks of development time, the benefit of this abstraction may not outweigh the costs.

like image 85
Tseng Avatar answered Jan 04 '26 07:01

Tseng


The “best practice” would be to just inject own loggers for every component and let every component do its own logging.

If you think this becomes too noisy for your application, then you can change the verbosity level for namespace parts, so you only get e.g. Information level logs for your controllers, and Warning (or worse) for everything else:

loggerFactory.AddConsole(new ConsoleLoggerSettings()
{
    Switches = new Dictionary<string, LogLevel>()
    {
        ["MyNamespace.Services"] = LogLevel.Warning,
        ["MyNamsepace.Controllers"] = LogLevel.Information
    }
});
like image 38
poke Avatar answered Jan 04 '26 06:01

poke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!