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
相关推荐
怀旧6661 小时前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
测试界的酸菜鱼1 小时前
C# NUnit 框架:高效使用指南
开发语言·c#·log4j
五羟基己醛2 小时前
【通义灵码】AI编码新时代
log4j
infiniteWei2 小时前
【Lucene】原理学习路线
学习·搜索引擎·全文检索·lucene
follycat2 小时前
[极客大挑战 2019]PHP 1
开发语言·学习·网络安全·php
并不会6 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
龙鸣丿7 小时前
Linux基础学习笔记
linux·笔记·学习
Nu11PointerException9 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
@小博的博客12 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生13 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法