java日志:二、log4j使用

java日志:二、log4j使用

1 介绍

Log4j是Apache下的一款开源日志框架,通过在项目中使用Log4j,可以控制日志信息输出到控制台、文件、甚至是数据库中。我们可以控制每条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的输出过程,方便项目调试。

Log4j主要由Loggers(日志记录器)、Appenders(输出端)和Layout(日志格式化器)组成,其中Loggers控制日志的输出级别与日志是否输出;Appenders指定日志的输出方式(输出到控制台、文件等);Layout控制日志信息的输出格式。

1.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()方法获取。

1.2 Appenders

Appenders用来指定日志输出到哪个地方,可以同时指定日志的输出目的地。Log4j常用的输出目的地有以下几种(结构:输出端类型+作用):

输出端类型作用
ConsoleAppender将日志输出到控制台
FileAppender将日志输出到文件中
DailyRollingFileAppender将日志输出到一个日志文件,并且每天输出到一个新的文件
RollingFileAppender将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件
JDBCAppender把日志信息保存到数据库中

1.3 Layouts

布局器Layouts用于控制日志输出内容的格式,可以使用各种需要的格式输出日志。常用Layouts如下:

格式化器类型作用
HTMLLayout格式化日志输出为HTML表格形式
SimpleLayout简单的日志输出格式化,打印的日志格式为(info-message)
PatternLayout最强大的格式日期,可以根据自定义格式输出日志,如果没有指定转换格式,就是用默认的转换格式

2 依赖配置

提前配置好junit的依赖:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
</dependency>

https://search.maven.org/ 查询log4j的版本:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

注意:需要去掉 < type >bundle</ type >,否则配置时aliyun仓库会报错:

Could not find artifact log4j:log4j:bundle:1.2.17 in nexus-server@alipay (http://mvn.test.alipay.net:8080/artifactory/repo)

3 Log4j的使用
在这里插入图片描述
直接执行以下会报错:

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testlog(){
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);
        logger.info("hello log4j");
    }
}

在这里插入图片描述

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testlog(){
        //初始化配置信息,暂不使用配置文件
        BasicConfigurator.configure();
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);
        logger.info("hello log4j");
        
        //日志级别
        //最高级别
        logger.fatal("fatal");//严重错误,一般会造成系统崩溃并终止运行
        logger.error("error");//错误信息,不会影响系统运行
        logger.warn("warn");//警告信息,可能会发生问题
        logger.info("info");//运行信息,数据连接、网络连接、IO操作等等
        logger.debug("debug");//调试信息,一般在开发中使用,记录程序变量参数传递信息等等
        logger.trace("trace");//追踪信息,记录程序所有流程信息
    }
}

在这里插入图片描述
4 log4j配置文件使用

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>RELEASE</version>
    <scope>compile</scope>
</dependency>

查看log4j的源码:
在这里插入图片描述
在这里插入图片描述
可知log4j是通过静态代码块中,类加载器加载的配置文件,所以可以在resources下新建一个log4j.properties:
在这里插入图片描述
继续:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要自定义appender的名称:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
log4j.properties:

log4j.rootLogger=WARN,conso
log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.SimpleLayout
package com.base7;

import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test;

public class Log4jTest {
    @Test
    public void testLogProperties(){
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);

        //最高级别
        logger.fatal("fatal");//严重错误,一般会造成系统崩溃并终止运行
        logger.error("error");//错误信息,不会影响系统运行
        logger.warn("warn");//警告信息,可能会发生问题
        logger.info("info");//运行信息,数据连接、网络连接、IO操作等等
        logger.debug("debug");//调试信息,一般在开发中使用,记录程序变量参数传递信息等等
        logger.trace("trace");//追踪信息,记录程序所有流程信息
    }
}
FATAL - fatal
ERROR - error
WARN - warn

5 log4j内置日志记录

在这里插入图片描述
进入LogLog的debug,开关如下:

public static void debug(String msg, Throwable t) {
    if (debugEnabled && !quietMode) {
        System.out.println("log4j: " + msg);
        if (t != null) {
            t.printStackTrace(System.out);
        }
    }
}

debugEnable是默认关闭的,quiteMode是默认开启的,在LogLog.class中按下快捷键ctrl+F12(搜索内部的方法等等):
在这里插入图片描述

package com.base7;

import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.jupiter.api.Test;


public class Log4jTest {
    @Test
    public void testLogProperties(){
        //开启log4j内置日志记录
        LogLog.setInternalDebugging(true);
        
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);

        //最高级别
        logger.fatal("fatal");//严重错误,一般会造成系统崩溃并终止运行
        logger.error("error");//错误信息,不会影响系统运行
        logger.warn("warn");//警告信息,可能会发生问题
        logger.info("info");//运行信息,数据连接、网络连接、IO操作等等
        logger.debug("debug");//调试信息,一般在开发中使用,记录程序变量参数传递信息等等
        logger.trace("trace");//追踪信息,记录程序所有流程信息
    }
}

