6. log4net配置使用

一. 目标

  • 1. 项目中使用log4net进行日志显示
  • 2. 过期日志进行清理
  • 3. 可以分目录和分文件显示日志

二. 技能介绍

① 使用log4Net的配置步骤

第一步: 创建App.config配置文件,并对log4Net配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net debug="true">
    <!--
    其中layout节点的配置说明:
    %m(message):输出的日志消息;
    %n(newline):换行;
		%d(datetime):输出当前语句运行的时刻;
		%r(runtime):输出程序从运行到执行到当前语句时消耗的毫秒数;
		%t(threadid):当前语句所在的线程ID ;
		%p(priority): 日志的当前日志级别;
		%c(class):当前日志对象的名称;
		%L:输出语句所在的行号;
		%F:输出语句所在的文件名;
		%-10:表示最小长度为10,如果不够,则用空格填充;
    -->
    <root>
      <!--() OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL () -->
      <level value="all" />
      <!--<appender-ref ref="ColoredConsoleAppender"/>-->
      <!--<appender-ref ref="RollingLogFileAppender"/>-->
    </root>
    <logger name="MainSlaveLogger">
      <appender-ref ref="MainSlave"/>
    </logger>
    <appender name="MainSlave" type="log4net.Appender.RollingFileAppender">
      <!--日志路径-->
      <param name= "File" value= "Logs\主站\"/>
      <!--多线程时采用最小锁定-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留的备份数的最大值,如果为0表示不备份-->
      <param name= "MaxSizeRollBackups" value= "0"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2022-05-22.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd'_Main.Log'"/>
      <!--日志根据日期滚动-->
      <param name= "RollingStyle" value= "Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <!-- 默认的  <param name="ConversionPattern" value="%n%d [%t] %-5p %c [%L] - %m %n" /> -->
        <param name="ConversionPattern" value="%n%d [%t] %-5p  - %m %n" />
      </layout>
    </appender>
  </log4net>
  <appSettings>
    <!-- 过期日志设置限制 -->
    <add key="OverdueDays" value="15"/>
  </appSettings>
</configuration>

第二步: 编写LoggerHelper类,对日志进行一些操作

日志的配置文件需要应用程序去加载,这里有两种加载方式,第一种是手动的去加载,比如在构造函数中去加载配置,如下图所示的程序.

namespace WaferSelectV3.Common
{
    public class LoggerHelper
    {
        // 静态构造函数在类型被第一次使用之前自动被调用,并且只会被调用一次.
        // 这里的使用指的是引用任何静态成员,创建类的实例或者是派生自该类型的类被使用
        static LoggerHelper()
        {
            // 加载log4Net的配置文件(手动加载)
            log4net.Config.XmlConfigurator.Configure();
            MainLogger = LogManager.GetLogger(@"MainSlaveLogger");
            WriteLogMain("LoggerHelper() 构造方法被调用", LogType.Test);
        }

        // 主站日志记录
        public static void WriteLogMain(string message, LogType logType, string errorCode = "")
        {
            switch (logType)
            {
                case LogType.Info:
                    MainLogger.Info(message);
                    break;
                case LogType.Debug:
                    MainLogger.Debug(message);
                    break;
                case LogType.Warn:
                    MainLogger.Warn(message);
                    break;
                case LogType.Exception:
                    MainLogger.Error(message);
                    break;
                case LogType.Fatal:
                    MainLogger.Fatal(message);
                    break;
                case LogType.Test:
                    MainLogger.Info($"TestShow:  {message}");
                    break;
            }
        }

        private static readonly ILog MainLogger;
    }

    public enum LogType
    {
        Info,
        Debug,
        Warn,
        Exception,
        Fatal,
        Test,
    }
}

当然这里加载日志配置文件的方式还有另外一种,就是让.NET应用自己去加载,只需要在应用配置文件AssemblyInfo.cs文件中加入下面的代码

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
② 清理过期日志
private static void DoClearOverDueLogs()
{
   // 从配置文件中获取保存日志的天数
   int maxDays = Convert.ToInt32(ConfigurationManager.AppSettings["OverdueDays"]);
   // 如果没有配置的时候maxDays返回的是多少呢.如果上面的OverdueDays没有配置,默认这里是返回0
   int days = maxDays == 0 ? 15 : maxDays;
   // 最小日期
   DateTime latestDay = DateTime.Now.AddDays(-days);
   // 通过LoggerManager获取所有的Appender
   //IAppender[] appenders = LoggerManager.GetRepository(Assembly.GetEntryAssembly()).GetAppenders();
   // 通过Logger对象获取所有的appenders,都是先获取Repository.都是先获取日志仓库,然后获取日志配置文件中已经配置的
   // 的所有的Appender.
   IAppender[] appenders = MainLogger.Logger.Repository.GetAppenders();
   foreach (var append in appenders)
   {
       if (!(append is RollingFileAppender roller))
       {
           continue;
       }
       string? dir = Path.GetDirectoryName(roller.File);
       string[] files = Directory.GetFiles(dir!, "*.log*");
       foreach (string filePath in files)
       {
           FileInfo file = new FileInfo(filePath);
           if (file.CreationTime < latestDay || file.LastWriteTime < latestDay)
           {
               try
               {
                   file.Delete();
               }
               catch (Exception ex)
               {
                   WriteLogMain("日志清理失败: " + ex.Message, LogType.Info);
               }
           }
       }
   }
}

