日志框架基本使用

文章详细介绍了Java日志框架的发展历程,从log4j到log4j2,再到SLF4J和logback的出现及其相互关系。同时,深入讲解了SLF4J的API工作原理,以及log4j2的配置细节,包括不同类型的Appender和日志级别设置。此外,还提到了logback的基本使用和配置示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请添加图片描述

日志框架背景

  1. log4j(作者Ceki Gülcü)出来时就等到了广泛的应用(注意这里是直接使用),是Java日志事实上的标准,并成为了Apache的项目

  2. Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增加了JUL(java.util.logging)

  3. 毕竟是JDK自带的,JUL也有很多人用。同时还有其他日志组件,如SimpleLog等。这时如果有人想换成其他日志组件,如log4j换成JUL,因为api完全不同,就需要改动代码。

  4. Apache见此,开发了JCL(Jakarta Commons Logging),即commons-logging-xx.jar。它只提供一套通用的日志接口api,并不提供日志的实现。很好的设计原则嘛,依赖抽象而非实现。这样应用程序可以在运行时选择自己想要的日志实现组件。

  5. 这样看上去也挺美好的,但是log4j的作者觉得JCL不好用,自己开发出slf4j,它跟JCL类似,本身不替供日志具体实现,只对外提供接口或门面。目的就是为了替代JCL。同时,还开发出logback,一个比log4j拥有更高性能的组件,目的是为了替代log4j。

  6. Apache参考了logback,并做了一系列优化,推出了log4j2。

  7. 各个日志框架必要的配置

    // 使用log4j,需要log4j.jar
    import org.apache.log4j.Logger;
    Logger logger_log4j = Logger.getLogger(Test.class);
    logger_log4j.info("Hello World!");
    
    // 使用log4j2,需要log4j-api.jar、log4j-core.jar
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    Logger logger_log4j2 = LogManager.getLogger(Test.class);
    logger_log4j2.info("Hello World!");
    
    // logback,需要logback-classic.jar、logback-core.jar
    import ch.qos.logback.classic.Logger;
    import ch.qos.logback.classic.LoggerContext;
    Logger logger_logback = new LoggerContext().getLogger(Test.class);
    logger_logback.info("Hello World!");
    
    // java.until.logging,简称jul
    import java.util.logging.Logger;
    Logger logger_jul = Logger.getLogger("java.Test");
    

SLF4J getLogger源码简单解析

  1. 部分源码

    private static final Logger logger = LoggerFactory.getLogger(MDCMain.class);
    
    public static Logger getLogger(Class<?> clazz) {
        Logger logger = getLogger(clazz.getName());
        //...
        return logger;
    }
    
    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }
    
    public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == 0) {
            Class var0 = LoggerFactory.class;
            synchronized(LoggerFactory.class) {
                if (INITIALIZATION_STATE == 0) {
                    INITIALIZATION_STATE = 1;
                    performInitialization();
                }
            }
        }
        switch(INITIALIZATION_STATE) {
            case 1:
                return SUBST_FACTORY;
            case 2:
                throw new IllegalStateException("org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
            case 3:
                //事实上,StaticLoggerBinder.getSingleton()
                //这里能直接加载到具体的实现类,log4j或logback,默认是logback,但不知道怎么找到的
                //具体实现类的路径/org/slf4j/impl/StaticLoggerBinder.class
                return StaticLoggerBinder.getSingleton().getLoggerFactory();
            case 4:
                return NOP_FALLBACK_FACTORY;
            default:
                throw new IllegalStateException("Unreachable code");
        }
    }
    
    private static final void performInitialization() {
        bind();
        if (INITIALIZATION_STATE == 3) {
            versionSanityCheck();
        }
    
    }
    
    private static final void bind() {
        try {
            String msg;
            try {
                Set<URL> staticLoggerBinderPathSet = null;
                if (!isAndroid()) {
                    //这里判断是否绑定多个路径的工厂,如果是打印日志提示,并取默认的logback
                    //判断的路径是/org/slf4j/impl/StaticLoggerBinder.class
                    staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
                    reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
                }
    
                StaticLoggerBinder.getSingleton();
                INITIALIZATION_STATE = 3;
                reportActualBinding(staticLoggerBinderPathSet);
            }
            //...
        }
        //...
    }
    
    /**存在logback和log4j2冲突时打印提示,并取logback绑定
    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/D:/maven-repository/ch/qos/logback/logback-classic/1.2.11/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/D:/maven-repository/org/apache/logging/log4j/log4j-slf4j-impl/2.17.2/log4j-slf4j-impl-2.17.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
    */
    

