使用log4j 2基本只需导入两个jar包:
log4j-core-xx.jar log4j-api-xx.jar
log4j 2.0与以往的1.x有一个明显的不同,其配置文件只能采用.xml, .json或者 .jsn。在默认情况下,系统选择configuration文件的优先级如下:(classpath为scr文件夹)
1.classpath下名为 log4j-test.json 或者log4j-test.jsn文件
2.classpath下名为 log4j2-test.xml
3.classpath下名为 log4j.json 或者 log4j.jsn文件
4.classpath下名为 log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- status=debug 可以查看log4j的装配过程 --> <Configuration status="off" monitorInterval="1800"> <properties> <property name="LOG_HOME">logs/sample</property> <property name="FILE_NAME">mylog</property> </properties> <Appenders> <!-- 定义控制台输出 --> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </Console> <RollingRandomAccessFile name="running-log" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/ $${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" /> <Policies> <!-- 每天生成一个日志文件 --> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!-- 每到10M生成一个日志文件 --> <SizeBasedTriggeringPolicy size="10 MB" /> </Policies> <!-- 最大保存文件数 --> <DefaultRolloverStrategy max="20" /> </RollingRandomAccessFile> <!-- 文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,--> <!-- 这个也挺有用的,适合临时测试用 --> <File name="log" fileName="log/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入 --> <!-- 按年份-月份建立的文件夹下面并进行压缩,作为存档 --> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="50MB"/> </RollingFile> </Appenders> <Loggers> <Logger name="com.cnblogs.yjmyzz.App2" level="trace" additivity="true"> <AppenderRef ref="running-log" /> </Logger> <Root level="error"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>解释一下:
5-8行定义了一些属性(可以根据需要自己随便添加),主要是为了后面引用起来方便。
16行 RollingRandomAccessFile 即表示以文件方式记录,注意一下filePattern的设置,它与24行的SizeBasedTriggeringPolicy(表示单个文件最大多少容量)结合在一起,非常有用,以这段配置为例,当单个文件达到10M后,会自动将以前的内容,先创建类似 2014-09(年-月)的目录,然后按 "xxx-年-月-日-序号"命名,打成压缩包。
27行的DefaultRolloverStrategy max="20"表示压缩包,最多保留20个。
45-48行,定义了一个新logger,它的级别是trace,使用文件方式来记录日志,additivity="true"这里注意一下,因为下面还有一个root logger,任何其它的logger最终都相当于继承自root logger,所以“com.cnblogs.yjmyzz.App2”这个logger中,如果记录了error及以上级别的日志,除了文件里会记录外,root logger也会生效,即:控制台也会输出一次。如果把additivity="true" 中的true,改成false,root logger就不会再起作用,即只会记录在文件里,控制台无输出。
TimeBasedTriggeringPolicy 基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:
interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟
modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00,。。。
loggers标签,用于定义logger的lever和所采用的appender,其中appender-ref必须为先前定义的appenders的名称,例如,此处为Console。那么log就会以appender所定义的输出格式来输出log。
root标签为log的默认输出形式,如果一个类的log没有在loggers中明确指定其输出lever与格式,那么就会采用root中定义的格式。
Appenders标签,其实就是输出,有各种扩展组件,主要类型有:
ConsoleAppender 输出结果到控制台
FileAppender 输出结果到指定文件
RollingFileAppender 同样输出结果到文件,区别是用一个buffer,因此速度会快点
另外关于logger的命名,很有讲究的,这里我们命名为com.cnblogs.yjmyzz.App2,如果正好有这样一个类:
package com.cnblogs.yjmyzz;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App2 {
static Logger logger = LogManager.getLogger();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
logger.trace("trace message " + i);
logger.debug("debug message " + i);
logger.info("info message " + i);
logger.warn("warn message " + i);
logger.error("error message " + i);
logger.fatal("fatal message " + i);
}
System.out.println("Hello World! 2");
}
}
log4j2是根据名称来用哪个logger的,第8行没有传任何参数,默认这个logger的name就是当前类的全称,即 com.cnblogs.yjmyzz.App2,这样就跟配置对应上了,所以刚才配置中的 nam="com.cnblogs.yjmyzz.App2"的logger,相当于只对App2这一个类起作用。
一个实用的配置文件:
1)我正在调试某个类,所以,我不想让其他的类或者包的日志输出,否则会很多内容,所以,你可以修改上面root的级别为最高(或者谨慎起见就用ERROR),然后,加一个针对该类的logger配置,给appender-ref定义那个File appender,这个appender的好处是有一个append为false的属性,这样,每次运行都会清空上次的日志,这样就不会因为一直在调试而增加这个文件的内容,查起来也方便,这个和输出到控制台就一个效果了。
2)我已经基本上部署好程序了,然后我要长时间运行了。我需要记录下面几种日志,第一,控制台输出所有的error级别以上的信息。第二,我要有一个文件输出是所有的debug或者info以上的信息,类似做程序记录什么的。第三,我要单独为ERROR以上的信息输出到单独的文件,如果出了错,只查这个配置文件就好了,不会去处理太多的日志,怎么做呢?
>首先,在appenders下面加一个Console类型的appender,通过加一个ThresholdFilter设置level为error。(直接在配置文件的Console这个appender中修改)
>其次,增加一个File类型的appender(也可以是RollingFile或者其他文件输出类型),然后通过设置ThresholdFilter的level为error。
这里可以添加一个appender,内容如下:
<File name="ERROR" fileName="logs/error.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> </File>并在loggers中的某个logger(如root)中引用(root节点加入这一行作为子节点)。
<appender-ref ref="ERROR" />
>然后,增加一个RollingFile的appender,设置基本上同上面的那个配置文件。
>最后,在logger中进行相应的配置。不过如果你的logger中也有日志级别的配置,如果级别都在error以上,你的appender里面也就不会输出erro以下的信息了。
可能存在的问题:在Eclipse下一切运行正常,如果把应用打包成jar包发布后,cmd命令行模式下,即使Console开着的情况下,也没法输出,文件输出也没有任何日志。
问题解决方案:需要在MANIFEST.MF文件里Class-Path 最前加个'.',目的是让与jar包平级的配置文件log4j2.xml加载进来。
有时候,为了使同一份log4j文件要支持写到不同的log中,需要在载入的时候对内容进行动态修改,比如根据server id分别生成game1.log,game2.log
可以代码进行加载log4文件
File file = new File("log4j2.xml");
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
final ConfigurationSource source = new ConfigurationSource();
source.setInputStream(in);
Configurator.initialize(null, source);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
官方建议一般程序员查看的日志改成异步方式,一些运营日志改成同步
Asynchronous Appenders 和 Asynchronous Loggers 区别:在</appenders> 节点里添加
<Async name="Async">
<AppenderRef ref="MyFile"/>
</Async>
Asynchronous Appenders 性能比同步快,比Asynchronous Loggers慢
在loggers节点添加
<AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true"> <AppenderRef ref="RandomAccessFile"/> </AsyncLogger>或者添加
<!-- Root Logger --> <asyncRoot level="DEBUG"> <appender-ref ref="DevLog" /> <appender-ref ref="Console" /> </asyncRoot>因为logger async 用的是无锁并发技术,必须引入Disruptor
测试下,单线程异步比同步效率提高了1倍。线程越多性能提高越明显。
如果要加上位置信息比如哪个类,第几行,需要设置 includeLocation="true" 但默认不设置好像也是true。
log4j2的按天分日志文件
<RollingFile name="error_appender" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd}.log"> <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/> <Policies> <TimeBasedTriggeringPolicy modulate="true" interval="1"/> </Policies> </RollingFile>
按大小分日志文件
<RollingFile name="error_appender" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/> <SizeBasedTriggeringPolicy size="100 MB" /> </RollingFile>
按分钟分日志文件
<RollingRandomAccessFile name="_1min_appender" fileName="${MINUTE_HOME}/minute" filePattern="${MINUTE_HOME}/minute-%d{yyyy-MM-dd-HH-mm}.log"> <PatternLayout pattern="%m%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true" /> </Policies> </RollingRandomAccessFile>
关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval,日期格式精确到哪一位,interval也精确到哪一个单位
log4j2 设置同一类型日志文件个数
<Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%-5p] %d %c - %m%n" /> </Console> <File name="File" fileName="dist/my.log"> <PatternLayout pattern="%m%n" /> </File> <RollingFile name="RollingFile" fileName="dist/my2.log" filePattern="dist/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="[%-5p] %d %c - %m%n" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="25 KB" /> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders>
关键在于 <DefaultRolloverStrategy max="20"/>,如果不做配置,默认是7,这个7指的是上面i的最大值,超过了就会覆盖之前的
http://www.cnblogs.com/yjmyzz/p/3988114.html
http://www.cnblogs.com/leo-lsw/p/log4j2tutorial.html
http://my.oschina.net/xldc/blog/384560#navbar-header
http://blog.csdn.net/zhang168/article/details/46814489