在这里插入图片描述
6 log4j的layout配置

log4j.properties:

log4j.rootLogger=WARN,conso
log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test;


public class Log4jTest {
    @Test
    public void testLogProperties(){
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);

        //最高级别
        logger.fatal("fatal");//严重错误,一般会造成系统崩溃并终止运行
        logger.error("error");//错误信息,不会影响系统运行
        logger.warn("warn");//警告信息,可能会发生问题
        logger.info("info");//运行信息,数据连接、网络连接、IO操作等等
        logger.debug("debug");//调试信息,一般在开发中使用,记录程序变量参数传递信息等等
        logger.trace("trace");//追踪信息,记录程序所有流程信息
    }
}

PatternLayout默认就是只打印%m(消息):

fatal
error
warn

在这里插入图片描述
修改log4j.properties如下:

#指定RootLogger 顶级父元素默认配置信息
#指定日志的级别是WARN,使用的appender是conso
log4j.rootLogger=WARN,conso
#指定控制台日志输出的appender
log4j.appender.conso=org.apache.log4j.ConsoleAppender
#指定消息格式 layout
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
#指定消息格式的内容
log4j.appender.conso.layout.conversionPattern=[%p]%r %c %t %d{yyyy年MM月dd日 HH:mm:ss.SSS} %m%n

#%m 输出代码中指定的日志信息
#%p 输出优先级,DEBUG、INFO等
#%n 换行符(Windows平台的换行符为"\r\n",Unix平台是"\n")
#%r 输出自应用启动到输出该log信息耗费的毫秒数
#%c 输出打印语句所属的类的全名
#%t 输出产生该日志的线程全名
#%d 输出服务器当前时间,默认为ISO8601,也可指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss.SSS}
#%l 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test.java:12)
#%F 输出日志消息产生时所在的文件名称
#%L 输出代码中的行号
#%% 输出"%"字符

执行上述代码,打印如下:(中文可能乱码,以?表示)

[FATAL]0 com.base7.Log4jTest main 2021?11?04? 21:01:38.394 fatal
[ERROR]1 com.base7.Log4jTest main 2021?11?04? 21:01:38.395 error
[WARN]2 com.base7.Log4jTest main 2021?11?04? 21:01:38.396 warn

再次修改:

#指定RootLogger 顶级父元素默认配置信息
#指定日志的级别是WARN,使用的appender是conso
log4j.rootLogger=WARN,conso
#指定控制台日志输出的appender
log4j.appender.conso=org.apache.log4j.ConsoleAppender
#指定消息格式 layout
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
#指定消息格式的内容
log4j.appender.conso.layout.conversionPattern=[%p]%r %c %t %F %L %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
[FATAL]0 com.base7.Log4jTest main Log4jTest.java 18 2021-11-04 21:03:55.717 fatal
[ERROR]4 com.base7.Log4jTest main Log4jTest.java 19 2021-11-04 21:03:55.721 error
[WARN]4 com.base7.Log4jTest main Log4jTest.java 20 2021-11-04 21:03:55.721 warn

替换%c %t %F %L为%l:

#指定RootLogger 顶级父元素默认配置信息
#指定日志的级别是WARN,使用的appender是conso
log4j.rootLogger=WARN,conso
#指定控制台日志输出的appender
log4j.appender.conso=org.apache.log4j.ConsoleAppender
#指定消息格式 layout
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
#指定消息格式的内容
log4j.appender.conso.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
[FATAL]0 com.base7.Log4jTest.testLogProperties(Log4jTest.java:18) 2021-11-04 21:04:43.529 fatal
[ERROR]4 com.base7.Log4jTest.testLogProperties(Log4jTest.java:19) 2021-11-04 21:04:43.533 error
[WARN]5 com.base7.Log4jTest.testLogProperties(Log4jTest.java:20) 2021-11-04 21:04:43.534 warn

可以在%与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对齐方式:

格式描述
%5c输出category名称,最小宽度是5,category<5,默认情况下右对齐
%-5c输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格
%.5c输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格
%20.30ccategory名称<20补空格,并且右对齐,>30字符,就会从左边多出的字符截掉

比如:

