1

I have a Visual Studio solution with 4 projects, that closely follows the Nop-commerce structure. The following is the structure of my solution.

- Core
- Data
- Services
- Web

The Web project is an asp.net mvc application. Now I want to add server-side logging to my solution, using log4net. My question is which project is best candidate to have the reference of log4net in it, and why? As far as I have studied, logger should be in my Web project. But what if I wanted to log from one of the other three projects?

3

You will need to have a reference to your logging library (e.g. log4net) in all projects that contain any code that wants to log. In a lot of cases that will mean nearly all your projects have a reference to your logging library.

In addition you will likely need a reference in your "entry point" project (e.g. your web app) so that you can configure log sinks etc...

You could introduce abstractions to avoid referencing your logging library everywhere, e.g. raise events instead of logging, or introduce a logging interface in your Core project. In some cases this can be worth it (e.g. an open source project where users will likely have different logging libraries), however in most projects this is a bad idea and just adds complexity for little real-world gain.

  • I am trying to do what you said in the last paragraph - introduce abstractions. That looks cleaner. In that case, where should I actually add reference of the log4net dll? In the core project? If I add the dll reference in core project, where do I add the configurations? I am a little lost here :-( – Sнаđошƒаӽ May 22 '17 at 11:59
  • 1
    @Sнаđошƒаӽ In that case your core project would contain some abstract logging interface, e.g. ILogger, and elsewhere you would implement that e.g. in a Log4NetLogger class - the assembly that contains this class needs to reference log4net. This class could live in any project accessible by your "entry point", e.g. Web, Services, Core or a completely new assembly. – Justin May 22 '17 at 12:03
  • That's exactly what I was thinking of. I just wasn't quite sure if doing that is good idea. Thanks a lot. – Sнаđошƒаӽ May 22 '17 at 12:06
1

Normally, it would go to one of your core projects (having no dependency on other projects). So that it can be used from all of the solution.

The configuration required for Log4net is saved in the web.config, but the logger class can be in any other project.

[update - to answer questions in the comment - well which are mostly answered by @Justin] Generally, Logging is implemented as an abstract class/interface where all required methods are declared like log, error, warn etc. Then you write implementation of this interface using a library of your choice, e.g. Log4Net

You need to add reference to log4net (or any other library that you choose) in your this project.

You need to keep it flexible so that you can change the library without changing the code everywhere else in the solution. e.g. For your production logging you use ApplicationInsight but for local dev you use log4net implementation.

A factory might be needed to get the correct type of logger depending on your environment/configuration.

All configuration related to Log4Net are kept in the web.config because it is the startup project. Also, it allows configurable properties for the library e.g minimum log level.

HTH

0

The way I see it, it depends on the scope of what you want to log. The most basic logging (and the one that should go on production to my understanding) would include only services and (maybe) web.

I assume that core and data cannot be accessed directly by the user: only through services, which in turn is accessed by services. If this is so you don't need to log every little step that data and core go through, so by handling the logging on services you know what is being requested by the user and the result of the operation; since both data and core must be informing services of the result of the request.

Further logging can be handy sometimes when debugging but I don't think that you want the overhead of the detailed log writing on production; I'd have a debug version that can be activated by configuration settings or preprocessor directives.

  • Thanks for your answer. You're right in saying that core and data having nothing to log on their own. But still, I am wanting to keep the ILogger in core, just in case I ever want to log something from core or data. Please share your thoughts regarding this approach of mine. – Sнаđошƒаӽ May 22 '17 at 12:33
  • The ILogger solution makes sense for the cases where that might be necessary, but still nor the core or the data parts should know about log4net. They should receive the instance of ILogger when instantiated. – Zalomon May 22 '17 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.