Java常用日志框架--log4j

系列文章目录

1.log4j概述

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

2.入门案例

1)引入log4j的依赖

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

2)书写入门案例

 @Test
    public void test07() throws IOException {
        /*
        Log4j入门案例
        注意加载初始化信息: BasicConfigurator.configure();
         */
        //加载初始化配置
        BasicConfigurator.configure();

        Logger logger = Logger.getLogger(LogDemoCtroller.class);

        logger.info("info信息");

    }
    输出:
    九月 18, 2022 4:48:33 下午 com.form.project.test.LogDemoCtroller test07
	信息: info信息

3.日志级别

日志级别说明,Log4j提供了8个级别的日志输出,分别为:
ALL:最低等级,用于打开所有级别的日志记录
TRACE:程序推进下的追踪信息,这个追踪信息的日志级别非常低,一般情况下是不会使用的
DEEUG:指出细粒度信息事件对调试应用程序是非常有帮助的,主要是配合开发,在开发过程中打印一些重要的运行信息
INFO:消息的粗粒度级别运行信息
WARN:表示警告,程序在运行过程中会出现的有可能会发生的隐形的错误,注意,有些信息不是错误,但是这个级别的输出目的就是为了给程序员以提示
ERROR:系统的错误信息,发生的错误不影响系统的运行,一般情况下,如果不想输出太多的日志,则使用该级别即可
FATAL:表示严重错误,它是那种一旦发生系统就不可能继续运行的严重错误,如果这种级别的错误出现了,表示程序可以停止运行了
OFF:最高等级的级别,用户关闭所有的日志记录

//日志级别输出打印,默认的级别为debug
  @Test
    public void test07() throws IOException {
        /*
        Log4j入门案例
        注意加载初始化信息: BasicConfigurator.configure();
        日志级别:

         */
        //加载初始化配置
        BasicConfigurator.configure();

        Logger logger = Logger.getLogger(LogDemoCtroller.class);

        logger.fatal("fatal信息");
        logger.error ("error信息");
        logger.warn("warn信息");
        logger.info("info信息");
        logger.debug("debug信息");
        logger.trace("trace信息");
    }
    输出:
0 [main] FATAL com.form.project.test.LogDemoCtroller  - fatal信息
0 [main] ERROR com.form.project.test.LogDemoCtroller  - error信息
0 [main] WARN  com.form.project.test.LogDemoCtroller  - warn信息
0 [main] INFO  com.form.project.test.LogDemoCtroller  - info信息
0 [main] DEBUG com.form.project.test.LogDemoCtroller  - debug信息

4.log4j.properties的加载与配置

Logger logger = Logger.getLogger(Log4jTest01.class);
进入到getLogger方法,会看到代码:
LogManager.getLogger(clazz.getName());
LogManager:日志管理器
点击LogManager,看看这个日志管理器中都实现了什么
看到很多常量信息,他们代表的就是不同形式(后缀名不同)的配置文件
我们最常使用到的肯定是1og4j.properties属性文件(语法简单,使用方便)

问题:log4j.properties的加载时机
加载完毕后我们来观察配胃文件是如何读取的?
继续观察LogManager,找到其中的静态代码块static,在static代码块中,我们找到
Optionconverter.selectAndConfigure(url,configuratorClassName,getLoggerRepository());
作为属性文件的加载,执行相应的properties配置对象:
configurator = new PropertyConfigurator();
进入到Propertyconfigurator类中,观察到里面的常量信息
这些常量信息就是我们在properties屑性文件中的各种属性配置项
其中,我们看到了如下两项信息,这两项信息是必须要进行配置的
static final String ROOT_LOGGER_PREFIX = “log4j.rootLogger”;
static final String APPENDER_PREFIX = “log4j.appender.”;