然后在构造函数中调用这个清理过期日志的任务

static LoggerHelper()
{
    // 加载log4Net的配置文件(手动加载)
    //log4net.Config.XmlConfigurator.Configure();
    MainLogger = LogManager.GetLogger(@"MainSlaveLogger");
    SizeLogger = LogManager.GetLogger(@"SizeSlaveLogger");
    WriteLogMain("LoggerHelper() 构造方法被调用", LogType.Test);

    Task.Run(async () =>
    {
        try
        {
            while (!ClearCts.Token.IsCancellationRequested)
            {
                DoClearOverDueLogs();
                WriteLogMain("清除过期日志完成.", LogType.Info);
                // 每隔24小时清理一次,后面加上一个Token的目的就是可以在外部取消这个异步等待任务
                await Task.Delay(86400000, ClearCts.Token);
            }
        }
        catch (OperationCanceledException)
        {
            WriteLogMain("清理过期日志监控任务被取消", LogType.Info);
        }
        catch (Exception ex)
        {
            WriteLogMain("清理过期日志任务发生异常: " + ex.Message, LogType.Exception);
        }
    });
}
③ 多日志文件显示

假如有这样的需求,你想要在同一个应用程序中,分文件保存日志,该如何去做呢,其实很简单.就在配置文件中多添加几个logger节点和appender节点即可,改成对应的目录名和文件名即可

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net debug="true">
    <!--
    其中layout节点的配置说明:
    %m(message):输出的日志消息;
    %n(newline):换行;
		%d(datetime):输出当前语句运行的时刻;
		%r(runtime):输出程序从运行到执行到当前语句时消耗的毫秒数;
		%t(threadid):当前语句所在的线程ID ;
		%p(priority): 日志的当前日志级别;
		%c(class):当前日志对象的名称;
		%L:输出语句所在的行号;
		%F:输出语句所在的文件名;
		%-10:表示最小长度为10,如果不够,则用空格填充;
    -->
    <root>
      <!--() OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL () -->
      <level value="all" />
      <!--<appender-ref ref="ColoredConsoleAppender"/>-->
      <!--<appender-ref ref="RollingLogFileAppender"/>-->
    </root>
    <logger name="MainSlaveLogger">
      <appender-ref ref="MainSlave"/>
    </logger>
    <logger name="SizeSlaveLogger">
      <appender-ref ref="SizeSlave"/>
    </logger>
    <appender name="MainSlave" type="log4net.Appender.RollingFileAppender">
      <!--日志路径-->
      <param name= "File" value= "Logs\主站\"/>
      <!--多线程时采用最小锁定-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留的备份数的最大值,如果为0表示不备份-->
      <param name= "MaxSizeRollBackups" value= "0"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2022-05-22.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd'_Main.Log'"/>
      <!--日志根据日期滚动-->
      <param name= "RollingStyle" value= "Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <!-- 默认的  <param name="ConversionPattern" value="%n%d [%t] %-5p %c [%L] - %m %n" /> -->
        <param name="ConversionPattern" value="%n%d [%t] %-5p  - %m %n" />
      </layout>
    </appender>
    <appender name="SizeSlave" type="log4net.Appender.RollingFileAppender">
      <!--日志路径-->
      <param name= "File" value= "Logs\尺寸\"/>
      <!--多线程时采用最小锁定-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留的备份数的最大值,如果为0表示不备份-->
      <param name= "MaxSizeRollBackups" value= "0"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2022-05-22.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd'_Size.Log'"/>
      <!--日志根据日期滚动-->
      <param name= "RollingStyle" value= "Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <!-- 默认的  <param name="ConversionPattern" value="%n%d [%t] %-5p %c [%L] - %m %n" /> -->
        <param name="ConversionPattern" value="%n%d [%t] %-5p  - %m %n" />
      </layout>
    </appender>
  </log4net>
  <appSettings>
    <!-- 过期日志设置限制 -->
    <add key="OverdueDays" value="15"/>
  </appSettings>
</configuration>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值