1 log4j
1.1 Log4j简介
使用System.out.println的局限性
无法在不修改代码前提下,控制日志开关
1.2 示例1
- 导入log4j的jar包(log4j-1.2.17.jar)
- Log4jTest
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class Log4jTest {
// 得到一个专属于这个类的日志记录器
private static Logger logger = Logger.getLogger(Log4jTest.class);
public static void main(String[] args) {
// 使用默认的配置信息,不需要log4j.properties
// 该方法就是给rootLogger默认appender值。configure源码如下
// Logger root = Logger.getRootLogger();
// root.addAppender(new ConsoleAppender(new
// PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));
BasicConfigurator.configure();
logger.debug("my first log4j info");
}
}
1.3 Log4J日志级别
1.3.1 代码
- 在src下建立db.properties文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///log4j
username=log4j
password=admin
- Configure:使用不同日志级别打印日志
ackage cd.itcast.log4j;
import java.io.IOException;
import java.util.Properties;
public class Configure {
// 同样,首先得到和这个类绑定的Logger实例
private static Logger log = Logger.getLogger(Configure.class);
public void config() {
log.info("using default db.properties");
config("db.properties");
}
public void config(String resourceName) {
log.info("using config file in classpath:" + resourceName);
try {
Properties prop = new Properties();
prop.load(this.getClass().getClassLoader().getResourceAsStream(resourceName));
log.debug("load properties file success");
for (String key : prop.stringPropertyNames()) {
String value = prop.getProperty(key);
// doSomeConfigWorkUseKeyAndValue(key,value)
log.debug("[properties] " + key + " : " + value);
}
} catch (Exception e) {
log.error("log properties file failed", e);
}
}
}
- LogTest2:客户端,调用debug与info方法
package cd.itcast.log4j;
import org.apache.log4j.BasicConfigurator;
import org.junit.Test;
public class LogTest2 {
public void testLog2(){
BasicConfigurator.configure();
Configure conf=new Configure();
conf.config();
}
public static void main(String[] args) {
new LogTest2().testLog2();
}
}
- 控制台输出
0 [main] INFO cd.itcast.log4j.Configure - using default db.properties
0 [main] INFO cd.itcast.log4j.Configure - using config file in classpath:db.properties
0 [main] DEBUG cd.itcast.log4j.Configure - load properties file success
0 [main] DEBUG cd.itcast.log4j.Configure - [properties] driverClass : com.mysql.jdbc.Driver
0 [main] DEBUG cd.itcast.log4j.Configure - [properties] url : jdbc:mysql:///log4j
0 [main] DEBUG cd.itcast.log4j.Configure - [properties] password : admin
0 [main] DEBUG cd.itcast.log4j.Configure - [properties] username : log4j
- testLog2:客户端,调用error方法
package cd.itcast.log4j;
import org.apache.log4j.BasicConfigurator;
import org.junit.Test;
public class LogTest2 {
@Test
public void testLog2(){
BasicConfigurator.configure();
Configure conf=new Configure();
//故意读一个不存在的日志
conf.config("aa.properties");
}
}
- 控制台输出:既打印error日志,又打印了错误的栈(类似e.printStack()的效果)
0 [main] INFO cd.itcast.log4j.Configure - using config file in classpath:aa.properties
16 [main] ERROR cd.itcast.log4j.Configure - log properties file failed
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at cd.itcast.log4j.Configure.config(Configure.java:20)
- 如果不想打印错误栈信息,在调用Logger.error方法的时候,不要把错误作为第二个参数传入方法即可
//log.error("log properties file failed", e);
log.error("log properties file failed");
1.3.2 扩展
- 日志级别顺序
debug<info<warn<error<fatal<off
- 日志级别作用
package cd.itcast.log4j;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.Test;
public class LogTest2 {
@Test
public void testLog2(){
BasicConfigurator.configure();
//设置根日志的日志级别为Level.INFO,即只有Level.INFO及其以上级别的日志生效
//默认情况下,rootLogger的日志级别被设置为了Level.DEBUG
Logger.getRootLogger().setLevel(Level.INFO);
Configure conf=new Configure();
conf.config();
}
}
- 控制台输出:debug级别的日志被屏蔽
0 [main] INFO cd.itcast.log4j.Configure - using default db.properties
0 [main] INFO cd.itcast.log4j.Configure - using config file in classpath:db.properties
- 日志记录器(Logger)的层次结构
//1. 此代码真正含义为,创建了一个名为cd.itcast.log4j.Configure的日志记录器(Logger)实例,这个实例的根Logger就是在LogTest2中得到的rootLogger()
//2. 我们并没有在cd.itcast.log4j.Configure绑定的Logger上设置日志级别
//3. 他会去找他的父Logger的Level,如果没有继续向上找,直到找到rootLogger的Level,rootLogger必须设置Level,如果中途找到了设置了Level的父Logger,则使用该Logger的Level,且不再继续向上查找
//4. 因此打印出来就只有大于或等于INFO的日志级别信息了
private static Logger log = Logger.getLogger(Configure.class);
1.4 Log4J控制不同包下的类的日志级别也不同
1.4.1 代码
- LogicProcessor:与Configure放在不同包下
package cd.itcast.core;
import org.apache.log4j.Logger;
import cd.itcast.log4j.Configure;
public class LogicProcessor {
private static Logger log=Logger.getLogger(LogicProcessor.class);
public void init(Configure conf){
log.info("init logic processor using conf");
}
public void process(){
log.info("process some logic");
log.debug("process some detail logic");
}
}
- LogTest3:与LogicProcessor同包
package cd.itcast.log4j;
import org.apache.log4j.BasicConfigurator;
import org.junit.Test;
import cd.itcast.core.LogicProcessor;
public class LogTest3 {
@Test
public void testLog(){
BasicConfigurator.configure();
Configure conf=new Configure();
conf.config();
LogicProcessor processor=new LogicProcessor();
processor.init(conf);
processor.process();
}
}
- 控制台输出:发现两个类中的日志都输出了
0 [main] INFO cd.itcast.log4j.Configure - using default db.properties
0 [main] INFO cd.itcast.log4j.Configure - using config file in classpath:db.properties
15 [main] DEBUG cd.itcast.log4j.Configure - load properties file success
31 [main] DEBUG cd.itcast.log4j.Configure - [properties] driverClass : com.mysql.jdbc.Driver
31 [main] DEBUG cd.itcast.log4j.Configure - [properties] url : jdbc:mysql:///log4j
31 [main] DEBUG cd.itcast.log4j.Configure - [properties] password : admin
31 [main] DEBUG cd.itcast.log4j.Configure - [properties] username : log4j
31 [main] INFO cd.itcast.core.LogicProcessor - init logic processor using conf
31 [main] INFO cd.itcast.core.LogicProcessor - process some logic
31 [main] DEBUG cd.itcast.core.LogicProcessor - process some detail logic
- 想cd.itcast.log.Configure做WARN级别之上的日志的输出,cd.itcast.core.LogicProcessor做DEBUG级别之上的日志输出
- 设置rootLogger日志级别为DEBUG;设置cd.itcast.log4j.Configure日志级别为WARN。
- 设置rootLogger日志级别为WARN;设置cd.itcast.core.LogicProcessor日志级别为DEBUG。
- LogTest3:第二种方法的具体实现
import org.junit.Test;
import cd.itcast.core.LogicProcessor;
public class LogTest3 {
@Test
public void testLog(){
BasicConfigurator.configure();
//rootLogger体系结构中的cd.itcast.log.Configure和cd.itcast.core.LogicProcessor默认日志级别都变成了WARN
Logger.getRootLogger().setLevel(Level.WARN);
//或者可以使用如下代码,表示将cd.itcast包下所有的类的日志级别改为Level.WARN,因为当我们绑定cd.itcast.core.LogicProcessor对应的Logger的时候,实际上隐式的绑定了cd、cd.itcast、cd.itcast.core这三个Logger
//Logger.getLogger("cd.itcast").setLevel(Level.WARN);
//通过Logger.getLogger(“cd.itcast.core.LogicProcessor”)得到的Logger实例和我们在LogicProcessor类中使用Logger.getLogger(LogicProcessor.class)得到的Logger实例是一个实例
//即在一个rootLogger体系结构中,绑定到同一个名字的Logger实例只会有一份
Logger.getLogger("cd.itcast.core.LogicProcessor").setLevel(Level.DEBUG);
Configure conf=new Configure();
conf.config();
LogicProcessor processor=new LogicProcessor();
processor.init(conf);
processor.process();
}
}
- 控制台输出
0 [main] INFO cd.itcast.core.LogicProcessor - init logic processor using conf
0 [main] INFO cd.itcast.core.LogicProcessor - process some logic
0 [main] DEBUG cd.itcast.core.LogicProcessor - process some detail logic
1.5 Log4j体系结构
1.5.1 log4j三要素
- Logger:日志记录器
- Appender:什么地方
- Layout:什么格式
1.5.2 Logger的结构
1.5.2.1 创建Logger的本质
- Log4jEquals:
package cd.itcast.log4j;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class Log4jEquals {
public static void main(String[] args) {
BasicConfigurator.configure();
Logger log1=Logger.getLogger("Log4jEquals");
Logger log2=Logger.getLogger("Log4jEquals");
//当我们说把一个日志记录器绑定在一个类上,这种说法是不准确的,正确的说,我们仅仅是使用给定的类的全限定名为Logger取了一个名字
Logger log3=Logger.getLogger(Log4jEquals.class);
Logger log4=Logger.getLogger("cd.itcast.log4j.Log4jEquals");
log1.info(log1==log2);
//log2使用的不是全限定名,所以对象不相等
log1.info(log2==log3);
log1.info(log3==log4);
}
}
- 控制台输出
0 [main] INFO Log4jEquals - true
0 [main] INFO Log4jEquals - false
0 [main] INFO Log4jEquals - true
1.5.2.2 Logger的创建顺序及父子关系
//1. Logger的层次结构是按照Logger的名字来创建的,log1是log2的父Logger,log2为log3的父Logger
//2. 执行代码Logger.getLogger("cd.itcast.log")时,Log4J仅仅为我们创建了名为cd.itcast.log这个Logger,而不会自动创建其父Logger(即名为"cd.itcast"的Logger)
//3. 执行代码Logget.getLogger("cd.itcast")时,Log4J才会为我们创建名为"cd.itcast"这个Logger
//4. Log4J会自动的去寻找"cd.itcast"这个Logger的上下级关系,并自动的把这个新创建的Logger添加到已有的Logger结构体系中。
Logger log1=Logger.getLogger(“cd”);
Logger log2=Logger.getLogger(“cd.itcast”);
Logger log3=Logger.getLogger(“cd.itcast.log”);
1.5.2.3 rootLogger的特点
- rootLogger是没有名字的
- rootLogger是自动存在的
- rootLogger必须设置Level等级:默认值为Level.DEBUG
- rootLogger没有名字,所以无法像其他的类一样,可以通过Logger.getLogger(String)得到,他只能通过Logger.getRootLogger方法得到
1.5.2.4 Logger中方法
public class Logger {
// 输出日志方法:
public void debug(Object message);
public void info(Object message);
public void warn(Object message);
public void error(Object message);
public void fatal(Object message);
// 输出带有错误r日志级别为DEBUG的日志方法:
public void debug(Object message, Throwable t);
public void info(Object message, Throwable t);
public void warn(Object message, Throwable t);
public void error(Object message, Throwable t);
public void fatal(Object message, Throwable t);
// 更通用的输出日志方法:
public void log(Level p, Object message);
}
1.5.2.5 setThreshold限制日志输出:与setLevel方法的功能类似
- testLogLevel2
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
public class testLogLevel2 {
public static void main(String[] args) {
//1. 系统先找最近的设置了Level的父Logger对应的Level等级,再找最近的设置了Threshold的父Logger对应的Threshold等级,哪个等级高以哪个为准
BasicConfigurator.configure();
Logger logger = Logger.getLogger("cd.itcast");
//2. 使用logger.getLoggerRepository得到Logger栈,即从当前Logger开始其下的所有的子Logger。然后,我们设置了这个栈的日志门槛(Threshold),换句话说就是最低日志输出级别为INFO
logger.getLoggerRepository().setThreshold(Level.INFO);
logger.setLevel(Level.INFO);
Logger midLogger = Logger.getLogger("cd.itcast.log");
midLogger.getLoggerRepository().setThreshold(Level.DEBUG);
//3. midLogger最近设置了Level的父Logger为"cd.itcast",等级为INFO,其最近设置了Threshold的父Logger为"cd.itcast.log",等级为DEBUG,INFO>DEBUG,所以此时日志等级为INFO,所以只能打出info
midLogger.debug("debug");
midLogger.info("info");
}
}
- 控制台输出
0 [main] INFO cd.itcast.log - info
1.5.3 Appender的结构
Appender定义了日志输出的目的地
- testLogAppender1
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
public class testLogAppender1 {
public static void main(String[] args) {
Logger log1=Logger.getLogger("cd");
log1.setLevel(Level.DEBUG);
//1. 把日志输出到控制台上的Appender,在创建ConsoleAppender的时候,需传入表示日志格式的类SimpleLayout(最简单的格式)的实例
log1.addAppender(new ConsoleAppender(new SimpleLayout()));
Logger log2=Logger.getLogger("cd.itcast.log");
//2. log2为log1的子Logger,它拥有log1的Appender,说明Appender与Level相同,拥有继承性
log2.info("log2 info");
log2.debug("log2 debug");
}
}
- 控制台输出
INFO - log2 info
DEBUG - log2 debug
- testLogAppender1:改写
//在main方法最开始添加如下代码
BasicConfigurator.configure();
- 控制台输出:Logger会继承其所有父Logger上的Appender,不止一个
//继承"cd"这个Logger的Appender
INFO - log2 info
//继承rootLogger的Appender
0 [main] INFO cd.itcast.log - log2 info
//同上
DEBUG - log2 debug
0 [main] DEBUG cd.itcast.log - log2 debug
- testLogAppender2:setAdditivity(false)方法使该Logger的子Logger停止追加它以及它所有父Logger上的Appender
import java.io.IOException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
public class testLogAppender2 {
public static void main(String[] args) throws IOException {
BasicConfigurator.configure();
Logger log1=Logger.getLogger("cd");
log1.setAdditivity(false);
log1.addAppender(new ConsoleAppender(new SimpleLayout()));
Logger log2=Logger.getLogger("cd.itcast");
log2.addAppender(new FileAppender(new SimpleLayout(),"a0.log"));
Logger log3=Logger.getLogger("cd.itcast.log");
log3.info("log2 info");
}
}
- 运行测试,结果:
//log2对应的a0.log文件中仍会打印,但rootLogger为log1的父Logger,所以其对应的控制台,就不会再打印了
INFO - log2 info
1.5.4 Layout的结构
创建Appender对象时需要传入Layout对象,它规定了日志格式
- testPatternLayout:PatternLayout使用标准的输出格式来指定格式化日志消息的样式
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class testPatternLayout {
public static void main(String[] args) {
Logger log=Logger.getLogger("cd");
//先定义了一个格式化日志的模式
//%r代表从Log4j启动到运行这条日志的时间差,单位为毫秒
//%t代表运行该日志的线程名称(main,thread-1)不是类名
//%-5p,首先-5代表这个字符总占用5个位置,p代表日志输出级别
//%c代表输出日志的Logger的名字
//%m代表输出的日志内容
//%n代表分行
String pattern="%r [%t] %-5p %c - %m%n";
log.addAppender(new ConsoleAppender(new PatternLayout(pattern)));
Logger log2=Logger.getLogger("cd.itcast.log");
log2.info("log2 info");
}
}
- 控制台输出
0 [main] INFO cd.itcast.log - log2 info
1.6 Log4j配置文件详解
1.6.1 .properties配置文件
#配置rootLogger
#Level:debug
#Appender:三个,名分别为stdout、D、E,即rootLogger打印时,在这三个位置都会打印
#Logger.getRootLogger().setLevel(Level.DEBUG);
#Logger.getRootLogger().addAppender();
log4j.rootLogger = debug , stdout , D , E
#配置名为"cd.itcast.log4j"的Logger
#Level:debug
#Appender:D
#Logger.getLogger("cd.itcast.log4j").setLevel(Level.DEBUG);
#Logger.getLogger("cd.itcast.log4j").addAppender();
log4j.logger.cd.itcast.log4j = debug , D
#关闭名为"cd.itcast.log4j"的Logger的Appender的追加性
#Logger.getLogger("cd.itcast.log4j").setAdditivity(false)
log4j.additivity.cd.itcast.log4j = false
#对名为"stdout"的Appender进行配置
#其Appender具体类为ConsoleAppender,即该Appender会被打印到控制台
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
#对名为"D"的Appender进行配置
#其Appender具体类为DailyRollingFileAppender,即该Appender会被打印到指定文件,且该文件可以自动滚动
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#日志打印到logs/log.log文件中
#也可以使用相对路径,为相对项目所在路径:D:\workspace\log4j1.2.17_test
#log4j.appender.D.File = logs/log.log会在D:\workspace\log4j1.2.17_test/logs/log.log建立日志
log4j.appender.D.File = D://logs/log.log
#默认值为true,表示追加,false表示覆盖原日志
log4j.appender.D.Append = true
#设置threshold
log4j.appender.D.Threshold = DEBUG
#设定Layout
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
#对名为"E"的Appender进行配置
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = D://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
1.6.2 Appender具体实现类
- org.apache.log4j.ConsoleAppender:控制台
- org.apache.log4j.FileAppender:文件
- org.apache.log4j.DailyRollingFileAppender:每天产生一个日志文件
- org.apache.log4j.RollingFileAppender:文件大小到达指定尺寸的时候产生一个新的文件
- org.apache.log4j.WriterAppender:将日志信息以流格式发送到任意指定的地方
1.6.3 Layout具体实现类
- org.apache.log4j.HTMLLayout:以HTML表格形式布局
- org.apache.log4j.PatternLayout:可以灵活地指定布局模式
- org.apache.log4j.SimpleLayout:包含日志信息的级别和信息字符串
- org.apache.log4j.TTCCLayout:包含日志产生的时间、线程、类别等等信息
1.6.4 Layout具体实现类log4j.appender.E.layout.ConversionPattern后的特殊字符详解
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},输出类似:2002年10月18日 22 : 10 : 28 , 921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java: 10 )
1.6.5 代码中初始化rootLogger的方式
//默认情况是先读取src同级的log4j.xml文件,如果获取不到则获取src内的log4j.properties文件
//在程序中调用BasicConfigurator.configure()方法:给根记录器增加一个ConsoleAppender,输出格式通过PatternLayout设为"%-4r [%t] %-5p %c %x - %m%n",还有根记录器的默认级别是Level.DEBUG.
BasicConfigurator.configure();
//读取使用Java的特性文件编写的配置文件
PropertyConfigurator.configure("D:/Code/conf/log4j.properties");
//读取指定XML形式的配置文件
DOMConfigurator.configure ( String filename )
1.6.6 .xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender class="org.apache.log4j.RollingFileAppender" name="zjjklog">
<param name="maxFileSize" value="10000KB" />
<param name="Threshold" value="ALL" />
<param name="maxBackupIndex" value="5" />
<param value="${fc.log.dir}/logs/fcrjdebug/zjjklog.txt" name="File" />
<layout class="org.apache.log4j.PatternLayout">
<param value="[${service.id}] %d %m%n" name="ConversionPattern" />
</layout>
</appender>
<appender class="org.apache.log4j.DailyRollingFileAppender"
name="fcrjtflog">
<param value="'.'yyyy-MM-dd-HH" name="DatePattern" />
<param name="Threshold" value="ALL" />
<param value="${fc.log.dir}/logs/fcrjdebug/fcrjtflog.txt" name="File" />
<layout class="org.apache.log4j.PatternLayout">
<param value="[${service.id}]%d %t %p [%c] %m%n" name="ConversionPattern" />
</layout>
</appender>
<appender class="org.apache.log4j.RollingFileAppender" name="fcrjdebuglog">
<param name="maxFileSize" value="10000KB" />
<param name="Threshold" value="ERROR" />
<param name="maxBackupIndex" value="5" />
<param value="${fc.log.dir}/logs/fcrjdebug/fcrjdebuglog.txt"
name="File" />
<layout class="org.apache.log4j.PatternLayout">
<param value="[${service.id}]%d %t %p [%c] %F Line:[%L] %m%n"
name="ConversionPattern" />
</layout>
</appender>
<!-- category为logger的子类,现在已经不常使用,下面的category都可以用logger代替 -->
<!-- Logger.getLogger("com.iflex.fcr").addAppender(); -->
<category name="com.iflex.fcr">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="1_BATCH_com.iflex.fcr" additivity="true">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="1_com.iflex.fcr.alert" additivity="true">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="mowaudit">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="apiauditforjson">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="org.apache.axis">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="OUTBOUND_CALL_ADAPTER">
<appender-ref ref="fcrjdebuglog" />
</category>
<category name="1_com.tf">
<appender-ref ref="fcrjtflog" />
</category>
<category name="1_zjjk">
<appender-ref ref="zjjklog" />
<appender-ref ref="console" />
</category>
<category name="1_BATCH_zjjk">
<appender-ref ref="zjjklog" />
<appender-ref ref="console" />
</category>
<category name="1_BATCH_com.tf">
<appender-ref ref="fcrjtflog" />
</category>
<logger additivity="false" name="PerfLogger">
<appender-ref ref="fcrjdebuglog" />
</logger>
<logger name="org.eclipse.persistence">
<level value="DEBUG" />
</logger>
<root>
<priority value="OFF"></priority>
<appender-ref ref="fcrjlog" />
</root>
</log4j:configuration>