1 说明
log4j,即 log for java ,用于日志记录,可以将日志输出到控制台、文件、数据库或者邮件等。使用时需要引入 log4j.properties,配置日志信息的优先级、输出目的地、输出格式等。
本文用一个个例子来说明如何在项目中使用 log4j 基于 log4j.properties 创建的 Logger 。本文基于 log4j 的版本
gav
log4j
log4j
1.2.17
2 概念
2.1 logger
日志记录器,一个日志的实例对象,它拥有 appender ,layout 和 level 属性
2.2 appender
日志的目的地,即日志最终会被记录到哪里,比如控制台,文件或者 db ,不同的目的地对应不同的 appender 类
2.3 layout
日志的布局,包括以下四种类型:
org.apache.log4j.HTMLLayout // 以HTML表格形式布局
org.apache.log4j.PatternLayout // 可以灵活地指定布局模式,最常用
org.apache.log4j.SimpleLayout // 包含日志信息的级别和信息字符串
org.apache.log4j.TTCCLayout // 包含日志产生的时间、线程、类别等等信息
PatternLayout 是最常用的布局,通常需要配合 conversionPattern 使用,该属性类似于 java 中的字符串格式说明,其中包含的转义符规定了输出的内容和格式。
日志的格式说明
%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
%d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
%r:输出自应用程序启动到输出该log信息耗费的毫秒数。
%t:输出产生该日志事件的线程名。
%l(小写的L):输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
%c:输出日志信息所属的类目,通常就是所在类的全名。
%M:输出产生日志信息的方法名。
%F:输出日志消息产生时所在的文件名称。
%L::输出代码中的行号。
%m::输出代码中指定的具体日志信息。
%n:输出一个回车换行符,Windows平台为'rn',Unix平台为'n'。
%x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%:输出一个'%'字符。
2.4 level
日志的优先级,只有优先级高于该 level 的日志信息才会输出
2.5 additivity
是否将子 logger 的日志追加到父 logger 的 appender 中去
2.6 log4j.properties
以 key-value 的形式定义了根 logger 以及自定义的 logger 及其 appender ,layout 和 level
3 例子
3.1 配置文件
# 配置 根 Logger
log4j.rootLogger=debug,consoleAppender
# 配置其他 Logger
# 文件类型 appender
log4j.logger.fileAppender=trace,fileAppender
#表示Logger fileAppender 不会在父 Logger (这里就是根 Logger rootLogger)的 appender 里输出,默认为true。
log4j.additivity.fileAppender=false
# 按天滚动的文件类型 appender
log4j.logger.dailyRollingFileAppender=trace,dailyRollingFileAppender
# 按大小滚动的 appender
log4j.logger.rollingFileAppender=trace,rollingFileAppender
# 将日志记录到 db 类型的 appender
#log4j.logger.dbAppender=trace, dbAppender
#配置全局参数
#项目名
project.name=log4j-demo
#日志存放路径
log.store.path=/Users/andyvictory/hacker/java/workspace/tips/src/main/resources
#输出到控制台
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
#log4j.appender.consoleAppender.layout.ConversionPattern=[%p][Thread:%t][%d{yyyy/MM/dd HH:mm:ss,SSS}][cost:%r][%l]: %m%n
log4j.appender.consoleAppender.layout.ConversionPattern=[%d{yyyy/MM/dd HH:mm:ss,SSS}]: %m%n
log4j.appender.consoleAppender.Threshold=debug
log4j.appender.consoleAppender.ImmediateFlush=TRUE
log4j.appender.consoleAppender.Target=System.out
#输出到文件
log4j.appender.fileAppender=org.apache.log4j.FileAppender
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n
log4j.appender.fileAppender.Threshold=trace
log4j.appender.fileAppender.ImmediateFlush=TRUE
log4j.appender.fileAppender.Append=TRUE
log4j.appender.fileAppender.File=${log.store.path}/fileAppend.log
log4j.appender.fileAppender.Encoding=utf-8
#输出到文件,文件按日期滚动
log4j.appender.dailyRollingFileAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyRollingFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n
log4j.appender.dailyRollingFileAppender.Threshold=warn
log4j.appender.dailyRollingFileAppender.ImmediateFlush=TRUE
log4j.appender.dailyRollingFileAppender.Append=TRUE
log4j.appender.dailyRollingFileAppender.File=${log.store.path}/dailyRollingFileAppender.log
log4j.appender.dailyRollingFileAppender.DatePattern='_'yyyy-MM-dd-HH-mm'.log'
log4j.appender.dailyRollingFileAppender.Encoding=utf-8
#输出到文件,文件按大小滚动
log4j.appender.rollingFileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n
log4j.appender.rollingFileAppender.Threshold=DEBUG
log4j.appender.rollingFileAppender.ImmediateFlush=TRUE
log4j.appender.rollingFileAppender.Append=TRUE
log4j.appender.rollingFileAppender.File=${log.store.path}/rollingFileAppender.log
log4j.appender.rollingFileAppender.MaxFileSize=1kb
log4j.appender.rollingFileAppender.MaxBackupIndex=10
log4j.appender.rollingFileAppender.Encoding=utf-8
#将日志登录到MySQL数据库
#log4j.appender.dbAppender=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.dbAppender.layout=org.apache.log4j.PatternLayout
#log4j.appender.dbAppender.Driver=com.mysql.cj.jdbc.Driver
#log4j.appender.dbAppender.URL=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true
#log4j.appender.dbAppender.User=root
#log4j.appender.dbAppender.Password=root
#log4j.appender.dbAppender.Sql=INSERT INTO logging_event(project_name,thread_name,caller_filename,caller_class,caller_method,caller_line,level_string,formatted_message,gmt_create) values('${project.name}','%t','%F','%c','%M','%L','%p','%m','%d{yyyy-MM-dd HH:mm:ss}')
3.2 测试例子
package myorg.apache.log4j;
import org.apache.log4j.Logger;
import org.junit.Test;
/**
* @author andy
* @desc
* @date 2021/1/31 上午10:13
*/
public class Log4j {
private final Logger logger = Logger.getLogger(this.getClass().getName());
/**
* 使用根 Logger rootLogger 记录日志
*/
@Test
public void rootLogger() {
if (logger.isInfoEnabled()) {
logger.info("rootLogger");
}
}
/**
* 测试输出到控制台
*/
@Test
public void consoleAppender() {
Logger consoleAppender = Logger.getLogger("consoleAppender");
if (consoleAppender.isInfoEnabled()) {
consoleAppender.info("consoleAppender.info");
}
if (consoleAppender.isDebugEnabled()) {
consoleAppender.debug("consoleAppender.debug");
}
consoleAppender.error("consoleAppender.error");
consoleAppender.warn("consoleAppender.warn");
if (consoleAppender.isTraceEnabled()) {
consoleAppender.trace("consoleAppender.trace");
}
}
/**
* 测试写入文件,以追加的形式
*/
@Test
public void fileAppender() {
Logger fileAppender = Logger.getLogger("fileAppender");
fileAppender.trace("fileAppender->trace");
if (fileAppender.isDebugEnabled()) {
fileAppender.debug("fileAppender->debug");
}
fileAppender.info("fileAppender->info");
fileAppender.error("fileAppender->error");
fileAppender.warn("fileAppender->warn");
}
/**
* 写入按天滚动的日志文件
*/
@Test
public void dailyRollingFileAppender() {
Logger dailyRollingFileAppender = Logger.getLogger("dailyRollingFileAppender");
dailyRollingFileAppender.trace("dailyRollingFileAppender.trace");
if (dailyRollingFileAppender.isDebugEnabled()) {
dailyRollingFileAppender.debug("dailyRollingFileAppender.debug");
}
if (dailyRollingFileAppender.isInfoEnabled()) {
dailyRollingFileAppender.info("dailyRollingFileAppender.info");
}
dailyRollingFileAppender.error("dailyRollingFileAppender.error");
dailyRollingFileAppender.warn("dailyRollingFileAppender.warn");
}
/**
* 测试按大小滚动的日志文件
*/
@Test
public void rollingFileAppender() {
Logger rollingFileAppender = Logger.getLogger("rollingFileAppender");
rollingFileAppender.trace("rollingFileAppender.trace");
if (rollingFileAppender.isDebugEnabled()) {
rollingFileAppender.debug("rollingFileAppender.debug");
}
if (rollingFileAppender.isInfoEnabled()) {
rollingFileAppender.info("rollingFileAppender.info");
}
rollingFileAppender.error("rollingFileAppender.error");
rollingFileAppender.warn("rollingFileAppender.warn");
}
}
4 参考文档
4.1 log4j 配置
包括完整的项目演示和配置讲解,非常详细
https://www.tutorialspoint.com/log4j/log4j_configuration.htm
4.2 log4j 博客教程
https://sematext.com/blog/log4j-tutorial/
4.3 格式说明
https://github.com/ZhangZiSheng001/log4j-demo