log4j2.xml详解

log4j2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",“.json"或者”.jsn"。

系统选择配置文件的优先级(从先到后)如下:
  (1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.
  (2).classpath下的名为log4j2-test.xml的文件.
  (3).classpath下名为log4j2.json 或者log4j2.jsn的文件.
  (4).classpath下名为log4j2.xml的文件.
  我们一般默认使用log4j2.xml进行命名。

  1. 根节点Configuration

    • status:用来指定log4j本身的打印日志的级别
    • monitorinterval:用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s
      两个子节点:
    • Appenders
    • Loggers(表明可以定义多个Appender和Logger).
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!-- status="OFF" 关闭log4j2自身日志,设置为trace会有各种log4j2的日志信息。-->
    <Configuration status="OFF" monitorInterval="60">
    </Configuration>
    
  2. Appenders节点

    常见的有三种子节点:Console、RollingFile、File

  3. Console节点用来定义输出到控制台的Appender

    • name:指定Appender的名字.
    • target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.
    • PatternLayout:输出格式,不设置默认为:%m%n.
    • File节点用来定义输出到指定位置的文件的Appender.
  4. File节点用来定义输出到指定位置的文件的Appender

    • name:指定Appender的名字.
    • fileName:指定输出日志的目的文件带全路径的文件名.
    • PatternLayout:输出格式,不设置默认为:%m%n.
    • RollingFile节点用来定义超过指定条件自动删除旧的创建新的Appender.
  5. RollingFile节点用来定义超过指定条件自动删除旧的创建新的Appender

    • name:指定Appender的名字.
    • fileName:指定输出日志的目的文件带全路径的文件名.
    • PatternLayout:输出格式,不设置默认为:%m%n.
    • filePattern : 指定当发生Rolling时,文件的转移和重命名规则.
    • Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
    • TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am.
    • SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.
    • DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。
  6. Loggers节点,常见的有两种:Root和Logger

    Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

    • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < - AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.
    • Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。
    • level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
    • name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
    • AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出
  7. log4j2.xml例子

    <?xml version="1.0" encoding="UTF-8"?>
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!-- 根节点Configuration:有 Appenders 和 Loggers 两个子节点。-->
    <!-- status="OFF" 关闭log4j2自身日志,设置为trace会有各种log4j2的日志信息。
    monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
    <configuration status="OFF" monitorInterval="60">
    	<!-- <property name="name">xxx</property> name是自己定义的内容,在当前内容中使用${name}:xxx的值获取,相当于设置变量 -->
        <properties>
            <!-- 服务器生产环境日志目录 -->
            <property name="SERVER_HOME_PATH">/home/java/logs/</property>
            <!-- 日志目录 -->
            <property name="LOG_HOME">${SERVER_HOME_PATH}</property>
            <!-- 日志备份目录 -->
            <property name="BACKUP_HOME">{LOG_HOME}/backup</property>
            <!-- 系统/服务名称 用于生成路径名称-->
            <property name="SERVER_NAME">bfs-web</property>
            <!-- 定义输出格式 -->
            <property name="PATTERN_MY">${LOG_HOME}/%date{yyyy-MM-dd}/${SERVER_NAME}/monitor-%d{yyyyMMdd-HH}.log">
                <PatternLayout pattern="[%TraceId] %T %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %.36c %-4L - %msg%xEx%n"</property>
        </properties>
        <appenders>
            <!-- 定义控制台输出 生产环境可以去掉-->
            <!-- SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT -->
            <Console name="Console" target="SYSTEM_OUT" follow="true">
             <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                <!--设置日志格式及颜色,具体格式解释在下面引用处-->
                <PatternLayout
                        pattern="[%T] [%style{%d{HH:mm:ss.SSS}}{bright,green}][%highlight{%-5level}][%style{%.36c %-4L}{bright,yellow}]: %msg%n%style{%throwable}{red}"
                        disableAnsi="false" noConsoleNoAnsi="false"/>
            </Console>
            <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
            <File name="FileLog" fileName="${BACKUP_HOME}/webTest.log" append="false">
                <PatternLayout pattern="${PATTERN_MY}"/>
            </File>
            <!-- 生产环境文件日志 -->
             <!-- immediateFlush:  -->
            <RollingRandomAccessFile name="ProductEnvLog" fileName="${LOG_HOME}/current/${SERVER_NAME}.log"
    immediateFlush="true"
    filePattern="${LOG_HOME}/%date{yyyy-MM-dd}/${SERVER_NAME}/monitor-%d{yyyyMMdd-HH}.log">
                <PatternLayout pattern="[%TraceId] %T %date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %.36c %-4L - %msg%xEx%n"/>
                <!-- 指定滚动日志的策略 -->
                <Policies>
                	<!-- TimeBasedTriggeringPolicy:Policies 子节点,基于时间的滚动策略。interval 属性根据日期模式中最具体的时间单位进行翻转的频率,默认为1。 -->
                    <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                    <!-- SizeBasedTriggeringPolicy:Policies 子节点,基于文件大小的滚动策略。size属性用来定义每个日志文件的大小。大小可以以字节为单位指定,后缀为KB,MB或GB,例如20MB。 -->
                     <SizeBasedTriggeringPolicy size="50MB" />
                     <!-- 以上两种策略2选1 -->
                </Policies>
            </RollingRandomAccessFile>
        </appenders>
        <loggers>
        	<!-- Root:指定项目的根日志,如果没有单独指定 Logger,那么默认使用该 Root 日志输出。-->
            <root level="info">
                <appender-ref ref="Console"/>
                <appender-ref ref="ProductEnvLog"/>
            </root>
            <!-- Logger:用来单独指定日志的形式。 -->
            <logger level="debug" name="com.bfs"/>
            <logger level="warn" name="org.apache.zookeeper.ZooKeeper"/>
        	<!-- 等等自由配置 -->
        </loggers>
    </configuration>
    

logback

  1. 基本使用

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.0.11</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.11</version>
    </dependency>
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Demo {
        //只需要slf4j-api和logback-classic即可基本使用,springboot默认依赖包已存在
        //这里并没有引用任何一个跟 Logback 相关的类,而是引用了 SLF4J 相关的类,这样在需要将日志框架切换为其它日志框架时,无需改动代码。
        private static final Logger logger = LoggerFactory.getLogger(Demo.class);
     
        public static void main(String[] args) {
            logger.info("Hello world");
        }
    }
    
  2. 分层命名规则

    例如, 命名为 com.wsl 的 logger,是命名为 com.wsl.test 的 logger 的父亲,是命名为 com.wsl.test.logback 的 logger 的祖先。

    在 logger 上下文中,有一个 root logger,作为所有 logger 的祖先,这是 logback 内部维护的一个 logger,并非开发者自定义的 logger。

    可通过以下方式获得这个 logger :

    Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
    
  3. 三个重要的类

    Logger 类位于 logback-classic 模块中, 而 Appender 和 Layout 位于 logback-core 中,这意味着, Appender 和 Layout 并不关心 Logger 的存在,不依赖于 Logger,同时也能看出, Logger 会依赖于 Appender 和 Layout 的协助,日志信息才能被正常打印出来。

    Appender 是绑定在 logger 上的,而 logger 又有继承关系,因此一个 logger 打印信息时的目的地 Appender 需要参考它的父亲和祖先。在 logback 中,默认情况下,如果一个 logger 打印一条信息,那么这条信息首先会打印至它自己的 Appender,然后打印至它的父亲和父亲以上的祖先的 Appender,但如果它的父亲设置了 additivity = false,那么这个 logger 除了打印至它自己的 Appender 外,只会打印至其父亲的 Appender,因为它的父亲的 additivity 属性置为了 false,开始变得忘祖忘宗了,所以这个 logger 只认它父亲的 Appender;此外,对于这个 logger 的父亲来说,如果父亲的 logger 打印一条信息,那么它只会打印至自己的 Appender中(如果有的话),因为父亲已经忘记了爷爷及爷爷以上的那些父辈了。

  4. 打印的方式

    //这种打印日志的方式有个缺点,就是无论日志级别是什么,程序总要先拼接字符串,再内部判断一次级别
    logger.debug("the message is " + msg + " from " + somebody);
    
    //这样的方式确实能避免字符串拼接的不必要损耗,但这也不是最好的方法,因为会有两次判断日志级别
    if(logger.isDebugEnabled()) { 
      logger.debug("the message is " + msg + " from " + somebody);
    }
    
    //有一种更好的方法,那就是提供占位符的方式,以参数化的方式打印日志
    logger.debug("the message {} is from {}", msg, somebody);
    
  5. 启动时读取文件

    在 classpath 中寻找 logback-test.xml文件
    如果找不到 logback-test.xml,则在 classpath 中寻找 logback.groovy 文件
    如果找不到 logback.groovy,则在 classpath 中寻找 logback.xml文件
    如果上述的文件都找不到,则 logback 会使用 JDK 的 SPI 机制查找 META-INF/services/ch.qos.logback.classic.spi.Configurator 中的 logback 配置实现类,这个实现类必须实现 Configuration 接口,使用它的实现来进行配置
    如果上述操作都不成功,logback 就会使用它自带的 BasicConfigurator 来配置,并将日志输出到 console

  6. 基本的logback.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
    
        <!--
            配置集中管理的属性
            直接使用该属性的value value格式":${name}
        -->
        <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>
        <!-- 日志文件存放目录 -->
        <property name="log_dir" value="D:/logback_test"/>
        <!--
            日志输出格式:
            %-5level 级别从左显示5个字符宽度
            %d{yyyy-MM-dd HH:mm:ss.SSS}日期
            %c类的完整名称
            %M为method
            %L为行号
            %thread线程名称
            %m或者%msg为信息
            %n换行
        -->
    
        <!--
            Appender: 设置日志信息的去向,常用的有以下几个
            ch.qos.logback.core.ConsoleAppender (控制台)
            ch.qos.logback.core.rolling.RollingFileAppender (文件大小到达指定尺
            寸的时候产生一个新文件)
            ch.qos.logback.core.FileAppender (文件)
        -->
    
        <!--控制日志输出位置的Appender-->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <!--控制台输出的对象 默认System.out 改为System.err 就变为了红色字体-->
            <target>System.out</target>
            <!--日志消息格式的配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
        </appender>
    
        <!--日志文件输出appender对象-->
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <!--日志格式配置-->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${pattern}</pattern>
            </encoder>
            <!--日志输出路径-->
            <file>${log_dir}/logback.log</file>
        </appender>
    
        <!--
            如果未设置level,那么当前logger将会继承上级的级别。
            additivity:
            是否向上级loger传递打印信息。默认是true。
        -->
        <root level="INFO">
            <appender-ref ref="console"/>
            <appender-ref ref="file"/>
        </root>
    </configuration>
    
  7. 日志拆分和归档Appender

    <!--日志拆分和归档Appender-->
    <appender name="rolling" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <!--日志输出路径-->
        <file>${log_dir}/roll_logback.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--指定具体实现规则-->
            <!--按照时间和压缩格式声明拆分的文件名-->
            <!--            <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd-HH-mm-ss}.log%i.gz</fileNamePattern>-->
            <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd-HH}.log%i.gz</fileNamePattern>
            <!--日志文件的保存期限-->
            <maxHistory>15</maxHistory>
            <!--按照文件大小拆分-->
            <maxFileSize>10KB</maxFileSize>
        </rollingPolicy>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="rolling"/>
    </root>
    

    日志文件

  8. 日志级别过滤

    <appender name="rolling" class="ch.qos.logback.core.rolling.RollingFileAppender">
        ...
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--日志过滤规则-->
            <level>INFO</level>
            <!--超过当前级别放行-->
            <onMath>ACCEPT</onMath>
            <!--小于当前级别拦截-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
  9. 异步日志实现(root标签要放最后)

    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <!--指定某个具体的Appender实现-->
        <appender-ref ref="rolling"/>
    </appender>
    <root level="ALL">
        <appender-ref ref="async"></appender-ref>
    </root>
    
  10. 自定义logger设置additivity为false,避免重复打印日志浪费空间

    <!--【强制】避免重复打印日志,浪费磁盘空间,务必在日志配置文件中设置 additivity=false。-->
    <!--自定义logger additivity自定义logger对象是否继承rootLogger-->
    <logger name="com.linp.mypro1.task" level="warn" additivity="false">
        <appender-ref ref="console"></appender-ref>
    </logger>
    
  11. logback默认配置

    <!--base.xml-->
    <?xml version="1.0" encoding="UTF-8"?>
    <included>
       <include resource="org/springframework/boot/logging/logback/defaults.xml" />
       <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
       <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
       <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
       <root level="INFO">
          <appender-ref ref="CONSOLE" />
          <appender-ref ref="FILE" />
       </root>
    </included>
    
    <!--console-appender.xml-->
    <included>
    	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    		<encoder>
    			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
    			<charset>${CONSOLE_LOG_CHARSET}</charset>
    		</encoder>
    	</appender>
    </included>
    
    <!--file-appender.xml-->
    <included>
    	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    		<encoder>
    			<pattern>${FILE_LOG_PATTERN}</pattern>
    			<charset>${FILE_LOG_CHARSET}</charset>
    		</encoder>
    		<file>${LOG_FILE}</file>
    		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    			<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
    			<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
    			<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
    			<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
    			<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
    		</rollingPolicy>
    	</appender>
    </included>
    
    <!--defaults.xml-->
    <included>
    	<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    	<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    	<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    
    	<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    	<property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-${file.encoding:-UTF-8}}"/>
    	<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    	<property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-${file.encoding:-UTF-8}}"/>
    
    	<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
    	<logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/>
    	<logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/>
    	<logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/>
    	<logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/>
    	<logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/>
    	<logger name="org.hibernate.validator.internal.util.Version" level="WARN"/>
    	<logger name="org.springframework.boot.actuate.endpoint.jmx" level="WARN"/>
    </included>
    

