Log4j日志框架
1、Log4j 简单入门
1、简单介绍
Log4j 官方网站: http://logging.apache.org/log4j/1.2/、Maven仓库:https://search.maven.org/search?q=g:log4j
- Log4j =》Log for java,从时间上讲,Log4j 的产生时间要比JUL早
- Log4j 很重要的一个缺陷是不支持占位符,但是用户可自己定义实现占位符的功能
- 从官网或者Maven仓库可以发现 Log4j 最后的版本是1.2.17
Log4j是Apache下的一款开源日志框架,通过使用Log4j,可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的输出过程,方便项目调试。这些设置可以通过一个配置文件来灵活的进行配置,而不需要修改应用的代码。
2、入门案例
1、建立maven工程并添加依赖
<!--https://search.maven.org/search?q=g:log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
2、默认直接获取Logger对象打印日志,可以发现没有打印我们想要的内容 (是由于我们什么都没有配置,并且Log4j也没有默认配置)
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
/**
* Log4j获取日志记录器对象的两个方法:
* public static Logger getLogger(String name);
* public static Logger getLogger(Class clazz);
*/
Logger logger = Logger.getLogger(Log4jTest.class);
logger.info("hello log4j");
}
}
// 输出内容
log4j:WARN No appenders could be found for logger (Log4jTest).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
注意:如果既没有Java硬编码配置,又没有使用配置文件配置日志输出。默认是没有任何配置,不会输出任何内容
3、使用Log4j提供的初始化默认配置方式
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
// 初始化配置信息,在入门案例中暂不使用配置文件
BasicConfigurator.configure();
/**
* Log4j获取日志记录器对象的两个方法:
* public static Logger getLogger(String name);
* public static Logger getLogger(Class clazz);
*/
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); // 记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
// 输出内容
0 [main] FATAL Log4jTest - fatal test
0 [main] ERROR Log4jTest - error test
0 [main] WARN Log4jTest - warn test
0 [main] INFO Log4jTest - info test
0 [main] DEBUG Log4jTest - debug test
可以发现只打印出了TRACE没有打印出来,是由于默认日志级别为DEBUG,低于DEBUG级别的是不会打印出来
2、Log4j 组件介绍
Log4j主要由Loggers(日志记录器)、Appenders(输出端)和Layout(日志格式化器)组成,其中Loggers控制日志的输出级别与日志是否输出;Appenders指定日志的输出方式(输出到控制台、文件等);Layout控制日志信息的输出格式。
1、Loggers
日志记录器,负责收集处理日志记录,实例的命名就是类"xx"的full quailied name(类的全限定名),Logger的名字大小写敏感,其命名有继承机制。例如:name为org.apache.commoms的logger会继承name为org.apache的logger。
Log4j中有一个特殊的logger叫做"root",它是所有logger的根,也就意味着其他所有的logger都会直接或者间接的继承自root。root logger可以用Logger.getRootLogger()方法获取。JUL也有一个名为”.“的根。
PS:自Log4j 1.2版以来, Logger 类已经取代了 Category 类。对于熟悉早期版本的Log4j的人来说,Logger 类可以被视为 Category 类的别名。
2、Appenders
Appender 用来指定日志输出到哪个地方(和JUL的Handler很像),可以同时指定日志的输出目的地。Log4j 常用的输出目的地。有以下几种:
输出端类型 | 作用 |
---|---|
ConsoleAppender | 将日志输出到控制台 |
FileAppender | 将日志输出到文件中 |
DailyRollingFileAppender | 将日志输出到一个日志文件,并且每天输出到一个新的文件 |
RollingFileAppender | 将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件 |
JDBCAppender | 把日志信息保存到数据库中 |
3、Layouts
Layouts 布局器,用于控制日志输出的格式,让我么可以自定义日志格式,Log4j 常用的 Layouts 有以下几种
格式化器 | 作用 |
---|---|
HTMLLayout | 格式化日志为html表格形式 |
XMLLayout | 格式化日志为xml文档形式 |
SimpleLayout | (默认)简单的日志输出格式化,打印的日志格式为(info - message) |
PatternLayout | 最强大的格式化器,可以根据自定义格式输出日志,如果没有指定转换格式,默认的格式只显示消息内容; |
4、日志输出格式
使用PatternLayout可以自定义格式输出,是我们最常用的方式,这种格式化输出采用类似C语言的printf函数的打印格式化日志信息,具体占位符及含义如下:
参数 | 说明 | 举例 |
---|---|---|
%m | 输出代码中指定的日志信息 | logger.info(日志信息) |
%p | 输出日志级别 | INFO、DEBUG、ERROR %-8p 表示占用8个字符,若字符不够用空格代替 |
%n | 换行符 | 必须在结尾加上换行符,否则日志将杂乱不堪 |
%r | 输出从应用启动到输出该log信息耗费的毫秒数 | log打印时间 - 应用启动时间 |
%c | 输出打印语句所属的类全名 | %c :com.xd.App %c{1}:App |
%C | 列出调用logger的类的全名(包含包路径) | %C :com.xd.App %C{1} :App |
%t | 输出产生该日志所在的线程名名称 | main 、thread-0、thread-1 |
%d | 输出服务器当前时间,精确到豪秒 | 输出服务器当前时间, 默认为ISO8601, 也可指定格式:%d{yyyy-MM-dd HH:mm:ss} |
%l | 输出日志发生的位置,包含包、类、方法、代码行数 | com.log.App.haveConfigFile(App.java:25) |
%L | 输出代码中的行号 | 12 |
%F | 显示调用logger的类的文件名 | App.class |
%% | 输出一个百分号 % | % |
%* 可以在 % 与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式。如:
%5c 输出category名称,最小宽度是5,category<5,默认的情况下右对齐
%-5c 输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格
%.5c 输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格
%20.30c category名称<20补空格,并且右对齐,>30字符,就从左边交远销出的字符截掉
5、日志输出级别
关于日志级别信息,例如:DEBUG、INFO、WARN、ERROR…级别是分大小的,DEBUG < INFO < WARN < ERROR,分别用来指定这条日志信息的重要程度,Log4j 输出日志的规则是:只输出级别不低于设定级别的日志信息,假设 Loggers 级别设定为 INFO,则 INFO、WARN、ERROR 级别的日志信息都会输出,而级别低于 INFO 的 DEBUG 则不会输出。
Log4j 的默认日志级别是:DEBUG
- OFF:最高等级的而级别,用户关闭所有的日志记录
- FATAL:严重的错误信息,一般会造成系统崩溃并终止运行
- ERROR:记录错误信息,不会影响系统运行。一般情况不想输出太多日志,则使用该级别即可
- WARN:记录警告信息
- INFO:记录运行信息
- DEBUG:(默认)记录调式信息,一般在开发中使用
- TRACE:记录追踪信息,记录程序的流程信息,一般情况不会使用
- ALL:最低等级,用于打开所有级别的日志记录
注:一般只使用4个级别,优先级从高到低为 ERROR > WARN > INFO > DEBUG
3、硬编码与配置文件
1、Java硬编码配置
1、Java代码配置:Appenders使用ConsoleAppender,Layouts使用SimpleLayout。
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import java.io.PrintWriter;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
// 配置一个控制台输出源
ConsoleAppender consoleAppender = new ConsoleAppender(new SimpleLayout());
consoleAppender.setName("console");
consoleAppender.setWriter(new PrintWriter(System.out));
logger.addAppender(consoleAppender);
logger.setLevel(Level.ERROR);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); // 记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
// 输出内容
FATAL - fatal test
ERROR - error test
2、Java代码配置,Appenders使用ConsoleAppender,Layouts使用自定义Layout。
import org.apache.log4j.*;
import org.apache.log4j.spi.LoggingEvent;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
// 配置一个自定义Layout(自定义格式化输出)
Layout layout = new Layout() {
@Override
public String format(LoggingEvent loggingEvent) {
// loggingEvent.getLoggerName()输出包名+类名
return loggingEvent.getLoggerName() + " " + loggingEvent.getMessage() + "\r\n";
}
@Override
public boolean ignoresThrowable() {
return false;
}
@Override
public void activateOptions() {
}
};
// 配置一个控制台输出源
ConsoleAppender consoleAppender = new ConsoleAppender(layout);
consoleAppender.setName("customConsole");
logger.addAppender(consoleAppender);
logger.setLevel(Level.ERROR);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); //记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
// 输出内容
Log4jTest fatal test
Log4jTest error test
3、注意如下两个配置,需要的时候可以配置
// 初始化配置信息(没有使用使用配置文件情况下)
BasicConfigurator.configure();
// 开启Log4j内置日志记录(用来打印Log4j更加详细的debug信息)
LogLog.setInternalDebugging(true);
2、加载配置文件
通过查看LogManager源码可知log4j是通过静态代码块中,类加载器加载的配置文件,所以可以在resources下新建一个log4j.properties
文件:
# 指定日志的输出级别与输出端
# WARN代表的是输出级别, console是我们自定义的一个名称appenderNam, 这个可以设置打印到多个地方, 中间用逗号隔开
log4j.rootLogger = WARN,console
# 配置appender输出方法及配置输出信息的格式
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.SimpleLayout
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); //记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
// 输出内容
FATAL - fatal test
ERROR - error test
WARN - warn test
4、Appender输出详解
1、将日志输出到控制台
ConsoleAppender:将日志输出到控制台
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,console
############################# 控制台输出配置 #############################
# 1、指定控制台日志输出的appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式xml.XMLLayout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
#log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n
log4j.appender.console.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); // 记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
控制台中输出如下内容
[FATAL] 0 Log4jTest.main(Log4jTest.java:6) 2022-03-30 15:09:46:620 fatal test
[ERROR] 0 Log4jTest.main(Log4jTest.java:7) 2022-03-30 15:09:46:620 error test
[WARN] 0 Log4jTest.main(Log4jTest.java:8) 2022-03-30 15:09:46:620 warn test
[INFO] 0 Log4jTest.main(Log4jTest.java:9) 2022-03-30 15:09:46:620 info test
2、将日志输出到指定文件
FileAppender:将日志输出到文件中
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,file
############################# 文件输出配置 #############################
# 2、指定文件日志输出的appender【默认是追加的】
log4j.appender.file = org.apache.log4j.FileAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式XMLLayout
log4j.appender.file.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容 (%r [%t] %p %c %x - %m%n)
log4j.appender.file.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# 指定日志文件的保存路径
log4j.appender.file.file = ./logs/log4j.log
# 指定日志文件的字符集
log4j.appender.file.encoding = UTF-8
此时这个日志信息会输出到这个指定位置的文件中。项目同级目录下会自动创建目录与文件(logs/log4j.log)输出内容如下:
[FATAL] 0 Log4jTest.main(Log4jTest.java:6) 2022-03-30 15:09:46:620 fatal test
[ERROR] 0 Log4jTest.main(Log4jTest.java:7) 2022-03-30 15:09:46:620 error test
[WARN] 0 Log4jTest.main(Log4jTest.java:8) 2022-03-30 15:09:46:620 warn test
[INFO] 0 Log4jTest.main(Log4jTest.java:9) 2022-03-30 15:09:46:620 info test
3、根据时间来拆分日志文件
DailyRollingFileAppender:将日志输出到一个日志文件,并且每天输出到一个新的文件
这个会根据你输入的时间间隔来生成新的日志信息,这个时间可以是一天,也可以是一秒,需要注意的是这个并不是自动为我们生成新的日志文件,是我们手动生成的日志文件,比如:你设置的间隔是 yyyy-MM-dd ,这个时候如果你现在输出了一个日志文件,那么在这个时间开始的后24个小时内都不会生成新的日志文件,在这24小时内输出的日志文件都会存储到这个一个旧的日志文件中。即使过了24个小时,系统也不会为我们自动生成一个新的日志文件,需要程序员在输出日志的时候才会生成一个新的日志文件,加可以精确到秒,那么一秒就会为我们生成一个新的日志文件。
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,dailyFile
############################# 按照时间规则输出到文件 #############################
# 3、按日期日志文件输出的appender【在这个类中没有提供覆盖的方法】
log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式XMLLayout
log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.dailyFile.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# 指定日志文件的保存路径【当前文件默认是覆盖的】
log4j.appender.dailyFile.file = ./logs/log4j.log
# 指定日志文件的字符集
log4j.appender.dailyFile.encoding = UTF-8
# 指定日期拆分规则 默认【'.'yyyy-MM-dd】时间pattern只能以短横线-划分
log4j.appender.dailyFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss
多次执行测试类,这时可以发现指定路径下会按照时间秒生产日志文件(log4j.log 中文件是覆盖的,log4j.log.xxx文件在同一个时间内是追加的)
log4j.log
log4j.log.2022-03-30-15-46-12
log4j.log.2022-03-30-15-46-14
在测试时可以根据秒来指定拆分策略,但实际生产环境中,我们可以根据按天或者周、月进行拆分。
4、根据文件大小拆分日志文件
RollingFileAppender:将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,rollingFile
############################# 按照文件大小拆分输出到文件 #############################
# 4、按照文件大小拆分的appender
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式XMLLayout
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.rollingFile.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# 指定日志文件的保存路径
log4j.appender.rollingFile.file = ./logs/log4j.log
# 指定日志文件的字符集
log4j.appender.rollingFile.encoding = UTF-8
# 指定日志文件内容的大小【这里为了测试所以1KB】
log4j.appender.rollingFile.maxFileSize = 1KB
# 指定日志文件的数量【默认是1个】 超过5个,按照时间覆盖(最旧的文件覆盖最新的文件)
log4j.appender.rollingFile.maxBackupIndex = 5
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
for (int i = 0; i < 100; i++) {
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); // 记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
}
}
}
只要文件超过1KB,那么则生成另一个文件,文件的数量最多5个。如果5个文件啊不够怎么办,作为日志管理来讲,不可能让日志无休止的增长,所以覆盖策略是:按照时间来进行覆盖,原则是保留新的,覆盖旧的。这个时候日志6会覆盖掉日志1.
log4j.log
log4j.log.1
log4j.log.2
log4j.log.3
log4j.log.4
log4j.log.5
5、将日志信息存储到数据库
JDBCAppender:把日志信息保存到数据库中
数据库这里需要新建数据库,加入数据库的依赖,然后在配置文件中配置连接数据库的信息并且设置插入语句。
-- create table
CREATE TABLE tab_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)
);
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,logDB
############################# 将日志信息存储到数据库 #############################
# 5、持久化日志信息 将日志信息存储到数据库的appender
log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
log4j.appender.logDB.URL = jdbc:mysql://localhost/tab_log
log4j.appender.logDB.User = root
log4j.appender.logDB.Password = password
# 此时要像数据库中插入数据,使用insert语句
log4j.appender.logDB.Sql = INSERT INTO tab_log(name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m')
然后执行测试类,可以查看到数据中成功插入日志。
6、将日志信息输出到多个位置
上面分别介绍了单个Appender的用法,实际上我们还可以将日志同时输出到多个Appender中。下面示例同时输出到控制台、文件与数据库中
# 指定日志的输出级别与输出端
# 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger=INFO,console,file,logDB
############################# 控制台输出配置 #############################
# 1、指定控制台日志输出的appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式xml.XMLLayout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
#log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n
log4j.appender.console.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd- HH:mm:ss:SSS} %m%n
############################# 文件输出配置 #############################
# 2、指定文件日志输出的appender【默认是追加的】
log4j.appender.file = org.apache.log4j.FileAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式XMLLayout
log4j.appender.file.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容 (%r [%t] %p %c %x - %m%n)
log4j.appender.file.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# 指定日志文件的保存路径
log4j.appender.file.file = ./logs/log4j.log
# 指定日志文件的字符集
log4j.appender.file.encoding = UTF-8
############################# 将日志信息存储到数据库 #############################
# 5、持久化日志信息 将日志信息存储到数据库的appender
log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
log4j.appender.logDB.URL = jdbc:mysql://localhost/tab_log
log4j.appender.logDB.User = root
log4j.appender.logDB.Password = password
# 此时要像数据库中插入数据,使用insert语句
log4j.appender.logDB.Sql = INSERT INTO tab_log(name,create,level,category,fileName,message) values('project_log','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%m')
实际上主要是对这个配置的修改:
# 指定日志的输出级别与输出端, 第1个逗号前是设置的日志级别,后面是自定义名称,输出到什么地方.名称在下方使用
log4j.rootLogger = info,console,file
5、自定义配置Logger
# 使用最高父类rootLogger配置logger,这个时候继承的是父logger(根节点)
log4j.rootLogger = info,console
# 配置自定义loggerlogger对象,会默认继承rootLogger
# 级别会覆盖, INFO升级为WARN. Appender会继承, 既会向控制台输出console, 也会向文件file输出
# 注意:这里自定义的com.xyz是Log4jTest类所在的包名路径
log4j.logger.com.xyz = warn,file
# 第三方框架(org.apache.log4j.Logger)的错误日志打印,不指定appender,就是默认rootLogger的appender(console)
log4j.logger.org.apache = error
############################# 控制台输出配置 #############################
# 1、指定控制台日志输出的appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式xml.XMLLayout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
#log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n
log4j.appender.console.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
############################# 文件输出配置 #############################
# 2、指定文件日志输出的appender【默认是追加的】
log4j.appender.file = org.apache.log4j.FileAppender
# 指定消息格式layout,使用简单格式SimpleLayout ,HTML格式HTMLLayout,xml格式XMLLayout
log4j.appender.file.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容 (%r [%t] %p %c %x - %m%n)
log4j.appender.file.layout.conversionPattern =[%p] %r %l %d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
# 指定日志文件的保存路径
log4j.appender.file.file = ./logs/log4j.log
# 指定日志文件的字符集
log4j.appender.file.encoding = UTF-8
package com.xyz;
import org.apache.log4j.Logger;
public class Log4jTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jTest.class);
logger.fatal("fatal test"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger.error("error test"); // 记录错误信息,不会影响系统运行
logger.warn("warn test"); // 记录警告信息
logger.info("info test"); // 记录运行信息
logger.debug("debug test"); // (默认)记录调式信息,一般在开发中使用
logger.trace("trace test"); // 记录追踪信息,记录程序的流程信息
// 三方框架的错误日志信息打印
// 因为log4j.properties文件中appender名是类名的包路径,
// 这里是org.apache.log4j.Logger,就可以继承log4j.properties的配置
Logger logger2 = Logger.getLogger(Logger.class);
logger2.fatal("fatal test2"); // 记录严重的错误信息,一般会造成系统崩溃并终止运行
logger2.error("error test2"); // 记录错误信息,不会影响系统运行
logger2.warn("warn test2"); // 记录警告信息
logger2.info("info test2"); // 记录运行信息
logger2.debug("debug test2"); // (默认)记录调式信息,一般在开发中使用
logger2.trace("trace test2"); // 记录追踪信息,记录程序的流程信息
}
}
控制台输出:
[FATAL] 0 com.xyz.Log4jTest.main(Log4jTest.java:7) 2022-03-30 17:58:48:215 fatal test
[ERROR] 10 com.xyz.Log4jTest.main(Log4jTest.java:8) 2022-03-30 17:58:48:225 error test
[WARN] 10 com.xyz.Log4jTest.main(Log4jTest.java:9) 2022-03-30 17:58:48:225 warn test
[FATAL] 10 com.xyz.Log4jTest.main(Log4jTest.java:19) 2022-03-30 17:58:48:225 fatal test2
[ERROR] 10 com.xyz.Log4jTest.main(Log4jTest.java:20) 2022-03-30 17:58:48:225 error test2
文件中输出:
[FATAL] 0 com.xyz.Log4jTest.main(Log4jTest.java:7) 2022-03-30 17:58:48:215 fatal test
[ERROR] 10 com.xyz.Log4jTest.main(Log4jTest.java:8) 2022-03-30 17:58:48:225 error test
[WARN] 10 com.xyz.Log4jTest.main(Log4jTest.java:9) 2022-03-30 17:58:48:225 warn test
可以看出:file中不会存入org.apache这个logger的日志,因为该logger没有指定appender,默认的rootLogger的appender只是输出到控制台的
自定义Logger结论:如果根节点的Logger和自定义父Logger配置的输出位置是不同的则取二者的并集,也就是配置的位置都会进行日志的输出。如果二者配置的日志级别不同,主要以按照我们自定义的父logger的级别输出为主。
6、参考文献 & 鸣谢
- 日志技术之Log4j学习【CSDN:StudyWinter】https://blog.csdn.net/Zhouzi_heng/article/details/107965987
- java日志:二、log4j使用【CSDN:小徐也要努力鸭】https://blog.csdn.net/a232884c/article/details/121102525