0

We have projects in VB and C# and they all have logging. Right now the implementation of a logger factory is causing memory leaks during load test. Looks like someone tried to hack the old code to support nlog and it creates counless instances of the log factory which is creating a lot of arrays and event handler leaks. I wanted to know what is the right approach to have a class that can be referenced in other projects to enable logging. Can we do something like

public interface ILogger{
 void Error(string message);
 void Debug(string message);
}

public NlogWrapper:ILogger{
 private readonly NLog.Logger _logger;
 public NLogLogger(string name)
 {
   _logger = NLog.LogManager.GetLogger(name);
 }

Then in my other library projects I create logger insance such as

Private logger As ILogger = New NlogWrapper("Admin_" + DateTime.Now.ToString("yyyyMMdd"))
  • I got confused with Nlog.LogFactory, Microsoft.Extensions.Logging and so on.
  • Or am I over complicating it and just go ahead and call 'NLog.LogManager.GetLogger' in all of my projects? The only problem is see is that there might be other clients that consume the logging.dll
  • Microsoft.Extensions.Logging looks like a clean approach but I am not sure where we will the framework that I will be using nlog and to load nlog configuration in a .net framework application without DI
Aswin Francis
  • 87
  • 1
  • 13
  • Maybe relevant: https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-GetCurrentClassLogger-and-Microsoft-ILogger – Rolf Kristensen Aug 25 '22 at 20:28
  • Notice with Microsoft Extension Logging you can call `LoggerFactory.Create(builder =>)` without using dependency-injection. You can make a singleton-instance using `Lazy` and use it as default fallback when needed (Instead of `NullLoggerFactory`) – Rolf Kristensen Aug 25 '22 at 20:30
  • Are you on DotnetFramework or DotNet-Core ? – granadaCoder Aug 25 '22 at 20:49
  • @RolfKristensen I will need to add this to the logging library right? However, when I do so I have to add references to MS.Extensions.Logging in all my assemblies that calls ILogger. I also have to write post build event to move all nlog, MS.Extensions*dll and some System*dll to bin folder of my site. However, my intention was that this logging.dll needs to be referenced and none of the clients needs to be aware of what logger I am using or its implementation – Aswin Francis Aug 26 '22 at 08:35
  • @granadaCoder .net framework – Aswin Francis Aug 26 '22 at 08:36

2 Answers2

0

If you can the best method is probably to just use NLog directly wherever you can. The downside with this approach is that changing logging library will require changes to all projects, even if such changes might be fairly straightforward.

The recommended way to initialize a logger is

private static Logger logger = LogManager.GetCurrentClassLogger();

since this will limit the number of loggers to one per class. This would probably be my preferred alternative for new code.

WIth Microsoft extensions logging the initialization should look like

private readonly ILogger<MyClass> _logger;

public HomeController(ILogger<MyClass> logger)
{
     _logger = logger;
}

As you can see this relies on dependency injection. More on nlog vs extension logging.

You could also create a single static logger for your entire application, but this would lose the possibility to filter logs on the typename, but that might be acceptable if the current code does not use that possibility.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • My aim is to have the logging.dll take care of entire log dependencies and logic and the rest of the projects that reference this dll just need to do ILogger logger= logProvider.GeLogger("Admin") and then call logger.Debug() – Aswin Francis Aug 26 '22 at 08:37
  • @AswinFrancis, sure, you can do that with nlog, but you should probably not create a new logger for each such method call, since creating loggers is somewhat expensive. Another possible downside is that you do not have any automatic naming of the loggers, so it may be more difficult to check what actual logger is used, or apply fine grained filters to the log. – JonasH Aug 26 '22 at 08:44
0

I guess the easy solution is making two projects:

  • Logger-Interface-Project that all projects can depend on, that provides a default logger-factory-singleton that can be replaced. But by default it uses a null-logger-factory-singleton-implementation.
  • Logger-Factory-Implementation-Project that host-application projects uses and provides an implementation of the logger-factory-singleton. That allows the host-application to replace the default logger-factory-singleton (Redirecting to Console.WriteLine, NLog, etc.)
Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70