1, Foreword
Log4net is a well-known log provider. When. NET Core released 1.0, log4net was already supported. However, there is no log4net in the official log provider recommended by. NET Core, and I don't know the internal reason. Write a gadget with. NET Core, in which log4net is used for logging. This paper mainly records how to integrate log4net and the implementation of global exception capture in. NET Core.
2, Preparation
Install log4net before using log4net. The operation here is very simple. It is convenient to download and install log4net through nuget. As shown below.
3, Implementation
a. log4net configuration
Create a new profile and name it log4 net.config Used to save the configuration of log4net. The configured log4net configuration is as follows.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <log4net> <!--Define the output media of the log. The log is output in four ways. The following can also be output according to one type or other types.--> <!--Define output to a fixed file--> <appender name="FileAppender" type="log4net.Appender.FileAppender"> <file value="log/log.txt" /> <appendToFile value="true" /> <layout type="log4net.Layout.PatternLayout"> <!--Text description at the end of each log--> <header value=" [============================Application log start============================ ] " /> <footer value=" [ ===========================End of application log=============================] " /> <!--Output format--> <!--Example: 2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info--> <conversionPattern value="%newline%newline Record time:%date thread ID:[%thread] Log level:%-5level Class or assembly name:%logger %newline property:[%property] - Description:%message%newline" /> </layout> </appender> <!--Define output to file,Cycle to create log file named after date--> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <!--Define file storage location Save log of current date,When a new log is generated the next day, the log of the current date will be saved for backup--> <file value="log/log" /> <!--Do not overwrite the original file,true: Overwrite original file--> <appendToFile value="false" /> <rollingStyle value="Date" /> <!--Scrolling logs in days,Keep a log of past dates--> <datePattern value="yyyy-MM-dd-HHmm".txt"" /> <layout type="log4net.Layout.PatternLayout"> <!--Text description at the end of each log--> <header value=" [============================Application log start============================ ] " /> <footer value=" [ ===========================End of application log=============================] " /> <!--Output format--> <!--Example: 2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info--> <conversionPattern value="%newline%newline Record time:%date thread ID:[%thread] Log level:%-5level Class or assembly name:%logger %newline property:[%property] - Description:%message%newline" /> </layout> </appender> <!--Define output to console command line--> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <!--Output format--> <conversionPattern value="%newline Time:%date thread ID: [%thread] Log level:%-5level Class or assembly name:%logger %newline property:[%property] - Description:%message%newline" /> </layout> </appender> <!--Define output to console in different colors--> <appender name="ManagedColoredConsoleAppender" type="log4net.Appender.ManagedColoredConsoleAppender"> <mapping> <level value="ERROR" /> <foreColor value="DarkRed" /> </mapping> <mapping> <level value="WARN" /> <foreColor value="Yellow" /> </mapping> <mapping> <level value="INFO" /> <foreColor value="DarkGray" /> </mapping> <mapping> <level value="DEBUG" /> <foreColor value="DarkGreen" /> </mapping> <layout type="log4net.Layout.PatternLayout"> <!--Output format--> <conversionPattern value="%newline Time:%date thread ID: [%thread] Log level:%-5level Class or assembly name:%logger %newline property:[%property] - Description:%message%newline" /> </layout> </appender> <!--Define the output to the database. Here is an example of the output to the Access In the database, the database is log4net.mdb(Path can be customized)--> <appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender"> <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=logDB/log4net.mdb" /> <commandText value="INSERT INTO LogDetails ([LogDate],[Thread],[Level],[Logger],[Message]) VALUES (@logDate, @thread, @logLevel, @logger,@message)" /> <!--Define parameters--> <parameter> <parameterName value="@logDate" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date" /> </layout> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@logLevel" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="240" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> </appender> <root> <!--Control level, from low to high: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF For example, the definition level is INFO,be INFO A downward level, such as DEBUG Logs will not be logged If not defined LEVEL The default value is DEBUG--> <level value="ALL"/> <!--Record log in file form--> <appender-ref ref="FileAppender" /> <!--Console control display log--> <!--<appender-ref ref="ConsoleAppender" />--> <!--The console displays logs in different colors--> <!--<appender-ref ref="ManagedColoredConsoleAppender" />--> <!--Define the output to the database. If the corresponding logging is not enabled, it can be commented out in this way--> <!--<appender-ref ref="AdoNetAppender_Access" />--> </root> </log4net> </configuration>
b. Log help class - Logger
The log4net loading and common methods are encapsulated in the log help class, Logger. The code is as follows.
using log4net; using log4net.Repository; using System; namespace WebApplication2 { public static class Logger { private static ILoggerRepository loggerRepository; public static ILoggerRepository LoggerRepository { get; private set; } public static ILog Log { get; private set; } /// <summary> ///Static constructor, automatically executed when the program starts /// </summary> //static Logger() //{ // LoggerRepository = CreateLoggerRepository(); // LoadLog4NetConfig(); //} /// <summary> ///Initialize log /// </summary> /// <returns></returns> public static void LoadLogger() { LoggerRepository = CreateLoggerRepository(); LoadLog4NetConfig(); } /// <summary> ///Create log warehouse instance /// </summary> /// <returns></returns> private static ILoggerRepository CreateLoggerRepository() { loggerRepository = loggerRepository ?? LogManager.CreateRepository("GlobalExceptionHandler"); // Single case return loggerRepository; } /// <summary> ///Load log4net configuration /// </summary> private static void LoadLog4NetConfig() { // Configure log4net log4net.Config.XmlConfigurator.Configure(loggerRepository, new System.IO.FileInfo(System.IO.Directory.GetCurrentDirectory() + "/log4net.config")); // Create log instance Log = LogManager.GetLogger(loggerRepository.Name, AppDomain.CurrentDomain.FriendlyName); Log.Info("Log configuration loaded"); } } }
c. Global exception capture filter
The code of the global exception capture filter is as follows. There is no exception handling in the code, but it is directly output to the log. Further processing of the log information can make the log information more readable.
using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace WebApplication2 { public class HttpGlobalExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { Logger.Log.Error("Exceptions caught by global exception filter:", context.Exception); } } }
d. Specify log provider as log4net and global exception capture
Specify the log provider in the ConfigureServices method of the Startup class, as follows
In code Common.Logger.LoggerRepository For the log help class, the log warehouse instance created in logger.
Add a global exception capture filter to the ConfigureServices method of the Startup class. The code is as follows.
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // Configuration log services.AddLogging(logConfig => { //log4net.Config.XmlConfigurator.Configure(Common.Logger.LoggerRepository); Logger.LoadLogger(); }); // Add global exception capture services.AddMvc(option => { option.Filters.Add<HttpGlobalExceptionFilter>(); }); }
e. Application
[HttpGet] public IEnumerable<WeatherForecast> Get() { ///Call global auto injection instance in single instance mode Logger.Log.Info("1111"); var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); }