Log4net is a an excellent library that allows developers to output log statements to a variety of output targets through what is called Appenders. However, it’s not compatible with .Net Core 2.0 yet, and all the online log4net extension libraries available today don’t provide a thorough solution to rectify all log4net appenders specifically the ADOAppender; which logs to a database. In this article I am going to introduce a solution to this problem.
I have uploaded the solution to GitHub at this URL: https://github.com/rizksobhi/Log4net.NetCore
1- AdoNetAppender
I have created an appender that is compatible with .Net Core that can be used to log to a database. The code is straight forward and I have imported most of it from the log4net library. https://github.com/rizksobhi/Log4net.NetCore/blob/master/Log4net.NetCore.Lib/Appenders/AdoNetAppender.cs
2- Configuration file replacements
I have substituted the configuration file with a static configuration class which provides several ways of creating a variety of appenders. This configuration class uses the AdoNetAppender which is described above.
public static IAppender CreateAdoNetAppender(string connectionString)
{
AdoNetAppender appender = new AdoNetAppender()
{
Name = "AdoNetAppender",
BufferSize = 1,
ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089",
ConnectionString = connectionString,
CommandText = "INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)"
};
AddDateTimeParameterToAppender(appender, "@log_date");
AddStringParameterToAppender(appender, "@thread", 255, "%thread");
AddStringParameterToAppender(appender, "@log_level", 50, "%level");
AddStringParameterToAppender(appender, "@logger", 255, "%logger");
AddStringParameterToAppender(appender, "@message", 4000, "%message");
AddErrorParameterToAppender(appender, "@exception", 2000);
appender.ActivateOptions();
return appender;
}
3- ASP.Net Core integration
The following extension method helps to register log4net in the logging factory
public static ILoggerFactory AddLog4Net(this ILoggerFactory factory, string connectionString, string logFilePath)
{
factory.AddProvider(new Log4NetProvider(connectionString, logFilePath));
return factory;
}
Now we can register our log4net provider through using the extension method at the Configure function in Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Log4netDBContext context, ILoggerFactory loggerFactory)
{
loggerFactory.AddLog4Net(Configuration["Logging:ConnectionString"], Configuration["Logging:LogFilePath"]);
DBInitializer.Initialize(context);
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Here is the implementation of Log4NetProvider https://github.com/rizksobhi/Log4net.NetCore/blob/master/Log4net.NetCore.Lib/Log4NetProvider.cs
And finally using in the HomeController
public HomeController(ILogger logger)
{
_Logger = logger;
}
public IActionResult Index()
{
_Logger.LogDebug("Index has been requested");
return View();
}
References