Pattern

LOG4J PatternLayout

  1. log4j占位符含义

    c	使用它为输出的日志事件分类,比如对于分类 "a.b.c",模式 %c{2} 会输出 "b.c" 。
    C	使用它输出发起记录日志请求的类的全名。比如对于类 "org.apache.xyz.SomeClass",模式 %C{1} 会输出 "SomeClass"。
    d	使用它输出记录日志的日期,比如 %d{HH:mm:ss,SSS} 或 %d{dd MMM yyyy HH:mm:ss,SSS}。
    F	在记录日志时,使用它输出文件名。
    l	用它输出生成日志的调用者的地域信息。
    L	使用它输出发起日志请求的行号。
    m	使用它输出和日志事件关联的,由应用提供的信息。
    M	使用它输出发起日志请求的方法名。
    n	输出平台相关的换行符。
    p	输出日志事件的优先级。
    r	使用它输出从构建布局到生成日志事件所花费的时间,以毫秒为单位。
    t	输出生成日志事件的线程名。
    x	输出和生成日志事件线程相关的 MDC (嵌套诊断上下文)。
    X	该字符后跟 MDC 键,比如 X{clientIP} 会输出保存在 MDC 中键 clientIP 对应的值。
    %	百分号, %% 会输出一个 %。
    

