In DDD, where's the right or recomendable place to call the logging service?

Viewed 94

I am working on a C#/.NET project. In order to respect the DDD architecture, where it could be the right or recomendable place to call the logging service (placed at the infrastructure layer, with database persistence)? I mean, should I call the logger in each component at the time the event occurs or should I propagate the messages(for example through OperationResult struct) upward to the application services layer so that instead it is this layer that calls the logging system? or what other way do you recommend and why? It would be recommendable to trigger an event (linked to the logging system) inside each component every time there is needed to logging something (error, warning or information)?

Thank you!

2 Answers

DDD is not an architecture pattern, it only states that you should model your domain, and that all the model, and only the model, should go in a specific domain unit : package, assembly, namespace, ... DDD can be used with any pattern, such as layered, bus, hexagonal, ... Based on DDD alone, the only answer is that logging code should go anywhere but in the domain unit.

In a classic layered application architecture, you usually have 4 layers:

  • persistence, allows application to store/restore data across time
  • business, enforces business rules integrity for state changing operations
  • presentation, responsible for communication with clients (DTO, MVC, ...)
  • application, transverse features specific to the application

Logging usually goes in the application layer, along with authentication or application hosting for instance. Also, some applications use a 3-layered architecture, in which case application and presentation layers are usually merged.

Also note that there are two interpretations of layered architecture, some say you can only reference neighbor layers ; another one states that you can only reference in a given direction, with layer "hopping" allowed.

Since application layer features are usually cross cutting concerns, it is normal to be able to access features from that layer from any other layer. I suggest against using events since this feature is usually very slow, you can call the logging service directly. If you really care about separation of concern, have a public interface referable from anywhere and use dependency injection to inject protected implementations.

I think this is not a programming decision, it depends on what kind of logs do you need and what for. Logging is a security decision, maybe sometimes a business decision too.

As of DDD afaik. it should be an infrastructure service. It is a typical problem, that usually you log everything everywhere, so it can be a global variable, class with static method, etc. so you don't need to inject it, though if it is more targeted like I mentioned above, that you decide what to log consciously, then it is better to inject it and maybe have a configuration where you can set what to log. I think it should be something async with a queue, so it won't block normal operation.

Related