log4j自定义级别并将新级别日志信息输出到指定带日期格式的log文件

时间:2022-11-09 21:49:23

参考网上各家的资料,本人实现的功能如下:

1、自定义级别:SERIOUS

2、将log.mailLog日志信息输出到指定log文件

3、按天更新日志,并将当天日期添加在文件名中



log4j可以实现INFO、DEBUG、ERROR等级别的日志输出,但是如果我们想自定义一个级别,并且将此级别的日志输出到指定的文件里,应该怎样做呢。

手上没有log4j的源码,只有用反编译工具对其开膛破肚了

有发现:


public class Level extends Priority
  implements Serializable
{
  public static final int TRACE_INT = 5000;
  public static final Level OFF = new Level(2147483647, "OFF", 0);

  public static final Level FATAL = new Level(50000, "FATAL", 0);

  public static final Level ERROR = new Level(40000, "ERROR", 3);

  public static final Level WARN = new Level(30000, "WARN", 4);

  public static final Level INFO = new Level(20000, "INFO", 6);

  public static final Level DEBUG = new Level(10000, "DEBUG", 7);

  public static final Level TRACE = new Level(5000, "TRACE", 7);

像FATAL、ERROR这些级别,实际上对应一数字50000、40000

猜想:我们可以自己定义一个级别呀,比如我们定义一个级别:20050,暂叫做SERIOUS吧

我打算将邮件发送情况记录在这个级别的日志文件里,写了个MailLog的类,源码如下:


/**
 * 
 *  用途:用于记录邮件发送的LOG类
 *
 */
public class MailLog {

 private static Logger logger = Logger.getLogger(MailLog.class);

 private static class SeriousLevel extends Level {
  private static final long serialVersionUID = 1076913470822079835L;

  private SeriousLevel(int level, String name, int sysLogLevel) {
   super(level, name, sysLogLevel);
  }
 }

 private static final Level MAIL_LOG_LEVEL = new SeriousLevel(
   20050, "SERIOUS", SyslogAppender.LOG_LOCAL0);

 public static void mailLog(Object pm_objLogInfo) {
  logger.log(MAIL_LOG_LEVEL, pm_objLogInfo);
 }
}



log4j.xml的配置如下:
<appender name="LOG.EMAIL" class="org.apache.log4j.RollingFileAppender">  
<param name="File" value="${catalina.home}/logs/EMAIL_LOG.log" />  
<param name="MaxFileSize" value="5120KB" /> 
<param name="MaxBackupIndex" value="10" />  
<layout class="org.apache.log4j.PatternLayout">  
  <param name="ConversionPattern" value="%d{yyy-MM-dd HH:mm:ss} [%-5p] %c {%F:%L} - %m%n" />  
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">     
  <param name="LevelMin" value="20050" />     
  <param name="LevelMax" value="20050" />     
</filter>    
</appender>


测试发现不对呀,EMAIL_LOG.log这个文件里除了自定义的级别日志外,还有debug、INFO等日志,是哪里的问题呢?

注意到,配置文件里有个filter,再次开膛破肚中,看下这个类org.apache.log4j.varia.LevelRangeFilter

很明了,过滤器里有个方法decide,就是在这里进行判断过滤的,所以,我们可以参考着,自己写个filter,源码如下:


public class MailLogFilter extends Filter {
 boolean acceptOnMatch = false;
 int levelMin;
 int levelMax;

 public int getLevelMin() {
  return levelMin;
 }

 public void setLevelMin(int levelMin) {
  this.levelMin = levelMin;
 }

 public int getLevelMax() {
  return levelMax;
 }

 public void setLevelMax(int levelMax) {
  this.levelMax = levelMax;
 }

 @Override
 public int decide(LoggingEvent lgEvent) {

  int inputLevel = lgEvent.getLevel().toInt();
  if (inputLevel >= levelMin && inputLevel <= levelMax) {
   return 0;
  }
  return -1;
 }

}


再将log4j.xml的配置里的filter更改为上面的类:


<appender name="LOG.EMAIL" class="org.apache.log4j.DailyRollingFileAppender">

<param name="File" value="${catalina.home}/logs/EMAIL_LOG.log" />  

<param name="Append" value="true"/>
<param name="MaxFileSize" value="5120KB" /> 
<param name="MaxBackupIndex" value="10" />  
<layout class="org.apache.log4j.PatternLayout">  
  <param name="ConversionPattern" value="%d{yyy-MM-dd HH:mm:ss} [%-5p] %c {%F:%L} - %m%n" />  
</layout>
<filter class="com.test.mail.MailLogFilter">     
  <param name="LevelMin" value="20050" />     
  <param name="LevelMax" value="20050" />     
</filter>    
</appender>


如果XML中有category,则在相应的下面添加LOG.EMAIL即可,例如在我的配置文件中还应该有如下两段:

<category name="com">
<priority value="DEBUG"/>
   <appender-ref ref="console"/>
   <appender-ref ref="LOG.EMAIL"/>
</category>

<category name="jsp_servlet">
<priority value="DEBUG"/>
   <appender-ref ref="console"/>
   <appender-ref ref="LOG.EMAIL"/>
</category>

大功告成!


测试:在项目文件中添加如下代码进行测试


MailLog loger = newMailLog ();
loger.mailLog("mailLog测试!--SERIOUS");


可以看到控制台有输出:mailLog测试!--SERIOUS


然后要将日志输出到指定文件,需要在xml配置文件中进行控制:


<appender name="LOG.EMAIL" class="org.apache.log4j.RollingFileAppender">  

 此处控制日志生成模式。

RollingFileAppender:普通生成日志文件,将新日志生成到一个文件

<param name="Append" value="true"/> 该参数控制是否覆盖掉文件中已有的日志信息,默认是false,即覆盖掉已有信息而不是追加到文件中
<param name="MaxFileSize" value="5120KB" /> 此处控制当文件大小达到设定大小后,将会另起一个新日志文件
<param name="MaxBackupIndex" value="10" /> 


DailyRollingFileAppender:按天生成日志文件

<param name="ConversionPattern" value="%d{yyy-MM-dd HH:mm:ss}  在日志文件名中添加当天日期,但是会先生成一个EMAIL_LOG.log文件(相当于临时文件),只有一天结束后才会将上一天的日志信息汇总到一个新文件并添加日期到文件名中。


具体可以参见:http://blog.csdn.net/wk_nba/article/details/4296872#reply

[%-5p] %c {%F:%L} - %m%n" />  控制日志信息的输出格式,不在赘述!


<filter class="com.test.mail.MailLogFilter">     
  <param name="LevelMin" value="20050" />     
  <param name="LevelMax" value="20050" />     
</filter>   


       上述可以控制只是输出loger.mailLog信息到日志文件,这对于监测工程中特定操作还是十分有效的,当让你也可以设定多个级别,只需将其控制在LevelMin和LevelMax之间,即可同时输出到日志文件,十分便捷!


       上述实验亲测有效,都是在别人搭好的环境中配置而成,至于具体如何添加到一个全新的工程中,还有待细究,留作下次再讲!

本次用到的链接:

http://www.taozhi168.com/dv_rss.asp?s=xhtml&boardid=14&id=764&page=1

http://www.blogjava.net/i369/archive/2012/02/24/209979.html