通过代码:
String prefix = “log4j.appender.” + appenderName;
我们需要自定义一个appenderName,我们起名叫做console,
log4j.appender.console
取值就是log4j中为我们提供的apender类
例如:
log4j.appender.console=org.apache.log4j.ConsoleAppender
在appender输出的过程中,还可以同时指定输出的格式
通过代码:
String layoutPrefix = prefix + “.layout”;
配置:
log4j.appender.console.layout=org.apache.log4j.simpleLayout请添加图片描述
1)通过在log4j.rootLogger继续在PropertyConfigurator类中搜索相关源代码,找到void configureRootCategory方法,在这个方法中执行了this.parseCategory方法。
2)观察该方法:找到代码StringTokenizer st = new StringTokenizer(value, “,”);表示以逗号分割的方式来切割字符串,证明了log4j.rootLogger的取值,其中可以有多个值,使用逗号进行分隔。
3)通过代码: String levelStr = st.nextToken();表示切割后的第一个值是日志的级别。
4)通过代码:while(st.hasMoreTokens()),表示接下来的值,是可以通过while循环遍历得到的,第2个~第n个值,就是我们配置的其他的信息,这个信息就是appenderName,证明了我们配置的方式
5)log4j.rootLogger=日志级别,appenderName1,appenderName2,appenderName3…
表示可以同时在根节点上配置多个日志输出的途径
所以log4j.rootLogger的配置方式如下:
代码为:

 @Test
    public void test08() throws IOException {
       
        //BasicConfigurator.configure();

        Logger logger = Logger.getLogger(LogDemoCtroller.class);

        logger.fatal("fatal信息");
        logger.error ("error信息");
        logger.warn("warn信息");
        logger.info("info信息");
        logger.debug("debug信息");
        logger.trace("trace信息");
    }

配置文件为:

log4j.rootLogger=trace,console
#配置appender输出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#配置输出的格式
log4j.appender.console.layout=org.apache.log4j.SimpleLayout

输出为:

FATAL - fatal信息
ERROR - error信息
WARN - warn信息
INFO - info信息
DEBUG - debug信息
TRACE - trace信息

5.log4j日志输出详细信息开关

1)通过Logger中的开关,可以输出日志的详细信息
2)查看LogManager类中的方法getLoggerRepository(),找到LogLog.debug(msg, ex); LogLog会使用debug级别的输出为我们展现日志输出详细信息,Logger是记录系统的体脂,那么LogLog是用来记录Logger的日志

进入到Logger.debug(msg,ex);方法中,通过代码: if (debugEnabled && !quietMode),观察到if判断中的这个两个开关都必须开启才行,quietMode是启动状态,不需要我们去管,debugEnabled默认是关闭的,所以我们需要设置debugEnabled为true
代码:

  @Test
    public void test09() throws IOException {
        /*
        通过Logger中的开关,打开日志输出的详细信息
         */
        LogLog.setInternalDebugging(true);
        Logger logger = Logger.getLogger(LogDemoCtroller.class);

        logger.fatal("fatal信息");
        logger.error ("error信息");
        logger.warn("warn信息");
        logger.info("info信息");
        logger.debug("debug信息");
        logger.trace("trace信息");
    }

输出:

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/Users/chezhewei/Desktop/project/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/Users/chezhewei/Desktop/project/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
FATAL - fatal信息
ERROR - error信息
WARN - warn信息
INFO - info信息
DEBUG - debug信息
TRACE - trace信息

6.log4j的输出格式

关于log4j.properties layout属性的配置,其中PatternLayout是日常使用最多的方式,查看其源码,setConversionPattern这个方法是该PatternLayout的核心方法
在log4j.properties中将 layout设置为PatternLayout,我们主要配置的是conversionPattern属性
%m 输出代码中指定的日志信息 (message)
%p 输出优先级,及 DEBUG、IFO 等
%n 换行符(Windows 平台的换行符为 “\n”,Unix 平台为"\n"),
%r 输出自应用启动到输出该 1og 信息耗费的亳秒数
%c 输出打印语句所属的类的全名
%t 输出产生该日志的线程全名
%d 输出服务器当前时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM 月dd 日
HH:mm:ss}
%l 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test. java:10)
%F 输出日志消息产生时所在的文件名称
%L 输出代码中的行号
%% 输出一个"%“字符
可以在 %与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对其方式。如:
%5c 输出 category 名称,最小宽度是5,category<5,默认的情况下右对齐4
%-5c 输出 category 名称,最小宽度是5,category<5,”-"号指定左对齐,会有空格
%.5c 输出 category 名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不
会有空格
%20.30c category 名称<20 补空格,并且右对齐,>30字符,就从左边多出的字符截掉
[%10p]:[ ]中必须有10个字符,由空格来进行补齐,信息右对齐
[%-10p]:[ ]中必须有10个字符,由空格来进行补齐,信息左对齐,应用广泛
配置文件改为:

