文章目录
一、Log4j简介
- Log4j是
Apache
的一个开源项目 - 可以控制日志信息输出到
控制台
、文件
、甚至是数据库
中 - 可以控制每一条日志的输出格式
- 通过一个
配置文件
来灵活地进行配置,而不需要修改应用的代码
二、Log4j组件介绍
- 主要由Loggers (日志记录器)、Appenders(输出控制器)和 Layout(日志格式化器)组成
- Loggers:控制日志的输出级别与日志
是否输出
- Appenders:指定日志的
输出方式
(输出到控制台、文件等) - Layout:控制日志信息的
输出格式
1、Loggers (日志记录器)
- 日志记录器,负责收集处理日志记录
- 实例的命名就是类的
全限定名
,如com.xc.log4j.XX - Logger的名字大小写敏感
- 实例的命名就是类的
- 命名有继承机制
- 例如:name为com.xc.log4j的logger会继承name为com.xc的logger的属性
- 父类所做的日志属性设置,会直接的影响到子类
- Log4J中有一个特殊的logger叫做"root",他是所有logger的根
- 也就意味着其他所有的logger都会直接或者间接地继承自root
- root logger可以用Logger.getRootLogger()方法获取
2、Appenders(输出控制器)
ConsoleAppender
:将日志输出到控制台
FileAppender
:将日志输出到文件中
DailyRollingFileAppender
:将日志输出到一个日志文件,并且每天
输出到一个新的文件RollingFileAppender
:将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小
达到指定尺寸时,会自动把文件改名,同时产生一个新的文件JDBCAppender
:把日志信息保存到数据库
中
3、Layout(日志格式化器)
HTMLLayout
:格式化日志输出为HTML表格形式SimpleLayout
:简单的日志输出格式化,打印的日志格式如默认INFO级别的消息PatternLayout
:最强大的格式化组件,有默认的转换格式,也可以自定义格式输出日志
日志输出格式说明
- %m:输出代码中指定的日志信息
- %p:输出级别,及 DEBUG、INFO 等
- %n:换行符(Windows平台的换行符为 "\n",Unix 平台为 "\n")
- %r:输出自应用启动到输出该 log 信息耗费的毫秒数
- %c:输出打印语句所属的类的全名
- %t:输出产生该日志的线程全名
- %d:输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss}
- %l:输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test.java:10)
- %F:输出日志消息产生时所在的文件名称
- %L:输出代码中的行号
- %%:输出一个 "%" 字符
可以在 % 与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式
%5c
:输出category名称,最小宽度
是5,category<5,默认的情况下右对齐
%-5c
:输出category名称,最小宽度
是5,category<5,"-"号指定左对齐
,会有空格%.5c
:输出category名称,最大宽度
是5,category>5,就会将左边多出的字符截掉,<5不会有空格%20.30c
:category名称<20补空格,并且右对齐,>30字符,就从左边较远处多出的字符截掉
三、Log4j快速入门
pom依赖
xml
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
java
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.Test;
public class Log4jTest {
@Test
public void test01() {
// 加载初始化配置(没有配置文件则需要添加此配置)
BasicConfigurator.configure();
// 实例化Logger
Logger logger = Logger.getLogger(Log4jTest.class);
logger.info("logger实例名称:" + logger.getName());
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
}
输出结果:
java
0 [main] INFO com.xc.log.Log4jTest - logger实例名称:com.xc.log.Log4jTest
1 [main] FATAL com.xc.log.Log4jTest - fatal信息
1 [main] ERROR com.xc.log.Log4jTest - error信息
1 [main] WARN com.xc.log.Log4jTest - warn信息
1 [main] INFO com.xc.log.Log4jTest - info信息
1 [main] DEBUG com.xc.log.Log4jTest - debug信息
Log4j提供了8个级别的日志输出
- ALL:最低等级 用于打开
所有级别
的日志记录 - TRACE:程序推进下的
追踪
信息,这个追踪信息的日志级别非常低,一般情况下是不会使用的 - DEBUG:指出细粒度信息事件对
调试
应用程序是非常有帮助的,主要是配合开发,在开发过程中打印一些重要的运行信息(默认级别) - INFO:消息的粗粒度级别
运行
信息 - WARN:表示
警告
,程序在运行过程中会出现的有可能会发生的隐形的错误 - ERROR:系统的
错误
信息,发生的错误不影响系统的运行 一般情况下,如果不想输出太多的日志,则使用该级别即可 - FATAL:表示
严重错误
,它是那种一旦发生系统就不可能继续运行的严重错误 - OFF:最高等级的级别,用户
关闭所有
的日志记录
四、Log4j自定义配置文件输出日志
Loader.getResource("log4j.properties")
;源码默认从类路径
找
1、输出到控制台
resources目录下的log4j.properties文件
java
@Test
public void test02(){
//自定义配置文件设置Appender(输出方式)和Layout(输出格式)
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
输出结果:
java
[FATAL ] [main] [2024-09-19 22:38:55:822] [com.xc.log.Log4jTest.test01(Log4jTest.java:18)] fatal信息
[ERROR ] [main] [2024-09-19 22:38:55:825] [com.xc.log.Log4jTest.test01(Log4jTest.java:19)] error信息
[WARN ] [main] [2024-09-19 22:38:55:825] [com.xc.log.Log4jTest.test01(Log4jTest.java:20)] warn信息
[INFO ] [main] [2024-09-19 22:38:55:825] [com.xc.log.Log4jTest.test01(Log4jTest.java:21)] info信息
2、输出到文件
resources目录下的log4j.properties文件
java
@Test
public void test03(){
//输出到文件对于追加,默认是true
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
输出结果:
3、输出到数据库
创建表结构:(字段的制定可以根据需求进行调整)
sql
CREATE TABLE `log` (
`log_id` int(11) NOT NULL AUTO_INCREMENT,
`project_name` varchar(255) DEFAULT NULL COMMENT '目项名',
`create_date` varchar(255) DEFAULT NULL COMMENT '创建时间',
`level` varchar(255) DEFAULT NULL COMMENT '优先级',
`category` varchar(255) DEFAULT NULL COMMENT '所在类的全名',
`file_name` varchar(255) DEFAULT NULL COMMENT '输出日志消息产生时所在的文件名称 ',
`thread_name` varchar(255) DEFAULT NULL COMMENT '日志事件的线程名',
`line` varchar(255) DEFAULT NULL COMMENT '号行',
`all_category` varchar(255) DEFAULT NULL COMMENT '日志事件的发生位置',
`message` varchar(4000) DEFAULT NULL COMMENT '输出代码中指定的消息',
PRIMARY KEY (`log_id`)
);
resources目录下的log4j.properties文件
java
@Test
public void test04(){
//将日志持久化到数据库表中
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
输出结果:
五、Log4j自定义配置文件拆分日志
1、按照文件大小进行拆分
resources目录下的log4j.properties文件
java
@Test
public void test05(){
Logger logger = Logger.getLogger(Log4jTest.class);
for (int i = 0; i < 10000; i++) {
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
}
第一次执行
第二次执行
- 最新日志在logFile.log文件中,logFile.log.x数字越小日志越新
- 先打印的日志会被先覆盖
- 如上第一次打印0123
- 第二次打印中的45是第一次打印的0123被覆盖后东西
- 01比23内容新,23被覆盖,那么
45中剩余的就是01的内容
- 总之
最新
的内容覆盖最旧
的内容
2、按照日期进行拆分
resources目录下的log4j.properties文件
java
@Test
public void test05(){
//根据日期拆分
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal信息");
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
- 这里使用的默认根据
天
拆分,也可以根据小时,分钟拆分 - 今天是9.20日,昨天的日志被添加到新文件logFile.log.2024-09-19中
- 当天日志都会记录在logFile.log中
六、自定义配置文件中的logger
- 常规创建出来的Logger对象,默认都是继承rootLogger的
- 也可以
自定义logger
,让其他logger来继承这个logger
- 如果根节点的logger和自定义logger配置的
输出位置
是不同的,则取二者的并集
,配置的位置都会进行输出操作 - 如果二者配置的
日志级别
不同,以按照我们自定的logger
的级别输出为主