• 动态修改log4net组件的日志文件名


    最近项目使用到log4net来记录日志,当然二话不说先到cnblogs上查看一下各位高手关于log4net的教程和心得
    主要参看了摩诘 的Log4Net使用指南 (确实是非常好的log4net的入门指南),在此篇文章的评论中@所罗门 有个
    问题可能摩诘比较忙没有时间去是实验和解答,问题如下:
    如果我在配置文件里不设定Appender的File,即删除了<param name="File" value="log-file.txt" /> 一行信息,
    我想要在程序运行时动态的设定log日志的文件名(例如以日期来作文件名),该怎么处理才能实现 
    刚好项目也需要动态的更改log的文件名,就尝试着去跟踪一下log4net的写日志的过程,看看它是如果写日志的.
    在跟踪的工程中发现log4net.Repository.Hierarchy.Logger类下面有Appenders属性,就是返回当前所有的append
    集合,刚好通过调试跟踪发现

     log4net.ILog log  =  log4net.LogManager.GetLogger( " AppLogger " );

    创建的log是一个log4net.Core.LogImpl类型,而此类型中有个Logger属性刚刚好是log4net.Repository.Hierarchy.Logger
    类型,所以想当然的有以下修改log路径的函数

     1  private   void  ChangeLog4netLogFileName(log4net.ILog iLog, string  fileName)
     2          {
     3             log4net.Core.LogImpl logImpl =  iLog  as  log4net.Core.LogImpl;
     4               if (logImpl != null )
     5              {
     6                  log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
     7                   for ( int  i = 0 ;i < ac.Count;i ++ )
     8                  {     // 这里我只对RollingFileAppender类型做修改 
     9                      log4net.Appender.RollingFileAppender rfa  =  ac[i]  as  log4net.Appender.RollingFileAppender;
    10                       if (rfa != null )
    11                      {
    12                          rfa.File  =  fileName;
    13                           if ( ! System.IO.File.Exists(fileName))
    14                          {
    15                              System.IO.File.Create(fileName);
    16                          }
    17                      }
    18                  }
    19              }
    20          }

    ok,让我们测试一下

    private   void  TestChangeLog4netLogFileName()
            {
                 string  fileName  =   @" c:/chang.log " ;
                log4net.ILog iLog  =  log4net.LogManager.GetLogger( " AppLogger " );
                
                ChangeLog4netLogFileName(iLog, fileName);
                iLog.Info( " Test:info " );
            }

    运行,哦C盘根目录下并没有要预期一样没有出现chang.log文件.why?猜想RollingFileAppender在初始化的时候就
    固定了文件名,后期对文件名的修改是不起作用的.继续跟踪代码,发现RollingFileAppender在记录日志时直接使用
    初始化时就实例化的一个QuietTextWriter类型的私有变量m_qtw(直接继承于基类TextWriterAppender),继续跟踪发现
    基类(TextWriterAppender)提供了Writer属性来修改m_qtw的值,所有修改一下上面的ChangeLog4netLogFileName函数

     1  private   void  ChangeLog4netLogFileName(log4net.ILog iLog, string  fileName)
     2          {
     3             log4net.Core.LogImpl logImpl =  iLog  as  log4net.Core.LogImpl;
     4               if (logImpl != null )
     5              {
     6                  log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
     7                   for ( int  i = 0 ;i < ac.Count;i ++ )
     8                  {     // 这里我只对RollingFileAppender类型做修改 
     9                      log4net.Appender.RollingFileAppender rfa  =  ac[i]  as  log4net.Appender.RollingFileAppender;
    10                       if (rfa != null )
    11                      {
    12                          rfa.File  =  fileName;
    13                           if ( ! System.IO.File.Exists(fileName))
    14                          {
    15                              System.IO.File.Create(fileName);
    16                          }
    17                           // 更新Writer属性 
    18                          rfa.Writer = new  System.IO.StreamWriter(rfa.File,rfa.AppendToFile,rfa.Encoding);
    19                      }
    20                  }
    21              }
    22          }

    在运行上面的测试代码,ok,chang.log文件如愿的出现.
    第一次写blogs,罗里罗嗦一大段,希望不会挑战你的耐心^_^

    最后附上log4net的配置(也直接从cnblogs上的某位大侠上面copy下来的)

     1  <? xml version="1.0" encoding="utf-8"  ?>  
     2  < configuration >  
     3       <!-- 如果不用App.config作配置文件,则configSections节不是必须的。 -->  
     4       < configSections >  
     5           <!-- “type”属性的完整格式为:配置节处理器类名,程序集名称,Version=程序集版本号,Culture=区域信息,PublicKeyToken=公钥 -->  
     6           < section  name ="log4net"  type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net"   />  
     7       </ configSections >  
     8       < log4net >  
     9           <!-- 日志记录器logger,可以有多个 -->  
    10           < logger  name ="AppLogger" >  
    11               < level  value ="ALL"   />  
    12               < appender-ref  ref ="RollingLogFileAppender"   />  
    13               < appender-ref  ref ="ConsoleAppender"   />  
    14           </ logger >  
    15           < logger  name ="Form1" >  
    16               < level  value ="DEBUG"   />  
    17               < appender-ref  ref ="LogFileAppender"   />  
    18           </ logger >  
    19           <!-- 所有logger的基,root的设置在所有logger中都起作用。 
    20          当在root和logger中重复设定相同的appender时,你会发现同一日志信息将被记录两次。 -->  
    21           <!-- <root> 
    22              <level value="WARN" /> 
    23              <appender-ref ref="LogFileAppender" /> 
    24              <appender-ref ref="ConsoleAppender" /> 
    25          </root> -->  
    26           <!-- 一个appender可以由多个logger共用,当然一个logger可以指定多个appender。 -->  
    27           < appender  name ="LogFileAppender"  type ="log4net.Appender.FileAppender" >  
    28               < param  name ="File"  value ="App.log"   />  
    29               < param  name ="AppendToFile"  value ="true"   />  
    30               < layout  type ="log4net.Layout.PatternLayout" >               
    31                   < param  name ="ConversionPattern"  value ="%d [%t] %-5p %c [%x] %X{auth} - %m%n"   />  
    32               </ layout >  
    33               < filter  type ="log4net.Filter.LevelRangeFilter" >  
    34                   < param  name ="LevelMin"  value ="ALL"   />  
    35                   < param  name ="LevelMax"  value ="FATAL"   />  
    36               </ filter >  
    37           </ appender > 
    38           < appender  name ="RollingLogFileAppender"  type ="log4net.Appender.RollingFileAppender" > 
    39               < file  value ="log/logfile1.log"   /> 
    40               < appendToFile  value ="true"   /> 
    41               < rollingStyle  value ="Date"   /> 
    42               < datePattern  value ="yyyyMMdd"   /> 
    43               < encoding  value ="utf-8" /> 
    44               < layout  type ="log4net.Layout.PatternLayout" >                 
    45                   < conversionPattern  value ="%d [%r] [%-5level]: - %message%newline"   /> 
    46               </ layout > 
    47           </ appender >  
    48           < appender  name ="ConsoleAppender"  type ="log4net.Appender.ConsoleAppender" >  
    49               < layout  type ="log4net.Layout.PatternLayout" >  
    50                   < param  name ="ConversionPattern"  value ="%d [%t] %-5p %c [%x] %X{auth} - %m%n"   />  
    51               </ layout >  
    52           </ appender >  
    53       </ log4net >  
    54  </ configuration > 
  • 相关阅读:
    Extjs Ext.ux.IFrame的用法 以及父子窗口间函数相互调用
    Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
    Java sun.misc.Unsafe类的学习笔记
    Java 并发编程学习笔记 理解CLH队列锁算法
    深入理解Java虚拟机 -- 读书笔记(1):JVM运行时数据区域
    Java并发编程学习笔记 深入理解volatile关键字的作用
    JVM Client Server启动设置
    双重检查锁定与延迟初始化
    Tomcat 添加为系统服务 开机自动启动
    配置TOMCAT 修改默认ROOT路径
  • 原文地址:https://www.cnblogs.com/Alex80/p/4377183.html
Copyright © 2020-2023  润新知