log4j.rootLogger=trace,console
#配置appender输出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#配置输出的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

代码不变:

 @Test
    public void test10() {
        /*
        通过Logger中的开关,打开日志输出的详细信息
         */
        LogLog.setInternalDebugging(true);
        Logger logger = Logger.getLogger(LogDemoCtroller.class);

        logger.fatal("fatal信息");
        logger.error ("error信息");
        logger.warn("warn信息");
        logger.info("info信息");
        logger.debug("debug信息");
        logger.trace("trace信息");
    }

输出:

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/Users/chezhewei/Desktop/project/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/Users/chenzhenwei/Desktop/project/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [[%p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
[FATAL]0 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:738 fatal信息
[ERROR]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:739 error信息
[WARN]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:739 warn信息
[INFO]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:739 info信息
[DEBUG]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:739 debug信息
[TRACE]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 22:56:23:739 trace信息

可以注意到打印出来的日志是不对齐,把[%p]改成[%-10p],输出如下:

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
log4j: Using URL [file:/Users/chezhewei/Desktop/project/target/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/Users/chenzhenwei/Desktop/project/target/classes/log4j.properties
log4j: Parsing for [root] with value=[trace,console].
log4j: Level token is [trace].
log4j: Category root set to TRACE
log4j: Parsing appender named "console".
log4j: Parsing layout options for "console".
log4j: Setting property [conversionPattern] to [[%-10p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n].
log4j: End of parsing for "console".
log4j: Parsed "console" options.
log4j: Finished configuring.
[FATAL     ]0 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:246 fatal信息
[ERROR     ]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:247 error信息
[WARN      ]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:247 warn信息
[INFO      ]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:247 info信息
[DEBUG     ]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:247 debug信息
[TRACE     ]1 com.tang.project1.test.LogDemoCtrollermain2022-09-19 23:04:37:247 trace信息

6.log4j将日志输出到文件中

6.1 将日志输出到文件中的配置

1)log4j中appender的功能:用于定义输出文件的方式
有以下5种输出方式可定义
1.org.apache.log4j.RollingFileAppender(滚动文件,自动记录最新日志)
2.org.apache.log4j.ConsoleAppender (控制台)
3.org.apache.log4j.FileAppender (文件)
4.org.apache.log4j.DailyRollingFileAppender (每天产生一个日志文件)
5.org.apache.log4j.WriterAppender (将日志信息以流格式发送到任意指定的地方)

#trace是日志级别,console和Myfile都是AppenderName,对应控制台输出的console和文件输出的Myfile,rootLogger要下面的 appender.xxx对应,不然就会报错,无法输出
log4j.rootLogger=trace,console,Myfile
#配置appender输出方式 输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
#配置输出的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%x] - %m%n

#配置appender输出方式 输出到文件
log4j.appender.Myfile=org.apache.log4j.FileAppender
#配置输出的格式
log4j.appender.Myfile.layout=org.apache.log4j.PatternLayout
log4j.appender.Myfile.layout.ConversionPattern=%d [%x] - %m%n
#配置日志文件输出路径,file是用来指定文件位置的属性
log4j.appender.Myfile.file=/Users/chezhewei/Desktop/log4j.log
log4j.appender.Myfile.encoding=UTF-8

2)查看源码了解到fileAppend,表示是否追加信息,通过构造方法赋值为true。 bufferSize表示缓冲区大小,通过构造方法赋值为8192。继续观察,找到setFile方法,这个方法就是用来指定文件位置的方法,通过ognl,可以推断setFile方法操作的属性就是File。
观察FileAppender的父类WriterAppender可以看到 protected String encoding;属性,可以用来设置编码格式。
OGNL表达式用法详解

public class FileAppender extends WriterAppender {
    protected boolean fileAppend;
    protected String fileName;
    protected boolean bufferedIO;
    protected int bufferSize;

    public FileAppender() {
        this.fileAppend = true;
        this.fileName = null;
        this.bufferedIO = false;
        this.bufferSize = 8192;
    }
     public FileAppender(Layout layout, String filename, boolean append, boolean bufferedIO, int bufferSize) throws IOException {
        this.fileAppend = true;
        this.fileName = null;
        this.bufferedIO = false;
        this.bufferSize = 8192;
        this.layout = layout;
        this.setFile(filename, append, bufferedIO, bufferSize);
    }

    public FileAppender(Layout layout, String filename, boolean append) throws IOException {
        this.fileAppend = true;
        this.fileName = null;
        this.bufferedIO = false;
        this.bufferSize = 8192;
        this.layout = layout;
        this.setFile(filename, append, false, this.bufferSize);
    }

    public FileAppender(Layout layout, String filename) throws IOException {
        this(layout, filename, true);
    }

    public void setFile(String file) {
        String val = file.trim();
        this.fileName = val;
    }

6.2 Log4j文件拆分

6.2.1 RollingFileAppender:按照文件大小进行拆分

RollingFileAppender表示使用按照文件带下进行拆分的方式进行操作,配置文件进行RollingFileAppender相关配置,如何进行拆分,观察RollingFileAppender的源码,
protected long maxFileSize = 10485760L;//表示拆分文件的大小
protected int maxBackupIndex = 1;//表示拆分文件的数量

log4j.rootLogger=trace,rollingFile
#配置appender输出方式 拆分文件
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
#配置输出的格式
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d [%x] - %m%n
#配置日志文件输出路径
log4j.appender.rollingFile.file=/Users/chenzhenwei/Desktop/log4j.log
log4j.appender.rollingFile.encoding=UTF-8
#拆分文件的大小为1MB
log4j.appender.rollingFile.maxFileSize=1MB
#拆分文件的数量为5个
log4j.appender.rollingFile.maxBackupIndex=5

如果超过了5个文件,多出来的日志就会从第一个文件开始进行日志的覆盖,保留新的日志,覆盖旧的日志。

6.2.2 DailyRollingFileAppender:按照时间进行日志拆分

查看源码属性:
private String datePattern = “'.'yyyy-MM-dd”;//默认是按照天来进行拆分的

#DailyRollingFileAppender的配置 拆分文件
log4j.appender.dailyRollingFile=org.apache.log4j.DailyRollingFileAppender
#配置输出的格式
log4j.appender.dailyRollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFile.layout.ConversionPattern=%d [%x] - %m%n
#配置日志文件输出路径
log4j.appender.dailyRollingFile.file=/Users/chenzhenwei/Desktop/log4j.log
log4j.appender.dailyRollingFile.encoding=UTF-8
#等不了一天了,设置时间到秒的程度
log4j.appender.dailyRollingFile.datePattern='.'yyyy-MM-dd HH-mm-ss

6.自定义Logger

查看PropertyConfigurator的源码得到信息:static final String LOGGER_PREFIX = “log4j.logger.”;这个属性值og4j.logger.就是我们在配置文件中对于自定义logger的配置属性
如果根节点的logger和自定义父logger配置的输出位置是不同的,取两者的并集,配置的位置都会进行输出操作。如果两者配置的日志级别不同,以自定义的父logger级别为主。

log4j.logger.com.test=ALL,test
log4j.additivity.test = false
log4j.appender.test=org.apache.log4j.FileAppender
log4j.appender.test.File=E:/test.log
log4j.appender.test.layout=org.apache.log4j.PatternLayout
log4j.appender.test.layout.ConversionPattern=[Inspur][%d{yyyy-MM-dd HH:mm:ss}][ %-5p] %C.%M(%L) %x- %m%n

以上为自定义日志的配置代码,log4j.logger.com.test=ALL,test是为特定的类配置特定自定义配置引入。com.test是类的全路径,all代表五种等级的日志都包含;log4j.additivity.test = false标识子Logger只在自己的 appender中输出日志,而不会在父Logger中输出。

总结

视频地址
https://www.bilibili.com/video/BV1Mb4y1Z74W?p=54&spm_id_from=pageDriver&vd_source=0345cd327c80ac53ca0b7e5e9ded8130

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值