一个成熟的项目,日志系统是必不可少的。当前流行的框架有 log4j
, logback
,它们都是基于 slf4j
日志规范/接口 开发。本文就来介绍一下 Log4j 。
认识 Log4J
日志架构
Log4j API 采用分层架构,每一层有不同的对象,完成不同的任务。这种分层架构让设计变得灵活,且易于日后扩展。
核心对象★
涉及一览 | 说明 |
---|---|
Logger |
负责获取日志信息,并存储于一个分层的命名空间之中。 |
Layout |
负责格式化日志信息的对象,在发布日志信息之前,它为 appender 对象提供支持。 |
Appender |
负责将日志信息输出到不同目的地,比如数据库、文件、控制台、Unix Syslog 等。 |
Logger
该对象位于分层架构中的最上层,负责获取日志信息,并存储于一个分层的命名空间之中。
对象获取
Logger 类不允许初始化一个新的实例,但提供了三个静态方法用来获取 Logger 对象:
实际上是从
LogManager
的Logger工厂中 获取 / 设置 和参数同名的Logger对象。
1 | /** 获得根日志对象*/ |
日志对象继承 & 日志对象名
可以通过Logger对象来触发打印日志。
Logger具有 父子/继承关系
,且所有日志对象都是RootLogger的子对象。子logger会继承父logger的appender等,触发打印后会从子类向上依次调用appender。
1 | # 设置两个日志对象,日志对象名为com.ibatis和com.ibatis.common.jdbc.SimpleDataSource |
Logger对象的继承关系是通过 日志对象名 来管理的。
除了以上在获取Logger对象的同时设置日志对象名外,还可以在
log4j.properties
设置并细化配置
1 | # 自定义一个日志对象,日志对象名为securityLog |
日志信息级别
一旦获取一个有名字的 logger 实例,就可以使用如下方法用于打印日志信息。
注意 :日志信息不一定会被输出,其会被日志对象(及其父logger)的最低日志级别 过滤
并且还需要对应的appender,才能输出到指定位置。
优先级 | 方法和描述 |
---|---|
1 | public void fatal(Object message) 使用 Level.FATAL 级别打印日志。 |
2 | public void error(Object message) 使用 Level.ERROR 级别打印日志。 |
3 | public void warn(Object message) 使用 Level.WARN 级别打印日志。 |
4 | public void info(Object message) 使用 Level.INFO 级别打印日志。 |
5 | public void debug(Object message) 使用 Level.DEBUG 级别打印日志。 |
6 | public void trace(Object message) 使用 Level.TRACE 级别打印日志。 |
最低日志级别
可以设置Logger对象打印日志信息的最低级别,只有大于或等于该级别的信息才会被输出
例如以下配置中:
com.ibatis.common.jdbc.SimpleDataSource
日志对象会无法输出日志,而com.ibatis.Demo
日志对象可以使用根日志对象的appender(CONSOLE)将日志信息输出到控制台。
1 | # 设置根日志对象最低日志级别为INFO,并设置一个appender(CONSOLE) |
1 | //最低日志级别也可以在java中设置 |
Layout
负责格式化日志信息的对象,在发布日志信息之前,它为 appender 对象提供支持。
所有 Layout
对象从 Appender
对象那里接收一个 LoggingEvent
对象,然后从 LoggingEvent
对象那里获取信息,并使用恰当的 ObjectRenderer
对象获取该信息的字符串形式。
位于继承关系顶层的是抽象类
org.apache.Log4j.Layout
,这是所有 Log4j API 中Layout
类的基类。
在应用中我们从不直接使用该类,而是使用它的子类,如下所示:
其中最常用的是
PatternLayout
, 本wiki主要主要针对其进行讲解。
- DateLayout
- HTMLLayout
- PatternLayout
- SimpleLayout
- XMLLayout
Appender
该对象位于分层架构中的较低一层,负责将日志信息输出到不同目的地,比如数据库、文件、控制台、Unix Syslog 等。
支持对象☆
这些是框架的可选对象,它们支持核心对象做一些额外的任务,同样在框架中发挥着重要作用。
Level
Level 对象定义了日志信息的粒度和优先级。
org.apache.Log4j.Level
类定义了日志级别,您可通过继承Level
类定制自己的级别。
级别(优先级:desc) | 描述 |
---|---|
OFF |
最高级别,用于关闭日志。 |
FATAL |
指明非常严重的错误事件,可能会导致应用终止执行。 |
ERROR |
指明错误事件,但应用可能还能继续运行。 |
WARN |
指明潜在的有害状况。 |
INFO |
指明描述信息,从粗粒度上描述了应用运行过程。 |
DEBUG |
指明细致的事件信息,对调试应用最有用。 |
TRACE |
比 DEBUG 级别的粒度更细。 |
ALL |
所有级别,包括定制级别。 |
Filter
Filter 对象用来分析日志信息,进而决定该条日志是否被记录。
一个 Appender 对象可对应多个 Filter 对象,当日志信息传给 Appender 对象时,与其关联的所有 Filter 对象需要判断是否将日志信息发布到目的地。
ObjectRenderer
ObjectRenderer 对象负责为传入日志框架的不同对象提供字符串形式的表示,Layout 对象使用该对象来准备最终的日志信息。
LogManager
LogManager 对象管理日志框架,它负责从系统级的配置文件或类中读取初始配置参数。
使用 Log4j
单纯的使用只需要 slf4j-api
, log4j
; 一些项目需要 slf4j-log4j12
(如: MyBatis
)。
1 | <!-- log (slf4j, log4j, slf4j-log4j整合)--> |
log4j.properties
默认情况下, LogManager
会在 classpath
中寻找 log4j.properties
文件。
以下是较为详细的配置示例,模式转换字符请参考:附录:PatternLayout
1 | # 设置根日志,最低日志级别为INFO,并添加了2个appender(CONSOLE,log_error)确定输出详情 |
*.java
获取日志对象,设置日志信息。
控制台 / 文件 输出日志
控制台输出:
[INFO] 2017-01-17 17:01:17 [org.Demo] - 用户**访问了***
1 | package org.Demo; |
数据库 输出日志
JDBCAppender.java
继承org.apache.Log4j.jdbc.JDBCAppender直接获得数据库相关信息,不需要单独配置
1 | public class LogJdbcAppender extends JDBCAppender { |
调用
控制台/文件输出:
[INFO] 2017-01-17 17:01:17 [org.Demo] - 用户**访问了***
数据库表
VISIT_LOG
插入了values
记录。
1 | package org.Demo; |
附录
PatternLayout
PatternLayout
是一个简单的 Layout
对象,提供了如下属性,该属性可通过配置文件更改:
序号 | 属性 & 描述 |
---|---|
1 | conversionPattern设置转换模式,默认为 %r [%t] %p %c %x - %m%n。 |
模式转换字符
下面的表格解释了上面模式中用到的字符,以及所有定制模式时能用到的字符:
转换字符 | 含义 |
---|---|
c |
输出日志对象名,一般为发起记录日志请求类的全名/自设置的日志对象名。比如对于类 org.apache.xyz.SomeClass ,模式 %C{1} 会输出 SomeClass 。也有可能是自定义日志对象名,比如 log4j.logger.securityLog = INFO 为 securityLog 。 |
d |
输出记录日志的日期,比如 %d{HH:mm:ss,SSS} 或 %d{dd MMM yyyy HH:mm:ss,SSS} 。 |
F |
在记录日志时,使用它输出文件名。 |
l |
输出生成日志的调用者的地域信息。 |
L |
输出发起日志请求的行号。 |
m |
输出和日志事件关联的,由应用提供的信息。 |
M |
输出发起日志请求的方法名。 |
n |
输出平台相关的换行符。 |
p |
输出日志事件的优先级。 |
r |
输出从构建布局到生成日志事件所花费的时间,以毫秒为单位。 |
t |
输出生成日志事件的线程名。 |
x |
输出和生成日志事件线程相关的 NDC (嵌套诊断上下文)。 |
X |
该字符后跟 MDC 键,比如 X{clientIP} 会输出保存在 MDC 中键 clientIP 对应的值。 |
% |
百分号, %% 会输出一个 % 。 |
格式修饰符
缺省情况下,信息保持原样输出。但是借助格式修饰符的帮助,就可调整最小列宽、最大列宽以及对齐。
下面的表格涵盖了各种修饰符:
格式修饰符 | 左对齐 | 最小宽度 | 最大宽度 | 注释 |
---|---|---|---|---|
%20c |
否 | 20 | 无 | 如果列名少于 20 个字符,左边使用空格补齐。 |
%-20c |
是 | 20 | 无 | 如果列名少于 20 个字符,右边使用空格补齐。 |
%.30c |
不适用 | 无 | 30 | 如果列名长于 30 个字符,从开头剪除。 |
%20.30c |
否 | 20 | 30 | 如果列名少于 20 个字符,左边使用空格补齐,如果列名长于 30 个字符,从开头剪除。 |
%-20.30c |
是 | 20 | 30 | 如果列名少于 20 个字符,右边使用空格补齐,如果列名长于 30 个字符,从开头剪除。 |