Log4Net log classification and automatic maintenance, log4net log Classification
Background
In the program, Log4Net is a good solution for debugging runtime information. I don't know if I use it badly. Instead, I don't want to read the logs. The reason is that I use the default Logger of n functions to record logs. In this way, the information recorded by all functions is dependent on the same configuration, so all the information is in one file, sometimes it is very inconvenient to search.
I think, can I classify them by function? If you configure different logger and load the Ilog instance based on different loggernames, you can do this. However, because the log configurations of these functions are extremely different, the file names may be different. So I want to configure it through code.
Solution
It should be normal to come to this kind of requirement. However, after searching, I found that there was related consultation in log4j, but I couldn't understand it. I could only download the source code of log4net myself and see how it works.
If we need to configure different ilogs, the process is like this. First, we need to create an ILoggerRepository to configure the Log Level and various Appender, then, you can use LogManager to obtain an Ilog object in ILoggerRepository to write logs. The Code is as follows:
Public static ILog GetLogger (string repositoryName = "") {if (string. isNullOrEmpty (repositoryName) return LogManager. getLogger ("Defalut"); ILoggerRepository repository = null; try {repository = LogManager. getRepository (repositoryName);} catch (Exception) {}// returns ilog if (repository! = Null) return LogManager. getLogger (repositoryName, "Defalut"); // It is created if it is not found. It is very likely that when it is created in multiple threads, try {repository = LogManager exists. createRepository (repositoryName);} catch (Exception) {repository = LogManager. getRepository (repositoryName);} // you can specify the log level to read the logs. The default value is var appSet = ConfigurationManager. appSettings. allKeys; // query the Log Level const string logLevel = "LogLevel"; var hasSettings = Array. indexOf (appSet, logLevel); if (hasSettings>-1) {var level = ConfigurationManager. appSettings [logLevel]. toLower (); if (level = "all") repository. threshold = Level. all; else if (level = "debug") repository. threshold = Level. debug; else if (level = "info") repository. threshold = Level. info; else if (level = "warn") repository. threshold = Level. warn; else if (level = "error") repository. threshold = Level. error; else if (level = "fatal") repository. threshold = Level. fatal; else if (level = "off") repository. threshold = Level. off;} else repository. threshold = Level. all; // search for the output Appender const string logAppender = "LogAppender"; hasSettings = Array. indexOf (appSet, logAppender); if (hasSettings>-1) {var appenders = ConfigurationManager. appSettings [logAppender]. toLower (). split (','); foreach (var appender in appenders) {if (appender = "rollingfile") LoadRollingFileAppender (repository); else if (appender = "console ") loadConsoleAppender (repository); else if (appender = "trace") LoadTraceAppender (repository) ;}} else LoadRollingFileAppender (repository); return LogManager. getLogger (repositoryName, "Default ");}
Log4net automatically maintains ILog and ILoggerRepository, so you do not need to save it. You can obtain it through LogManger. However, I cannot find a way to check whether the specified ILoggerRepository exists. Therefore, I can use try catch in the above Code to determine whether the ILoggerRepository exists. Because we configure log4net through code, but still want to set the Log Level and output type through configuration, so I choose to configure it in the deleettings file once, it takes effect for all ILoggerRepository. The reason for not configuring each function is mainly because of configuration troubles. If you want to configure different logger directly in log4net, it may be better to reference it through loggername.
Log Maintenance
So the next question is, how do I delete logs?
Log4net can configure RollingFileAppender, which is translated as a rolling file. You can set the MaximumFileSize and MaxSizeRollBackups parameters to create a new file every time the log file reaches a certain size. The maximum number of files is MaxSizeRollBackups, the premise is that the file names are consistent.
For example, we use the following Configuration:
<! -- RollingFileAppender: output to file --> <appender name = "SysAppender" type = "log4net. Appender. RollingFileAppender"> <! -- Log Path --> <file value = "Logs/"/> <! -- Overwrite or not. The default value is true. --> <appendToFile value = "true"/> <! -- Do not occupy the log file process --> <lockingModel type = "log4net. Appender. FileAppender + MinimalLock"/> <rollingStyle value = "Composite"/> <! -- File name --> <DatePattern value = "yyyy-MM-dd HH 'hour. log'"> </DatePattern> <! -- Set unlimited backup =-1 and the maximum number of backups is 1000 --> <param name = "MaxSizeRollBackups" value = "1000"/> <! -- Size of each file --> <param name = "MaximumFileSize" value = "500KB"/> <! -- Can the name be changed to false? --> <param name = "StaticLogFileName" value = "false"/> <layout type = "log4net. Layout. PatternLayout"> <! -- Output format --> <conversionPattern value = "% n [record time] % date % n [description] % message % n"/> </layout> </appender>
The result is that logs are backed up in hours, and the maximum number of backups per hour is 1000. A log file is generated every kb. As the number of days increases, the number of files increases and we need to clear the files ourselves. Therefore, the preceding configuration can be changed slightly:
<! -- RollingFileAppender: output to file --> <appender name = "SysAppender" type = "log4net. Appender. RollingFileAppender"> <! -- Log Path --> <file value = "Logs/log. log"/> <! -- Overwrite or not. The default value is true. --> <appendToFile value = "true"/> <! -- Do not occupy the log file process --> <lockingModel type = "log4net. Appender. FileAppender + MinimalLock"/> <rollingStyle value = "Composite"/> <! -- File name --> <DatePattern value = "yyyy-MM-dd HH 'hour. log'"> </DatePattern> <! -- Set unlimited backup =-1 and the maximum number of backups is 1000 --> <param name = "MaxSizeRollBackups" value = "1000"/> <! -- Size of each file --> <param name = "MaximumFileSize" value = "500KB"/> <! -- Can the name be changed to false? --> <param name = "StaticLogFileName" value = "true"/> <layout type = "log4net. Layout. PatternLayout"> <! -- Output format --> <conversionPattern value = "% n [record time] % date % n [description] % message % n"/> </layout> </appender>
It mainly sets the log file name and static name, which cannot be changed. In this way, there are a maximum of 1000 log files, so you do not need to manually maintain them. You will see such log file names:
Log. log. log.1 log. log.2... by default, the last number of the file name increases and the time is the oldest. Therefore, you can view the new log mainly in the first file name.
Note: If the Appender uses a static file name, the history log will be overwritten, and the application that cares about the history log is extremely concerned. We recommend that you do not use this solution to clear the logs, write code honestly.
Download test code