【终于来了】一篇文章搞定Log4j
一、简介
Log4j
( Logger For Java ) , Java 日志的记录包。官方网站 。Log4j 是 Apache
的一个开源项目, 为Java提供了日志记录功能。能够让程序员非常方便的记录日志, 并且提供了多种适配方式,能满足各种需求。
<dependency>
<groupId>org.log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
</dependency>
二、Log4j 组成
Log4j 核心主要包括三部分:
Level :日志等级, 用于定义日志的重要程度
Appender:追加器, 用于定义日志的输出位置
Layout:布局, 用于定义日志的输出格式
三、Level (日志等级)
下面是 Log4j 中Level 源码。
通过源码我们可以看到, Log4j 日志等级有:
off
: 关闭日志 , 最高等级, 任何日志都无法输出fatal
,:灾难性错误, 在能够输出日志的所有等级中最高error
:错误, 一般用于异常信息warn
:警告, 一般用于不规范的引用等信息info
:普通信息debug
:调试信息, 一般用于程序执行过程trace
:堆栈信息, 一般不使用all
:打开所有日志, 最低等级, 所有日志都可使用
在 Logger 核心类中, 除了 off/all
以外, 其他每个日志等级都对应一组重载的方法, 用于记录不同等级的日志。
当且仅当 方法对应的日志等级 大于等于 设置的日志等级时, 日志才会被记录
四、Appender(追加器)
Appender 用于定义日志的输出位置, Log4j 提供了多种可供选择的追加器。常用追加器有
Appender | 作用 |
---|---|
ConsoleAppender | 将日志记录在控制台 |
FileAppender | 将日志记录在文件中 |
RollingFileAppender | 将日志记录在文件中, 当文件达到一定大小之后,会创建新文件 |
DailyRollingFileAppender | 将日志记录在文件中, 每天一个备份文件 |
JDBCAppender | 将日志记录在数据库表中 |
以上五个为常用Appender,完整列表为
当然, 如果觉得这些也不能满足你的需求, 你可以:
实现
Appender
接口implementsAppender
继承
AppenderSkeleton
类 重写核心方法
五、Layout (布局)
Layout 用于定义输出日志的格式, 常用Layout 有
Layout | 格式 |
---|---|
SimpleLayout | 简单格式, 格式为 日志等级-日志内容 |
TTCCLayout | Time,Thread,Category,Context [线程] 日志等级 记录日志的类的包名.类名 - 日志内容 |
XMLLayout | 以XML格式输出日志 |
HTMLLayout | 以HTML文件格式输出日志 |
PatternLayout | 灵活格式输出日志, 使用通配符自定义格式 |
以上五个为常用Layout ,完整列表为
六、使用Java代码记录日志
public class Test {
public static void main(String[] args) {
// 获取日志对象, 参数为当前类class对象
Logger logger = Logger.getLogger(Test.class);
// 设置日志等级为TRACE等级
logger.setLevel(Level.DEBUG);
// 创建Appender对象
ConsoleAppender conAppender = new ConsoleAppender();
// 设置Appender
conAppender.setTarget(ConsoleAppender.SYSTEM_OUT);
conAppender.activateOptions();
// 设置Layout
SimpleLayout simpleLayout = new SimpleLayout();
// 将 simpleLayout 设置到Appender中
conAppender.setLayout(simpleLayout);
// 将Appender 添加到 rootLogger 中
logger.addAppender(conAppender);
// 记录日志
logger.error("这是日志信息");
}
}
ERROR - 这是日志信息
Process finished with exit code 0
这种方式是最直观的方式, 代码非常直观的定义了Log4j 的三大组成要素,缺点是 代码太过于冗余, 如果只是为了记录个日志, 而要去写这么长的代码, 真的是 本末倒置了, 也不能体现出Log4j 灵活的特性。所以, 实际开发中不会使用这种模式(其实真是原因就是根本没人这样用, 小C就是非要找些冠冕堂皇的理由以显示其专业性!!)
七、使用XML文件配置
我们可以在 ResourcesRoot
目录下(如果是Eclipse , 可以是 src
或者 任何 source folder
), 说白了就是项目编译后的根目录(对于Java萌新而言, 就暂且认为是 src 目录吧), 创建一个 log4j.xml
配置文件, 一定要注意:文件的位置 和 文件名 一个都不能错, 然后在 XML 文件中添加配置信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "log4j" "log4j.dtd" >
<log4j:configuration>
<appender name="cons" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out"/>
<layout class="org.apache.log4j.SimpleLayout"></layout>
</appender>
<root>
<level value="INFO"></level>
<appender-ref ref="cons"/>
</root>
</log4j:configuration>
简单看看吧, 这种配置方式实际开发过程中也没人使用。
八、使用properties配置
我们可以在 ResourcesRoot
目录下(如果是Eclipse , 可以是 src
或者 任何 source folder
), 说白了就是项目编译后的根目录(对于Java萌新而言, 就暂且认为是 src 目录吧), 创建一个 log4j.properties
配置文件, 一定要注意:文件的位置 和 文件名 一个都不能错, 然后在 properties 文件中添加配置信息
log4j.rootLogger=debug,cons
log4j.appender.cons=org.apache.log4j.ConsoleAppender
log4j.appender.cons.target=System.out
log4j.appender.cons.layout=org.apache.log4j.PatternLayout
log4j.appender.cons.layout.ConversionPattern=%m%n
import org.apache.log4j.*;
public class Test {
public static void main(String[] args) {
// 获取日志对象, 参数为当前类class对象
Logger logger = Logger.getLogger(Test.class);
// 记录日志
logger.error("这是日志信息");
}
}
propertis 文件是最常用的配置方式。实际开发过程中, 基本都是使用properties文件。后面的章节会给出一个比较完整的配置手册
pripertis配置文件的配置方式为
# 配置日志等级, 指定生效的Appender名字, AppenderA是定义的Appender的名字
log4j.rootLogger=日志等级,AppenderA,AppenderB,...
# ---------------- 定义一个appender------------------------
# 定义一个appender, appender名字可以是任意的,
# 如果要使该appender生效, 须加入到上一行rootLogger中, 后面为对应的Appender类
log4j.appender.appender名字=org.apache.log4j.ConsoleAppender
log4j.appender.appender名字.target=System.out
# 定义Appender的布局方式
log4j.appender.appender名字.layout=org.apache.log4j.SimpleLayout
九、Java代码与Properties对比
有的童鞋会觉得说Java代码的写法更加的直观, 每一行在做什么更清晰, 其实, 对比一下Java代码和Properties文件就会发现, 两者是一样的, Properties文件配置也不需要记特别多的东西。比如说
其实, properties 文件 就是 对java代码的简化, 使用Java代码解读下properites, 你会发现结果是基本一致的
十、总结
总结来说, log4j 的配置文件主要架构是
log4j.rootLogger=日志等级, AppenderNameA,,,,
log4j.appender.AppenderNameA=要使用的Appender
log4j.appender.AppenderNameA.PropertyA=PropertyA的值
log4j.appender.AppenderNameA.PropertyB=PropertyB的值
log4j.appender.AppenderNameA.PropertyC=PropertyC的值
log4j.appender.AppenderNameA.layout=要使用的Layout
log4j.appender.AppenderNameA.layout.PropertyA=PropertyA的值
log4j.appender.AppenderNameA.layout.PropertyB=PropertyB的值
log4j.appender.AppenderNameA.layout.PropertyC=PropertyC的值
PropertyA 其实就是 前面的类中的 setXxxx 方法对应的属性, 例如:
log4j.appender.cons=org.apache.log4j.ConsoleAppender
log4j.appender.cons.target=System.out
也就意味着
ConsoleAppender cons = new ConsoleAppender();
cons.setTarget("System.out");
如果set方法参数是对象类型, 那么则写对应类型的包名.类名, 例如
log4j.appender.cons=org.apache.log4j.ConsoleAppender
log4j.appender.cons.layout=org.apache.log4j.SimpleLayout
也就意味着
ConsoleAppender cons = new ConsoleAppender();
SimpleLayout simpleLayout = new SimpleLayout();
cons.setLayout(simpleLayout);
如此, 就算你忘记了要配置哪些东西, 翻一翻源代码也就OK了
十一、附录
1、大型properties文件
# 设置 全局日志等级
# 可以使用log4j.appender.xxx.threshold=LEVEL 为某个特定appender设置日志等级
# 设置 所有生效的appender, 没有出现在此处的appender, 即使定义了也无效
log4j.rootLogger = debug,cons,myFile,myrFile,mydFile,jdbc
# ================================= 控制台 日志记录 ================================
log4j.appender.cons=org.apache.log4j.ConsoleAppender
# 设置当前appender的日志等级为info,当方法的优先级大于info时, 控制台才会有输出
log4j.appender.cons.threshold=info
# 设置日志输出方式, System.out 和 System.err 两种选择
log4j.appender.cons.target=System.out
# 设置为true,表示创建新的System.out 对象, 不使用System类中的out属性
log4j.appender.cons.follow=true
log4j.appender.cons.layout=org.apache.log4j.SimpleLayout
# ================================= 文件 日志记录 ================================
log4j.appender.myFile=org.apache.log4j.FileAppender
# 文件存储路径
log4j.appender.myFile.file=./log.txt
# 是否以追加的形式向日志文件中写入内容, 默认为true,不会覆盖之前的内容, 否则只会保留最后一次写入的日志
log4j.appender.myFile.append=false
log4j.appender.myFile.layout=org.apache.log4j.SimpleLayout
# =============================== 滚动文件 日志记录 ================================
# 当日志达到一定大小时, 将重新创建新文件记录日志
log4j.appender.myrFile=org.apache.log4j.RollingFileAppender
log4j.appender.myrFile.file=./log.txt
# 最多备份文件的个数,当文件大小超过设置的值时, 会将原内容进行备份。
# 该值指定了备份文件的个数, 如果超过数量, 则会删除掉最早的备份文件, 如果为0 则不进行备份
log4j.appender.myrFile.maxBackupIndex=5
# 每个文件的最大容量 默认单位是b, 可以指定 "KB", "MB" 或者 "GB", 当文件超过该大小时, 会将其进行备份(maxBackupIndex!=0)
log4j.appender.myrFile.maxFileSize=1024
# 每个文件的最大容量, 类似于 maxFileSize, 不过是long类型, 即不可有单位, 单位是b
log4j.appender.myrFile.maximumFileSize=1024
log4j.appender.myrFile.layout=org.apache.log4j.SimpleLayout
# ============================== 每日滚动文件 日志记录 ================================
# 日志按天进行备份
log4j.appender.mydFile=org.apache.log4j.DailyRollingFileAppender
# 前一天日志的备份文件的后缀格式(后缀为前一天日期,格式为日期格式)
log4j.appender.mydFile.datePattern=yyyyMMdd
# 当天的日志的记录文件路径
log4j.appender.mydFile.file=./nl.txt
log4j.appender.mydFile.layout=org.apache.log4j.SimpleLayout
# ================================= JDBC 日志记录 ===============================
# 选择jdbc记录器
log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
# 驱动
log4j.appender.jdbc.driver=com.mysql.jdbc.Driver
# 密码
log4j.appender.jdbc.password=
# url
log4j.appender.jdbc.URL=jdbc:mysql://localhost:3306/log
# 用户名
log4j.appender.jdbc.user=root
# 数据库插入语句
log4j.appender.jdbc.sql=insert into t_log values ('%m')
# 布局
log4j.appender.jdbc.layout=org.apache.log4j.SimpleLayout
2、PatternLayout 输出格式
格式 | 作用 |
---|---|
%p | 日志等级 |
%d | 日期 2018-6-26 16:05:19,555 |
%d{ymdhms自定义日期格式} | %d{yyyyMMddHHmmss} |
%r | 记录日志所消耗的时间 |
%C | 产生日志的包名.类名 |
%t | 产生日志的线程名 |
%m | 日志消息 |
%l | 产生日志的 包名.类名.方法名(类名:行数) |
%L | 行号 |
例如:
log4j.appender.cons.layout=org.apache.log4j.PatternLayout
log4j.appender.cons.layout.ConversionPattern= [%p] %d %c - %m%n
完整格式配置, 详见官方API
您的点赞就是对小C最大的支持!也是小C继续分享的动力, 感谢各位的支持,谢谢