log4j学习

依赖

xml 复制代码
<!--log4j依赖-->
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>

<!--测试-->
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>RELEASE</version>
  <scope>compile</scope>
</dependency>

入门案例以及日志级别说明

java 复制代码
@Test
public void test01() {

  /*
            Log4入门案例
                注意在家初始化信息:BasicConfigurator.configure();

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

                其中 DEBUG 是默认的日志输出级别
         */
  // 加載初始化配置
  BasicConfigurator.configure();

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

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

配置文件说明

properties 复制代码
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 = %r [%t] %p %c %x - %m%n
java 复制代码
@Test
public void test02() {
  /*
            配置文件的说明
                1、观察原源码  BasicConfigurator.configure();
                    可以得到两条信息
                    (1)创建根节点对象 Logger root = Logger.getRootLogger();
                    (2)根节点添加了ConsoleAppender对象(表示默认打印到控制台,自定义的格式化输出)

                2、不使用 BasicConfigurator.configure();加载
                    使用自定义的配置文件来实现功能
                    通过对上边第一点的输出
                    配置文件需要提供Logger、Appender、Layout 3个组件信息(通过配置文件来代替代码)

                    分析
                    Logger logger = Logger.getLogger(Log4jTest.class);

                    进入到getLogger方法,会看到代码
                    LogManager.getLogger(clazz.getName());
                    LogManager:是一个日志管理器

                    LogManager,里边有很多常量,它们代表的就是不同形式(后缀名不同)的配置文件
                    最常使用的就是log4j.properties 这个属性文件(语法简单,使用方便)

                问题:log4j.properties的加载时机
                     找到LogManager的static代码块
                     在static下遭到下列代码
                     Loader.getResource("log4j.properties");
                     系统会去当前类路径下找到log4j.properties这个文件进行加载
                     对于maven工程resource目录就是当前类路径下的

                     加载完毕后,配置文件是如何读取呢?
                     OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository());
                     进去方法:
                     作为属性文件进行加载: configurator = new PropertyConfigurator();
                     进入到这个PropertyConfigurator这个属性类,看到很多常量,这些常量就是我们在属性配置文件中的配置项
                     如下两项是我们必须配置的
                     static final String ROOT_LOGGER_PREFIX   = "log4j.rootLogger";
                     static final String      APPENDER_PREFIX = "log4j.appender.";

                     通过这行代码:
                     String prefix = APPENDER_PREFIX + appenderName;
                     我们需要自定义一个appendername 假设蛇我们去的名字是console 就是控制台输出
                     (起名字需要见名之意,console那么我们在配置应该配置控制台输出)
                     log4j.appender.console
                     取值就是log4j中为我们提供的appender类
                     例如
                        log4j.appender.console = org.apache.log4j.ConsoleAppender
                     还可以指定输出格式
                     通过代码:
                        String layoutPrefix = prefix + ".layout";
                     配置:
                        log4j.appender.console.layout = org.apache.log4j.SimpleLayout

                    通过log4j.properties继续在类中搜索
                    找到方法void configureRootCategory
                    在这个方法中找到执行了parseCategory 方法
                    观察这个方法:
                    执行了代码:StringTokenizer st = new StringTokenizer(value, ",");
                    表示要以逗号的方式分割字符串,证明了log4j.rootLogger的取值,其中可以有多个值,但是要以逗号进行分割

                    通过代码:
                    String levelStr = st.nextToken();
                    表示切割后的第一个值是日志的级别

                    通过代码:
                    while(st.hasMoreTokens())
                    表示接下2~n个都是可以通过循环来取得的,具体的内容是:appenderName(日志输出到哪里)
                    证明我们配置方式是:
                        log4j.rootLogger = 日志级别,appenderName1,appenderName2,...,appenderName n
                    表示我们可以同时在根节点上配置多个日志输出的途径

                    通过我们自己的配置文件就可以加载和这个代码了

         */
  // BasicConfigurator.configure();

  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 复制代码
@Test
public void test03(){
  /*

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


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

         */

  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信息");
}

关于log4j.properties 的 layout 的说明

properties 复制代码
log4j.appender.console.layout.conversionPattern = %r [%t] %p %c %x - %m%n

-X号: X信息输出时左对齐;
%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%c: 输出日志信息所属的类目,通常就是所在类的全名
%t: 输出产生该日志事件的线程名
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.Java:10)
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像Javaservlets这样的多客户多线程的应用中。
%%: 输出一个"%"字符
%F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息
%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行

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

1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。

2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。

3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。

4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。

java 复制代码
@Test
public void test04() {
  /*

            关于log4j.properties 的 layout 的说明
                其中PatternLayout 是日常使用最多的方式
                查看源码
                setConversionPattern这个方式就是PatterLayout的核心方法
                conversionPattern

                在log4j.properties 这个文件中将layout设置为PatterLayout
                主要配置的属性是conversionPatter

                [%p]%r %c %t %d{yyyy:MM:dd HH:mm:ss} %m %n
                可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式
                [%p]%r %c %t %d{yyyy:MM:dd HH:mm:ss} %m %n
                [%-5p] 左对齐5个字符,不足5个空格补齐
                [%5p] 右对齐5个字符,不足5个空格补齐
          */

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

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

}

将日志输出到文件中

properties 复制代码
# 第一个是日志输出级别 2-n是appenderName(就是日志在哪里展示)
log4j.rootLogger = trace,file
# 配置appender 输出方式 日志输出到哪里,输出到文件
log4j.appender.file = org.apache.log4j.FileAppender
# 表示输出的格式
log4j.appender.file.layout = org.apache.log4j.PatternLayout
# 自定义layout输出的内容
log4j.appender.file.layout.conversionPattern =  [%-5p]%r %c %t %d{yyyy:MM:dd-HH:mm:ss} %m %n
# 文件存储的位置 第一个file是我们自己命名的appenderName 第二个file是我们用来指定文件位置的属性
log4j.appender.file.file = E://test//log4j.log
# 配置输出的字符编码
log4j.appender.file.encoding = utf-8
java 复制代码
@Test
public void test05() {
  /*

            将日志输出到文件中
            console是输出控制台的,将日志输出到文件中,也可以做多方向的输出


          查看FileAppender的源码
          查看属性信息
          protected boolean fileAppend = true; 表示是否追加日志信息,true表示追加
          protected int bufferSize = 8*1024; 缓冲区的大小 kb
          继续观察找到 setFile 方法 设置文件的位置
          通过ognl可以推断出setFile这个方法操作的就是File

          如果有输出中文的需求怎么办
          观察FileAppender的父类 WriterAppender
          protected String encoding; 有一个这个属性,就是来设置日志输出的字符编码

         */

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

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


}

日志太大对其进行分割----按照文件大小

properties 复制代码
# 第一个是日志输出级别 2-n是appenderName(就是日志在哪里展示)
log4j.rootLogger = trace,rollingFile
# 配置RollingFileAppender 输出方式 日志输出到哪里,输出到文件
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
# 表示输出的格式
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
# 自定义layout输出的内容
log4j.appender.rollingFile.layout.conversionPattern =  [%-5p]%r %c %t %d{yyyy:MM:dd-HH:mm:ss} %m %n
# 文件存储的位置 第一个file是我们自己命名的appenderName 第二个file是我们用来指定文件位置的属性
log4j.appender.rollingFile.file = E://test//log4j.log
# 配置输出的字符编码
log4j.appender.rollingFile.encoding = utf-8
# 指定日志文件内容大小 1兆b 超过就进行拆分
log4j.appender.rollingFile.maxFileSize = 1MB
# 指定日志拆分的数量
log4j.appender.rollingFile.maxBackupIndex = 5
java 复制代码
@Test
public void test06() {
  /*
            将日志输出到文件中
                日志太多了,不方便管理怎么维护
                FileAppender为我们提供了好用的子类来进一步对文件输出进行处理
                RollingFileAppender
                DailyRollingFileAppender

                1、RollingFileAppender
                    这个类表示按照文件的大小来进行拆分的方式进行操作
                    配置文件进行RollingFileAppender的相关配置

                    如何拆分,观察RollingFileAppender的源码
                    protected long maxFileSize = 10*1024*1024;表示拆分文件的大小,默认是10m
                    protected int  maxBackupIndex  = 1; 拆分文件的书名


                    # 指定日志文件内容大小 1兆b 超过就进行拆分
                    log4j.appender.rollingFile.maxFileSize = 1MB
                    # 指定日志拆分的数量
                    log4j.appender.rollinFile.maxBackupIndex = 5

                    只要文件超过1MB,那么则会生成另外一个文件,文件的数量最多是5个
                    文件1 记录日志 1MB
                    文件2 记录日志 1MB
                    ...
                    ...
                    文件5 记录日志 1MB

                    如果5个文件不够怎么办,作为日志管理来说,也不可能让日志无休止的继续增长下去
                    所以,覆盖策略,按照时间来进行覆盖,原则就是保留新的,覆盖旧的

         */

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

  for (int i = 0; i < 10000; i++) {
    logger.fatal(i + "fatal信息" );
    logger.error(i + "error信息");
    logger.warn(i + "warn信息");
    logger.info(i + "info信息");
    logger.debug(i + "debug信息");
    logger.trace(i + "trace信息");
  }

日志太大对其进行分割----按照时间大小

配置文件

properties 复制代码
# 第一个是日志输出级别 2-n是appenderName(就是日志在哪里展示)
log4j.rootLogger = trace,dailyRollingFile
# 配置DailyRollingFileAppender 输出方式 日志输出到哪里,输出到文件
log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender
# 表示输出的格式
log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout
# 自定义layout输出的内容
log4j.appender.dailyRollingFile.layout.conversionPattern =  [%-5p]%r %c %t %d{yyyy:MM:dd-HH:mm:ss} %m %n
# 文件存储的位置 第一个file是我们自己命名的appenderName 第二个file是我们用来指定文件位置的属性
log4j.appender.dailyRollingFile.file = E://test//log4j.log
# 配置输出的字符编码
log4j.appender.dailyRollingFile.encoding = utf-8
# 根据时间来进行拆分
# 设置DatePattern属性为'.'yyyy-ww 这个是按照周来进行拆分日志
log4j.appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd HH-mm-ss
相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码9 天前
嵌入式学习路线
学习
毛小茛9 天前
计算机系统概论——校验码
学习
babe小鑫9 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms9 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下9 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。9 天前
2026.2.25监控学习
学习
im_AMBER9 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J9 天前
从“Hello World“ 开始 C++
c语言·c++·学习