Logback Pattern

  1. logback占位符含义

    <!-- 输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边点符号之后的字符串。-->
    <!-- %logger mainPackage.sub.sample.Bar 	mainPackage.sub.sample.Bar-->
    <!-- %logger{5} mainPackage.sub.sample.Bar 	m.s.s.Bar-->
    %c {length }
    %lo {length }
    %logger {length }
    
    <!-- 输出执行记录请求的调用者的全限定名。参数与上面的一样。尽量避免使用,除非执行速度不造成任何问题。-->
    %C {length }
    %class {length }
    
    <!--输出上下文名称。-->
    %contextName
    %cn
    
    <!-- 输出日志的打印日志,模式语法与java.text.SimpleDateFormat 兼容。-->
    <!-- %d 2006-10-20 14:06:49,812 -->
    <!-- %date 2006-10-20 14:06:49,812 -->
    <!-- %d{yyyy-MM-dd HH:mm:ss.SSS} 2006-10-20 14:06:49,812 -->
    %d {pattern }
    %date {pattern }
    
    <!--输出执行记录请求的java源文件名。尽量避免使用,除非执行速度不造成任何问题。-->
    %F / %file
    
    <!--输出生成日志的调用者的位置信息,整数选项表示输出信息深度。-->
    %caller{depth} %caller{depth, evaluator-1, ... evaluator-n}
    
    <!--输出执行日志请求的行号。尽量避免使用,除非执行速度不造成任何问题。-->
    %L / %line
    
    <!--输出应用程序提供的信息。-->
    %m / %msg / %message
    
    <!--输出执行日志请求的方法名。尽量避免使用,除非执行速度不造成任何问题。-->
    %M / %method
    
    <!--输出平台先关的分行符“\n”或者“\r\n”。-->
    %n
    
    <!--输出日志级别。-->
    %p / %le / %level
    
    <!--输出从程序启动到创建日志记录的时间,单位是毫秒-->
    %r / %relative
    
    <!--输出产生日志的线程名。-->
    %t / %thread
    
    <!--p 为日志内容,r 是正则表达式,将p 中符合r 的内容替换为t 。-->
    <!--例如, "%replace(%msg){'\s', ''}"-->
    %replace(p ){r, t}
    
    <!--%X用于输出和当前线程相关联的NDC(嵌套诊断环境),在代码中给org.slf4j.MDC添加key/value即可增加新值-->
    <!--%X{testKey:-aaa} 输出testKey所对应的value,默认为aaa-->
    %X
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值