#指定消息格式的内容
log4j.appender.conso.layout.conversionPattern=[%10p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

右对齐:

[     FATAL]0 com.base7.Log4jTest.testLogProperties(Log4jTest.java:18) 2021-11-04 21:12:26.715 fatal
[     ERROR]3 com.base7.Log4jTest.testLogProperties(Log4jTest.java:19) 2021-11-04 21:12:26.718 error
[      WARN]3 com.base7.Log4jTest.testLogProperties(Log4jTest.java:20) 2021-11-04 21:12:26.718 warn

7 log4j的FileAppender配置
在这里插入图片描述

package com.base3;

import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testLogFj(){
        //开启log4j内置日志记录
        LogLog.setInternalDebugging(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");
    }
}

控制台输出:
在这里插入图片描述
日志file位置,log4j会在当前路径下,自动新建一个文件夹以及文件,然后写入内容(log4j源码中默认是以追加的形式写入文件):
在这里插入图片描述
8 log4j的RollingFileAppender使用(按照文件大小拆分日志)

log4j.properties:

log4j.rootLogger=WARN,conso,rollingFile

log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
log4j.appender.conso.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

#日志文件输出的 appender对象
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.file.file=./logs/file.log
#指定日志文件的字符集
log4j.appender.file.encoding=UTF-8

#按照文件大小拆分的appender
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
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/rolling_file.log
log4j.appender.rollingFile.encoding=UTF-8
#指定日志文件的大小(单位:KB、MB、GB等)
log4j.appender.rollingFile.maxFileSize=1MB
#指定日志文件的数量
log4j.appender.rollingFile.maxBackupIndex=10
package com.base3;

import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testLogFj(){
        //开启log4j内置日志记录
        LogLog.setInternalDebugging(true);
        //获取日志记录器对象
        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");
        }
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最多只会产生10个文件:
在这里插入图片描述
9 log4j的DailyRollingFileAppender使用(按照时间规则拆分日志)
在这里插入图片描述
但是有setDatePattern方法,可自由修改时间规则模式:
在DailyRollingFileAppender类文件按下ctrl+F12:
在这里插入图片描述
在log4j.properties中指定日期拆分的规则(时间pattern只能以短横线-划分):

log4j.rootLogger=INFO,conso,dailyFile

log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
log4j.appender.conso.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

#按照时间规则拆分的appender
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
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/daily_roll_file.log
log4j.appender.dailyFile.encoding=UTF-8
#指定日期拆分规则
log4j.appender.dailyFile.datePattern='.'yyyy-MM-dd-HH-mm-ss-SSS

10 自定义logger对象设置

log4j.properties:

log4j.rootLogger=INFO,conso

#自定义logger对象(会默认继承rootLogger:
# 级别会覆盖,由INFO升级为warn,但是既会向控制台输出:conso;
# 也会向文件file输出)
# 注意:这里自定义的com.base3,是Log4jTest类所在的包名路径
log4j.logger.com.base3 = warn,file

log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
log4j.appender.conso.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

#日志文件输出的 appender对象
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.file.file=./logs/xiaoxu_file.log
#指定日志文件的字符集
log4j.appender.file.encoding=UTF-8
package com.base3;

import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testLogFj(){
        //开启log4j内置日志记录
//        LogLog.setInternalDebugging(true);
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);
        //日志记录输出
        logger.fatal("fatal 1");
        logger.error("error 1");
        logger.warn("warn 1");
        logger.info("info 1");
        logger.debug("debug 1");
        logger.trace("trace 1");
    }
}

在这里插入图片描述
在这里插入图片描述
三方框架的日志信息打印(自定义logger,继承的形式):

log4j.properties:

log4j.rootLogger=INFO,conso

#自定义logger对象(会默认继承rootLogger:
# 级别会覆盖,由INFO升级为warn,但是既会向控制台输出:conso;
# 也会向文件file输出)
# 注意:这里自定义的com.base3,是Log4jTest类所在的包名路径
log4j.logger.com.base3 = warn,file
#第三方框架(org.apache.log4j.Logger)的错误日志打印,不指定appender,就是默认rootLogger的appender(conso)
log4j.logger.org.apache=error

log4j.appender.conso=org.apache.log4j.ConsoleAppender
log4j.appender.conso.layout=org.apache.log4j.PatternLayout
log4j.appender.conso.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

#日志文件输出的 appender对象
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日志文件保存路径
log4j.appender.file.file=./logs/xiaoxu_file.log
#指定日志文件的字符集
log4j.appender.file.encoding=UTF-8
package com.base3;

import org.apache.log4j.Logger;
import org.apache.log4j.helpers.LogLog;
import org.junit.Test;

public class Log4jTest {
    @Test
    public void testLogFj(){
        //开启log4j内置日志记录
//        LogLog.setInternalDebugging(true);
        //获取日志记录器对象
        Logger logger=Logger.getLogger(Log4jTest.class);
        //日志记录输出
        logger.fatal("fatal 1");
        logger.error("error 1");
        logger.warn("warn 1");
        logger.info("info 1");
        logger.debug("debug 1");
        logger.trace("trace 1");
        //三方框架的错误日志信息打印
        //因为log4j.properties文件中appender名是类名的包路径,
        //这里是org.apache.log4j.Logger,就可以继承log4j.properties的配置
        Logger logger1=Logger.getLogger(Logger.class);
        logger1.fatal("fatal apache1");
        logger1.error("error apache1");
        logger1.warn("warn apache1");
        logger1.info("info apache1");
        logger1.debug("debug apache1");
        logger1.trace("trace apache1");
    }
}

在这里插入图片描述
file中不会存入org.apache这个logger的日志,因为该logger没有指定appender,默认的rootLogger的appender只是输出到控制台的:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值