I'm logging just fine using dependency injection on my controllers, now I need to log something from a static class.
How can I log from a static class?
I can't use dependency injection because it's static and I can't just pass in an existing logger object to the static class because it would have the wrong name of class in the log file.
In other words how can I get a logger from the loggerfactory inside my static class?
I came across a similar question and they pointed to an article on a loggerfactory in a static class but that doesn't actually work as I can't get a new logger from it because it won't accept a static class as the parameter:
"Static types cannot be used as type arguments"
Set the environment key Logging:LogLevel:Microsoft to a value of Information on Windows. Test the settings when using an app created with the ASP.NET Core web application templates. The dotnet run command must be run in the project directory after using set .
You can use dependency injection in a static class using method or property injection. However, you cannot use constructor injection in a static class because the constructor of a static class cannot accept any parameters.
log4net is one of the most common external logging services available to . NET developers. The developers for log4net promise you can have logging integrated with your application within minutes, and it's true—setup is easy. log4net is available in NuGet, so it's just as easy to install as it is to code.
The ILoggerFactory is the factory interface for creating an appropriate ILogger type instance and also for adding the ILoggerProvider instance. The Logging API includes the built-in LoggerFactory class that implements the ILoggerFactory interface.
Solution is to have a static reference to the LoggerFactory in a utility static class initialized on startup:
/// <summary>
/// Shared logger
/// </summary>
internal static class ApplicationLogging
{
internal static ILoggerFactory LoggerFactory { get; set; }// = new LoggerFactory();
internal static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName);
}
Which you initialize on Startup.cs:
public Startup(ILogger<Startup> logger, ILoggerFactory logFactory, IHostingEnvironment hostingEnvironment)
{
_log = logger;
_hostingEnvironment = hostingEnvironment;
Util.ApplicationLogging.LoggerFactory = logFactory;//<===HERE
}
Then you can build a logger to use from your static class like so:
internal static class CoreJobSweeper
{
private static ILogger log = Util.ApplicationLogging.CreateLogger("CoreJobSweeper");
}
I found this question with answers useful, but I remembered I already have installed Serilog. Instead of implementing a custom static instance, I could use the default implementation from Serilog.
It comes with multiple nice logging features with multiple overloaded version.
Here are two examples:
using Serilog;
...
Log.Error(myException, "my message");
Log.Warning("My message", myValue);
Serilog.Log
is a static instance that is ready when configured in Program.cs or Startup.cs.
You can use the static LoggerFactory
instance with the following extension method which accepts a regular parameter of type Type
, rather than a generic type parameter:
CreateLogger(ILoggerFactory, Type)
i.e. loggerFactory.CreateLogger(typeof(T))
rather than loggerFactory.CreateLogger<T>()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With