【终于来了】一篇文章搞定Log4j

3,148 阅读8分钟

一、简介

Log4j ( Logger For Java ) , Java 日志的记录包。 官方网站 。Log4j 是 Apache 的一个开源项目, 为Java提供了日志记录功能。能够让程序员非常方便的记录日志, 并且提供了多种适配方式,能满足各种需求。

使用Log4j 只需要导入一个jar包,jar 下载地址。 Maven 坐标为:

<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接口 implements Appender
  • 继承 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文件配置

我们可以在 Resources Root目录下(如果是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配置

我们可以在 Resources Root目录下(如果是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继续分享的动力, 感谢各位的支持,谢谢

在这里插入图片描述