参考:
log4j日志管理系统简单使用说明:http://www.360doc.com/showRelevantArt.aspx?ArticleID=6711&ArticleNum=6
如何用自己的 appender 来扩展 log4j 框架:http://www.360doc.com/showWeb/0/0/4468.aspx
本人和同事正在设计一个应用struts,spring,hibernate等技术的企业信息化的web系统。为了建立自己灵活的高效的日志系统,比如对所有的sql,或者对所有的error信息,又或者对特定的信息,特定的Log4j日志级别(ALL
、DEBUG
、INFO
、WARN
、ERROR
, FATA或
OFF)
分别输出到相应的日志。总之就是能随意操纵怎么样的log信息写到那里去。于是选择log4j。
但是简单地使用log4j却满足不了我的要求。曾想过许多的方法来通过log4j将所有的执行sql语句写到特定的文件里,
但是均因为log4j只会将日志级别 大于等于 配置文件的设置属性appender.x.Threshold的日志输出。
比如
《log4j.properties》
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Threshold=WARN
只会将级别为WARN,ERROR,FATA的日志信息输出。
这样的话,就满足我不了我的要求,比如将WARN和INFO的信息输出到屏幕,将DEBUG的信息输出到DEBUG.TXT.
于是就只能编写自己的appender来扩张log4j框架,这样就可以做到随意根据日志级别输出。
比如
(1)将debug信息输出到debug.txt.
(2)WARN和INFO的信息输出到屏幕
看我的配置文件《Log4j_ex.properties》
log4j.rootLogger=DEBUG,A1,R,S,ALL_Log
##只将WARN和INFO的信息输出到屏幕
log4j.appender.A1=hr.log4j.MyConsoleAppender
log4j.appender.A1.Threshold_1=ERROR
log4j.appender.A1.Switch_1=on
log4j.appender.A1.Threshold_2=INFO
log4j.appender.A1.Switch_2=on
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
##只将debug信息输出到debug.txt
log4j.appender.R=hr.log4j.MyRollingFileAppender
log4j.appender.R.File=debug.txt
#log4j.appender.R.MaxFileSize=500KB
#log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.Threshold_1=DEBUG
log4j.appender.R.Switch_1=on
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n
##只将sql的语句输出到sql.txt
log4j.appender.S=hr.log4j.MyRollingFileAppender
log4j.appender.S.File=sql.txt
#log4j.appender.S.MaxFileSize=500KB
#log4j.appender.S.MaxBackupIndex=1
log4j.appender.S.Threshold_3=INFO
log4j.appender.S.Switch_3=On
log4j.appender.S.MessageSetting=SQL
log4j.appender.S.layout=org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n
##将所有的日子信息输出到ALL_Log.txt
log4j.appender.ALL_Log=org.apache.log4j.RollingFileAppender
log4j.appender.ALL_Log.File=ALL_Log.txt
log4j.appender.ALL_Log.MaxFileSize=500KB
log4j.appender.ALL_Log.MaxBackupIndex=1
log4j.appender.ALL_Log.layout=org.apache.log4j.PatternLayout
log4j.appender.ALL_Log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
src:
package com.wwking.wtspring.frame.web.log;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Priority;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
/**
* @author laiyuyou
* @version 1.0 2006/07/14
*/
public abstract class WTAppenderSkeleton extends AppenderSkeleton {
/**
* There is no level threshold filtering by default.
*/
protected Priority threshold_1;
protected String switch_1;
protected Priority threshold_2;
protected String switch_2;
protected Priority threshold_3;
protected String switch_3;
/** just for the special setting */
protected String messageSetting;
/**
* This method performs threshold checks and invokes filters before
* delegating actual logging to the subclasses specific {@link
* AppenderSkeleton#append} method.
*/
public synchronized void doAppend(LoggingEvent event) {
if (closed) {
LogLog.error("Attempted to append to closed appender named [" + name + "].");
return;
}
//turn on the filter switch.
if (!isAsSevereAsThreshold(event.getLevel())) {
return;
}
//filter the unspecify Message.
if (this.messageSetting != null) {
if (!isMessageSetting(event)) {
return;
}
}
Filter f = this.headFilter;
FILTER_LOOP: while (f != null) {
switch (f.decide(event)) {
case Filter.DENY:
return;
case Filter.ACCEPT:
break FILTER_LOOP;
case Filter.NEUTRAL:
f = f.next;
}
}
this.append(event);
}
/**
Check whether the message level is equal the appender's
threshold_1 or threshold_2 or threshold_3 that the switch corresponded is turn on. If there is no threshold set, then the return value is
always <code>false</code>.
*/
public boolean isAsSevereAsThreshold(Priority priority) {
boolean rt = false;
if (switch_1 != null && switch_1.equalsIgnoreCase("on")) {
rt = rt || ((threshold_1 != null) && priority.equals(threshold_1));
}
if (switch_2 != null && switch_2.equalsIgnoreCase("on")) {
rt = rt || ((threshold_2 != null) && priority.equals(threshold_2));
}
if (switch_3 != null && switch_3.equalsIgnoreCase("on")) {
rt = rt || ((threshold_3 != null) && priority.equals(threshold_3));
}
return rt;
}
private boolean isMessageSetting(LoggingEvent event) {
if (event.getMessage().toString().length() >= messageSetting.length()) {
String ms = event.getMessage().toString().substring(0,
messageSetting.length());
if (ms.equalsIgnoreCase(messageSetting)) {
return true;
} else {
return false;
}
}
return true;
}
public String getMessageSetting() {
return messageSetting;
}
public void setMessageSetting(String messageSetting) {
this.messageSetting = messageSetting;
}
public String getSwitch_1() {
return switch_1;
}
public void setSwitch_1(String switch_1) {
this.switch_1 = switch_1;
}
public String getSwitch_2() {
return switch_2;
}
public void setSwitch_2(String switch_2) {
this.switch_2 = switch_2;
}
public String getSwitch_3() {
return switch_3;
}
public void setSwitch_3(String switch_3) {
this.switch_3 = switch_3;
}
public Priority getThreshold_1() {
return threshold_1;
}
public void setThreshold_1(Priority threshold_1) {
this.threshold_1 = threshold_1;
}
public Priority getThreshold_2() {
return threshold_2;
}
public void setThreshold_2(Priority threshold_2) {
this.threshold_2 = threshold_2;
}
public Priority getThreshold_3() {
return threshold_3;
}
public void setThreshold_3(Priority threshold_3) {
this.threshold_3 = threshold_3;
}
}