我不完全确定为什么创造一个新的如此繁重。这似乎对我有用:LoggingEvent
package test.logging;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.spi.LoggingEvent;
public class MyDailyRollingFileAppender extends DailyRollingFileAppender {
@Override
protected void subAppend(LoggingEvent event) {
String modifiedMessage = String.format("**** Message modified by MyDailyRollingFileAppender ****\n\n%s\n\n**** Finished modified message ****", event.getMessage());
LoggingEvent modifiedEvent = new LoggingEvent(event.getFQNOfLoggerClass(), event.getLogger(), event.getTimeStamp(), event.getLevel(), modifiedMessage,
event.getThreadName(), event.getThrowableInformation(), event.getNDC(), event.getLocationInformation(),
event.getProperties());
super.subAppend(modifiedEvent);
}
}
通过此测试:
package test;
import org.apache.log4j.Logger;
public class TestLogging {
public static void main(String[] args) {
Logger log = Logger.getLogger(TestLogging.class);
log.info("I am testing my logging");
log.info("Here is an exception", new Exception());
}
}
和此配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="MyDailyRollingFileAppender" class="test.logging.MyDailyRollingFileAppender">
<param name="Append" value="true"/>
<param name="datePattern" value="'.'yyyy-MM-dd"/>
<param name="File" value="mine.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p (%x) [%t] %c{1} - %m%n" />
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="MyDailyRollingFileAppender"/>
</root>
</log4j:configuration>
我得到以下输出:
2011-10-14 10:09:09,322 INFO () [main] TestLogging - **** Message modified by MyDailyRollingFileAppender ****
I am testing my logging
**** Finished modified message ****
2011-10-14 10:09:09,333 INFO () [main] TestLogging - **** Message modified by MyDailyRollingFileAppender ****
Here is an exception
**** Finished modified message ****
java.lang.Exception
at test.TestLogging.main(TestLogging.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
虽然我做了类似的事情,但我使用了稍微不同的方法。我没有编写我想要使用的每种类型的子类,而是创建了一个包装其他对象的子类,并在发送到包装的s之前修改消息。像这样:Appender
Appender
Appender
Appender
package test.logging;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.AppenderAttachable;
import org.apache.log4j.spi.LoggingEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
public class MyAppenderWrapper extends AppenderSkeleton implements AppenderAttachable {
private final List<Appender> appenders = new ArrayList<Appender>();
public void close() {
synchronized (appenders) {
for (Appender appender : appenders) {
appender.close();
}
}
}
public boolean requiresLayout() {
return false;
}
public void addAppender(Appender appender) {
synchronized (appenders) {
appenders.add(appender);
}
}
public Enumeration getAllAppenders() {
return Collections.enumeration(appenders);
}
public Appender getAppender(String name) {
synchronized (appenders) {
for (Appender appender : appenders) {
if (appender.getName().equals(name)) {
return appender;
}
}
}
return null;
}
public boolean isAttached(Appender appender) {
synchronized (appenders) {
for (Appender wrapped : appenders) {
if (wrapped.equals(appender)) {
return true;
}
}
return false;
}
}
public void removeAllAppenders() {
synchronized (appenders) {
appenders.clear();
}
}
public void removeAppender(Appender appender) {
synchronized (appenders) {
for (Iterator<Appender> i = appenders.iterator(); i.hasNext(); ) {
if (i.next().equals(appender)) {
i.remove();
}
}
}
}
public void removeAppender(String name) {
synchronized (appenders) {
for (Iterator<Appender> i = appenders.iterator(); i.hasNext(); ) {
if (i.next().getName().equals(name)) {
i.remove();
}
}
}
}
@Override
protected void append(LoggingEvent event) {
String modifiedMessage = String.format("**** Message modified by MyAppenderWrapper ****\n\n%s\n\n**** Finished modified message ****", event.getMessage());
LoggingEvent modifiedEvent = new LoggingEvent(event.getFQNOfLoggerClass(), event.getLogger(), event.getTimeStamp(), event.getLevel(), modifiedMessage,
event.getThreadName(), event.getThrowableInformation(), event.getNDC(), event.getLocationInformation(),
event.getProperties());
synchronized (appenders) {
for (Appender appender : appenders) {
appender.doAppend(modifiedEvent);
}
}
}
}
您可以像这样配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="StdOut" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p (%x) [%t] %c{1} - %m%n" />
</layout>
</appender>
<appender name="FileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="Append" value="true"/>
<param name="datePattern" value="'.'yyyy-MM-dd"/>
<param name="File" value="mine.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p (%x) [%t] %c{1} - %m%n" />
</layout>
</appender>
<appender name="AppenderWrapper" class="test.logging.MyAppenderWrapper">
<appender-ref ref="StdOut"/>
<appender-ref ref="FileAppender"/>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="AppenderWrapper"/>
</root>
</log4j:configuration>
这样,消息仍会发送到原始追加器,但会与修改后的消息一起发送。