log4j
log4j是之前最流行的日志输出系统,目前尽管有了log4j2和其他日志输出系统。但log4j 里面的概念还是保留了。
先看个例子:
这里我使用的是 slf4 => log4j,依赖:
dependencies {
compile "org.slf4j:slf4j-api:1.7.30"
compile "org.slf4j:slf4j-log4j12:1.7.30" // 适配到 log4j
compile "log4j:log4j:1.2.17"
}
打印日志时,只需要:
private Logger logger = LoggerFactory.getLogger(XXX.class);
// 注意是 slf4j的 org.slf4j.Logger
概念
Logger
输出日志之前都要获取一个Logger。一个 Logger 被当作为一个实体。而且Logger是有层级关系的,跟包名的层级是一致的。
比如,名为com.hust 的Logger 的父级是 名为 com 的Logger。而且会自动关联。而且向上最高层是root logger。
等级
Logger 能够被分成不同的等级(TRACE, DEBUG, INFO, WARN, ERROR)。对于一个给定的名为 L 的 logger,它的有效层级为从自身一直回溯到 root logger,直到找到第一个不为空的层级作为自己的层级。
为了确保所有的 logger 都有一个层级,root logger 会有一个默认层级 --- DEBUG。root logger 默认等级是DEBUG。
这样所有的logger都会有一个等级。
打印规则
日志的打印级别为 p,Logger 实例的级别为 q,如果 p >= q,则该条日志可以打印出来。
日志的打印级别为 p,Logger 实例的级别为 q,如果 p >= q,则该条日志可以打印出来
TRACE < DEBUG < INFO < WARN < ERROR。
Appender
输出目的地叫做 appender。appender 包括console、file、remote socket server、MySQL、PostgreSQL、Oracle 或者其它的数据库、JMS、remote UNIX Syslog daemons 中。
这样可以指定的把日志输出到不同的地方。
另外,logger L 的日志输出语句会遍历 L 和它的子级中所有的 appender。这就是所谓的 appender 叠加性(appender additivity)。
因此,对于Logger L
设置 additivity = true,logger L的appender 就是 自己的appender 叠加其父级的appender;
设置 additivity = fasle,L的appender 只有自己指定的appender。L的子层级也无法继承L的appender。
值得注意的是:如果 L 指定了appender,同时父层级也有同样的appender,会当成两个appender处理,即会输出两遍。
常用的appender有:
ConsoleAppender: 输出到控制台;
FileAppender:输出到文件;
RollingFileAppender:输出到文件,文件达到一定阈值时,自动备份日志文件;
DailyRollingFileAppender:可定期备份日志文件,默认一天一个文件,也可设置为每分钟一个、每小时一个;
WriterAppender:可自定义日志输出位置。
PatternLayout
也就是日志的格式化输出。利用PatternLayout定义日志输出格式,附带把输出日志的环境信息带上,增加日志的可读性。
%n - 换行
%m - 日志内容
%p - 日志级别(FATAL,ERROR,WARN,INFO,DEBUG)
%r - 程序启动到现在的毫秒数
%t - 当前线程名
%d - 日期和时间, 一般使用格式 %d{yyyy-MM-dd HH:mm:ss, SSS}
%l - 输出日志事件的发生位置, 同 %F%L%C%M
%F - java 源文件名
%L - java 源码行数
%C - java 类名,%C{1} 输出最后一个元素
%M - java 方法名
配置
log4j配置
log4j.xml 最基本的结构为 <log4j:configuration> 元素,包含 0 或多个 <appender> 元素,其后跟 0 或多个 <logger> 元素,其后再跟最多只能存在一个的 <root> 元素。
一个比较全的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<!-- 将日志信息输出到控制台 -->
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<!-- 设置日志输出的样式 -->
<layout class="org.apache.log4j.PatternLayout">
<!-- 设置日志输出的格式 -->
<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%t] [%-5p] [method:%l] %m%n"/>
</layout>
<!--过滤器设置输出的级别-->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<!-- 设置日志输出的最小级别 -->
<param name="levelMin" value="INFO"/>
<!-- 设置日志输出的最大级别 -->
<param name="levelMax" value="ERROR"/>
<!-- 设置日志输出的xxx,默认是false -->
<param name="AcceptOnMatch" value="true"/>
</filter>
</appender>
<!-- 单独过滤并输出 ERROR 日志到 error.log 文件 -->
<appender name="ERROR" class="org.apache.log4j.FileAppender">
<!-- 输出文件全路径名-->
<param name="File" value="/Users/zhangwei/note/error.log"/>