【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板

news2024/11/13 10:12:38

文章目录

  • 一、日志框架介绍
    • 1、浅谈与slfj4、log4j、logback的关系
    • 2、性能方面
    • 3、Slf4j使用方法
  • 二、log4j配置
  • 三、log4j2配置
    • 1、SpringBoot整合Log4j2
    • 2、非SpringBoot项目引入的依赖
    • 3、log4j2-spring.xml文件(Spring项目)或log4j2.xml(非Spring项目)
  • 四、logback配置


一、日志框架介绍

1、浅谈与slfj4、log4j、logback的关系

  • Slf4j

SLF4J(Simple Logging Facade for Java)是一个日志框架的抽象层,可以与不同的日志实现进行绑定。它允许开发人员在代码中使用统一的日志接口,而无需关心具体的日志实现。

简单来讲就是slf4j是一系列的日志门面,也可以理解为 slf4j 是接口,而 logbacklog4j具体实现了这些接口的日志框架,slf4j 具备很高的易用性和很好的抽象性。

  • Log4j

Logback是Log4j的后继版本,由Log4j的作者开发。相比Log4j,Logback具有更好的性能和更丰富的功能,同时也更易于配置和扩展。

  • Logback

Logback是Log4j的后继版本,由Log4j的作者开发。相比Log4j,Logback具有更好的性能和更丰富的功能,同时也更易于配置和扩展。

  • Log4j2

log4j2是log4j的代替升级版,之前log4j曾爆出“核弹级”漏洞,现在已经不推荐使用了。

在这里插入图片描述


2、性能方面

在测试环境和条件相同的情况下,log4j2 全面优于 logback, log4j2性能是 logback的两倍。

建议使用Log4j2,因为它是三种框架中最快、最先进的。如果性能不是你的最高优先级,那么Logback仍然是一个不错的选择。


3、Slf4j使用方法

使用SLF4J编写日志消息非常简单。首先需要调用 LoggerFactory 上的 getLogger 方法来实例化一个新的 Logger 对象。一共有两种方法:

  • 方法1:直接使用

使用 org.slf4j.LoggerFactorygetLogger 方法获取Logger实例,推荐 private static final。然后就可以调用记录器上的 errorwarninfodebugtrace 方法之一,以编写具有相应日志级别的日志消息。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) {
        // 日志级别默认从高到低:ERROR,WARN,INFO,DEBUG,TRACE
        log.error("This is an error message");
        log.warn("This is a warn message");
        log.info("This is an info message");
        log.debug("This is a debug message");
        log.trace("This is a trace message");
    }
}
  • 方法2:使用lombok(推荐)

直接在类上打上lombok的注解, 这个方法是最简单,代码量最小,编程效率最高的, 而且lombok组件在很多场景都很好用

  • 引入lombok坐标
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
</dependency>
  • 使用Lombok中的Slf4j
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Main {
    public static void main(String[] args) {
        log.error("This is an error message");
        log.warn("This is a warn message");
        log.info("This is an info message");
        log.debug("This is a debug message");
        log.trace("This is a trace message");
    }
}




二、log4j配置

Apache Log4J是一个非常古老的日志框架,多年来一直是最流行的日志框架。它包含了一些基本概念,如分层日志级别和日志记录器,这些概念仍然被现代日志框架使用。

官网:https://logging.apache.org/log4j/1.x/

开发团队在2015年宣布了Log4j的生命终结。虽然很多遗留项目仍在使用它,但如果我们启动一个新项目,推荐使用log4j2或logback。

在讨论Log4j2和Logback之前,让我们先快速了解一下所需的依赖项和配置。

  • log4j依赖
<!-- log4j日志 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  • log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n"/>
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug"/>
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info"/>
    </logger>
    <root>
        <level value="debug"/>
        <appender-ref ref="STDOUT"/>
    </root>

</log4j:configuration>



三、log4j2配置

官网:https://logging.apache.org/log4j/2.x/

1、SpringBoot整合Log4j2

pom.xml中排除SpringBoot自带的日志依赖(SpringBoot默认选用SLF4J和logback来记录日志)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--排除自带的日志依赖-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

引入log4j2依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <version>3.2.5</version>
</dependency>


2、非SpringBoot项目引入的依赖

  • log4j2所必须的依赖
<!-- Log4j2 dependencies -->
<!-- log4j2 门面API -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.1</version>
</dependency>
<!-- log4j2的日志实现 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.1</version>
</dependency>
<!-- 为slf4j绑定日志实现 log4j2的适配器 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.13.3</version>
</dependency>
  • 若是日志使用的是slf4j+log4j2,并使用log4j2的异步日志,引入如下依赖
<!-- 使用slf4j作为日志的门面,使用log4j2来记录日志 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
<!-- log4j2 门面API -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.1</version>
</dependency>
<!-- log4j2的日志实现 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.1</version>
</dependency>
<!-- 为slf4j绑定日志实现 log4j2的适配器 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.13.3</version>
</dependency>
<!-- log4j2并发编程依赖包,如果配置异步日志需要引入下面两个 -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.4.0</version>
</dependency>

3、log4j2-spring.xml文件(Spring项目)或log4j2.xml(非Spring项目)

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

<!--
status:用来指定log4j本身打印日志的级别,框架默认级别为warn (若是设置debug,log4j的配置过程也会展现出来)
monitorInterval:用于指定log4j自动重新配置的监测间隔时间,单位是秒(s),最小的间隔时间是5s。(修改配置文件后无需重新发动应用,可以自动加载)
-->
<configuration status="warn" monitorInterval="30">
    <!-- 全局参数 -->
    <properties>
        <!-- 日志打印级别 -->
        <property name="LOG_LEVEL">DEBUG</property>
        <!-- APP名称 -->
        <property name="APP_NAME" value="Mybatis"/>
        <!-- 日志文件存储路径 -->
        <property name="LOG_HOME">../logs</property>
        <!-- 日志编码 -->
        <property name="CHARSET" value="UTF-8"/>
        <!-- 存储天数 -->
        <property name="LOG_MAX_HISTORY" value="60d"/>
        <!-- 单个日志文件最大值, 单位 = KB, MB, GB -->
        <property name="LOG_MAX_FILE_SIZE" value="10MB"/>
        <!-- 每天每个日志级别产生的文件最大数量 -->
        <property name="LOG_TOTAL_NUMBER_DAILY" value="100"/>
        <!-- 压缩文件的类型,支持zip和gz,建议Linux用gz,Windows用zip -->
        <property name="ARCHIVE_FILE_SUFFIX" value="zip"/>
        <!-- 日志文件名 -->
        <property name="LOG_FILE_NAME" value="${LOG_HOME}"/>
        <property name="FILE_NAME_PATTERN" value="${LOG_HOME}/%d{yyyy-MM-dd}"/>


        <!--日志输出格式-控制台彩色打印-->
        <property name="ENCODER_PATTERN_CONSOLE">%blue{%d{yyyy-MM-dd HH:mm:ss.SSS}} | %highlight{%-5level}{ERROR=Bright
            RED, WARN=Bright Yellow, INFO=Bright Green, DEBUG=Bright Cyan, TRACE=Bright White} | %yellow{%t} |
            %cyan{%c{1.}} : %white{%msg%n}
        </property>

        <!--日志输出格式-文件-->
        <property name="ENCODER_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %5pid --- [%15.15t] %c{1.} [%L] : %m%n
        </property>

        <!--日志输出格式-控制台彩色打印-->
        <!--<property name="DEFAULT_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} %style{%5pid}{bright,magenta} -&#45;&#45; [%17.17t] %cyan{%c{1.} [%L]} : %m%n
        </property>-->
        <property name="DEFAULT_PATTERN">%blue{%d{yyyy-MM-dd HH:mm:ss,SSS}} %cyan{[%thread]} %highlight{%-5level}{ERROR=Bright
            RED, WARN=Bright Yellow, INFO=Bright Green, DEBUG=Bright Magenta, TRACE=Bright White} %cyan{%logger [%L]} : %m%n
        </property>
    </properties>

    <Appenders>
        <!-- 控制台的输出配置 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${DEFAULT_PATTERN}" charset="${CHARSET}"/>
        </Console>

        <!-- 新增包含所有级别日志的文件 Appender -->
        <RollingFile name="RollingFileAllLevels" fileName="${LOG_FILE_NAME}/all.log"
                     filePattern="${FILE_NAME_PATTERN}/${APP_NAME}-all.%d{yyyy-MM-dd HH.mm}-%i.log">
            <Filters/>  <!-- 不过滤任何日志级别 -->
            <!-- 日志输出格式-文件 -->
            <PatternLayout pattern="${ENCODER_PATTERN}"/>
            <!-- 触发策略 -->
            <Policies>
                <!-- 归档每天的文件,每天滚动一次 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 限制单个文件大小,日志达到size滚动一次 -->
                <SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}"/>
            </Policies>
            <!-- 限制每天文件个数 -->
            <DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
                <!-- 日志保留策略,日志只保留60天 -->
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <IfFileName glob="*-all.*.log"/>
                    <IfLastModified age="${LOG_MAX_HISTORY}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <!-- 打印出所有的info及以下级别的信息,每次大小超过size进行压缩,作为存档-->
        <RollingFile name="RollingFileAll" fileName="${LOG_FILE_NAME}/info.log"
                     filePattern="${FILE_NAME_PATTERN}/${APP_NAME}-info.%d{yyyy-MM-dd HH.mm}-%i.log">
            <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
            <ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 输出日志的格式 -->
            <PatternLayout pattern="${ENCODER_PATTERN}"/>
            <Policies>
                <!-- 归档每天的文件 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 限制单个文件大小 -->
                <SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}"/>
            </Policies>
            <!-- 限制每天文件个数 -->
            <DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <IfFileName glob="*-info.*.log"/>
                    <IfLastModified age="${LOG_MAX_HISTORY}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileDebug" fileName="${LOG_FILE_NAME}/debug.log"
                     filePattern="${FILE_NAME_PATTERN}/${APP_NAME}-debug.%d{yyyy-MM-dd HH.mm}-%i.log">
            <Filters>
                <ThresholdFilter level="DEBUG"/>
                <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout pattern="${ENCODER_PATTERN}"/>
            <Policies>
                <!-- 归档每天的文件 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 限制单个文件大小 -->
                <SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}"/>
            </Policies>
            <!-- 限制每天文件个数 -->
            <DefaultRolloverStrategy compressionLevel="9"
                                     max="${LOG_TOTAL_NUMBER_DAILY}">
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <IfFileName glob="*-debug.*.log"/>
                    <IfLastModified age="${LOG_MAX_HISTORY}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileWarn" fileName="${LOG_FILE_NAME}/warn.log"
                     filePattern="${FILE_NAME_PATTERN}/${APP_NAME}-warn.%d{yyyy-MM-dd HH.mm}-%i.log">
            <Filters>
                <ThresholdFilter level="WARN"/>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout pattern="${ENCODER_PATTERN}"/>
            <Policies>
                <!-- 归档每天的文件 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- 限制单个文件大小 -->
                <SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}"/>
            </Policies>
            <!-- 限制每天文件个数 -->
            <DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <IfFileName glob="*-warn.*.log"/>
                    <IfLastModified age="${LOG_MAX_HISTORY}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${LOG_FILE_NAME}/error.log"
                     filePattern="${FILE_NAME_PATTERN}/${APP_NAME}-error.%d{yyyy-MM-dd HH.mm}-%i.log">
            <Filters>
                <ThresholdFilter level="ERROR"/>
            </Filters>
            <PatternLayout pattern="${ENCODER_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_FILE_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy compressionLevel="9" max="${LOG_TOTAL_NUMBER_DAILY}">
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <IfFileName glob="*-error.*.log"/>
                    <IfLastModified age="${LOG_MAX_HISTORY}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <!-- 只有定义了logger并引入以上Appenders,Appender才会生效 -->
    <Loggers>
        <!-- Root:指定项目的根日志,如果没有单独指定Logger,那么默认使用该Root日志输出 -->
        <root level="${LOG_LEVEL}">
            <!-- AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender -->
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileAll"/>
            <appender-ref ref="RollingFileDebug"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <!-- 添加新的Appender引用 -->
            <appender-ref ref="RollingFileAllLevels"/>
        </root>
    </Loggers>
</configuration>

在log4j2中, 共有8个级别,按照从低到高为:OFF(关闭)>FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)>Trace(追踪)>All(所有)。

  • OFF:最高等级的,用于关闭所有日志记录。
  • Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志。
  • Error:输出错误信息日志。
  • Warn:输出警告及warn以下级别的日志。
  • Info:消息在粗粒度级别上突出强调应用程序的运行过程。
  • Debug:指出细粒度信息事件对调试应用程序是非常有帮助的。
  • Trace:是追踪,就是程序推进一下。
  • All:最低等级的,用于打开所有日志记录。

从左到右打印的内容越来越详细,程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。

  • 控制台设置日志彩色输出

在Log4j 2.10以前的版本,pattern中配置%highlight属性是可以正常打印彩色日志的,例如:

<property name="DEFAULT_PATTERN">%blue{%d{yyyy-MM-dd HH:mm:ss,SSS}} %cyan{[%t]} %highlight{%-5level}{ERROR=Bright
    RED, WARN=Bright Yellow, INFO=Bright Green, DEBUG=Bright Magenta, TRACE=Bright White} %cyan{%logger [%L]} : %m%n
</property>

通过查阅官方文档,发现在2.10版本以后,Log4j2默认关闭了Jansi(一个支持输出ANSI颜色的类库)

IDEA中,点击右上角->Edit Configurations,在VM options中添加配置 log4j.skipJansi 这个全局属性即可。

-Dlog4j.skipJansi=false

启动应用,显示效果如下:




四、logback配置

Logback的架构分为三个模块,logback-corelogback-classiclogback-access

Logback core提供了日志框架的核心功能。Logback classic为核心功能添加了更多功能,例如对SLF4J的本机支持。logback access将其与servlet容器集成,以便可以使用它编写HTTP访问日志。

官网:https://logback.qos.ch/

SpringBoot官方推荐使用带有-spring的文件名作为配置,如logback-spring.xml而不是logback.xml

这样命名的好处在于:因为标准的logback.xml配置文件加载得太早,所以不能在其中使用扩展,需要使用logback-spring.xml

当然上面是默认的命名规则,如果你想自定义xml的名称,自定义路径,可以通过logging.config属性配置:logging.config=classpath:logging-config.xml

  • 引入logback依赖

只需要定义对logback-classic的依赖。它包括对logback core和SLF4J API的依赖关系。

<!-- slf4j日志门面的一个具体实现 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
  • logback-spring.xml、logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds" debug="false">
    <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
    <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
    <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
    <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <property name="log.path" value="log" />
    <property name="console_log_pattern"
              value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/>
    <property name="charset" value="UTF-8"/>
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 -->
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
             <level>DEBUG</level>
         </filter>
        <encoder>
            <pattern>${console_log_pattern}</pattern>
        </encoder>
    </appender>

    <!--输出到文件,只记录INFO级别信息-->
    <appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/roll_info/logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>${console_log_pattern}</pattern>
            <charset>${charset}</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 如果超过10MB就删除 -->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>10MB</maxFileSize>
        </triggeringPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--输出到文件,只记录WARN级别信息-->
    <appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>
    <!--输出到文件,只记录ERROR级别信息-->
    <appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>

    <!--
    root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
    可以包含零个或多个appender元素。
    -->
    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="info_file" />
        <appender-ref ref="warn_file"/>
        <appender-ref ref="error_file"/>
    </root>

    <!--
        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
        <logger>仅有一个name属性,
        一个可选的level和一个可选的additivity属性。
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              如果未设置此属性,那么当前logger将会继承上级的级别。
        additivity:是否向上级logger传递打印信息,默认是true
    -->
    <!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
         第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
         第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
    -->
    <logger name="com.hyh.logback.web.LogTestController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
        <appender-ref ref="warn_file"/>
        <appender-ref ref="error_file"/>
    </logger>

    <!--    如果多环境开发可以用springProfile -->
    <!--开发环境:打印控制台-->
    <springProfile name="dev">
        <!--可以输出项目中的debug日志,包括mybatis的sql日志-->
        <logger name="com.hyh.logback.web" level="DEBUG">
            <appender-ref ref="console"/>
        </logger>
        <!--
            root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
            level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
            可以包含零个或多个appender元素。
        -->
        <root level="INFO">
            <appender-ref ref="console"/>
        </root>
    </springProfile>
</configuration>

最终的效果,会在项目路径下生成日志文件:/log/info/log-info-2024-11-10.0.log,并且日志文件的策略也在xml中定义。

  • 简易版logback配置(只在控制台输出日志信息,不记录到文件)
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
    <!-- 指定日志输出的位置 -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日志输出的格式 -->
            <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
        </encoder>
    </appender>

    <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
    <root level="DEBUG">
        <!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
        <appender-ref ref="STDOUT" />
    </root>

    <!-- 根据特殊需求指定局部日志级别 -->
    <logger name="com.aizen.crowd.mapper" level="DEBUG"/>

</configuration>

最佳实践

  1. 滚动日志,永远不让磁盘满
    ○ 根据运行环境要求, 配置最大日志数量
    ○ 根据运行环境要求, 配置日志文件最大大小
  2. 日志如何使用才方便统计和定位问题
    ○ 统一日志格式,比如统一先打印方法名称,再打印参数列表
    ○ 写好要打印参数的 toString方法
  3. 日志如何配置性能才比较高
    ○ 日志配置应该遵循结构清晰,尽量简化的原则,能不让框架计算的,尽量不让框架计算, 比如方法名,行号等
  4. 全公司,或者个人使用习惯统一,这样有助于后续的日志收集、分析和统计


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2237414.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

StarUML建模工具安装学习与汉化最新零基础详细教程【一键式下载】(适用于Windows、MacOS系统、Linux系统)

StarUML破解安装下载教程 前言&#xff1a; StarUML破解与汉化安装下载教程&#xff0c;仅供学习研究和交流使用&#xff0c;禁止作为商业用途或其他非法用途&#xff01; 仓库作者&#xff1a;X1a0He&#xff0c;经仓库作者授权使用。 目录 StarUML破解安装下载教程1. 下载…

【网络安全】2.3 安全的网络设计_2.防御深度原则

文章目录 一、网络架构二、网络设备三、网络策略四、处理网络安全事件五、实例学习&#xff1a;安全的网络设计结论 网络设计是网络安全的基础&#xff0c;一个好的网络设计可以有效的防止攻击者的入侵。在本篇文章中&#xff0c;我们将详细介绍如何设计一个安全的网络&#…

IoTDB 与 HBase 对比详解:架构、功能与性能

五大方向&#xff0c;洞悉 IoTDB 与 HBase 的详尽对比&#xff01; 在物联网&#xff08;IoT&#xff09;领域&#xff0c;数据的采集、存储和分析是确保系统高效运行和决策准确的重要环节。随着物联网设备数量的增加和数据量的爆炸式增长&#xff0c;开发者和决策者们需要选择…

如何找到系统中bert-base-uncased默认安装位置

问题&#xff1a; 服务器中无法连接huggingface&#xff0c;故需要自己将模型文件上传 ubuntu 可以按照这个链接下载 Bert下载和使用&#xff08;以bert-base-uncased为例&#xff09; - 会自愈的哈士奇 - 博客园 里面提供了giehub里面的链接 GitHub - google-research/be…

Qt 学习第十六天:文件和事件

一、创建widget对象&#xff08;文件&#xff09; 二、设计ui界面 放一个label标签上去&#xff0c;设置成box就可以显示边框了 三、新建Mylabel类 四、提升ui界面的label标签为Mylabel 五、修改mylabel.h&#xff0c;mylabel.cpp #ifndef MYLABEL_H #define MYLABEL_H#incl…

华为ensp配置bgp(避坑版)

文章目录 前言一、BGP是什么&#xff1f;二、拓扑三、基础配置四、测试五、拓展总结 前言 BGP&#xff08;Border Gateway Protocol&#xff0c;边界网关协议&#xff09;是一种在互联网中使用的路径矢量协议。它主要用于在不同的自治系统&#xff08;AS&#xff09;之间交换路…

QT最新版6.8在线社区版安装教程

访问QT的官网&#xff1a; Qt | Tools for Each Stage of Software Development Lifecycle 点击 Download Try&#xff1a; 点击社区版最新在线安装&#xff1a; 往下翻网页&#xff0c; 点击下载&#xff1a; 开始安装&#xff1a; 使用--mirror进行启动安装程序&#xff1…

鸿蒙多线程开发——Worker多线程

1、概 述 1.1、基本介绍 Worker主要作用是为应用程序提供一个多线程的运行环境&#xff0c;可满足应用程序在执行过程中与主线程分离&#xff0c;在后台线程中运行一个脚本进行耗时操作&#xff0c;极大避免类似于计算密集型或高延迟的任务阻塞主线程的运行。 创建Worker的线…

海量数据迁移:Elasticsearch到OpenSearch的无缝迁移策略与实践

文章目录 一&#xff0e;迁移背景二&#xff0e;迁移分析三&#xff0e;方案制定3.1 使用工具迁移3.2 脚本迁移 四&#xff0e;方案建议 一&#xff0e;迁移背景 目前有两个es集群&#xff0c;版本为5.2.2和7.16.0&#xff0c;总数据量为700T。迁移过程需要不停服务迁移&#…

在配置环境变量之后使用Maven报错 : mvn : 无法将“mvn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

最近&#xff0c;我在 Windows 系统上安装和配置 Apache Maven 时遇到了一些问题&#xff0c;想在此记录下我的解决历程&#xff0c;希望对遇到类似问题的朋友有所帮助。 问题描述 我下载了 Maven 并按照常规步骤配置了相关的环境变量。然而&#xff0c;在 PowerShell 中输入…

大模型,智能家居的春秋战国之交

智能家居&#xff0c;大家都不陌生。尽管苹果、谷歌、亚马逊等AI科技巨头&#xff0c;以及传统家电厂商都在积极进入这一领域&#xff0c;但发展了十多年之后&#xff0c;智能家居依然长期呈现出一种技术上人工智障、市场上四分五裂的局面。 究其原因&#xff0c;是此前传统家电…

【设计模式】结构型模式(四):组合模式、享元模式

《设计模式之结构型模式》系列&#xff0c;共包含以下文章&#xff1a; 结构型模式&#xff08;一&#xff09;&#xff1a;适配器模式、装饰器模式结构型模式&#xff08;二&#xff09;&#xff1a;代理模式结构型模式&#xff08;三&#xff09;&#xff1a;桥接模式、外观…

众测遇到的一些案列漏洞

文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行…

算法求解(C#)-- 寻找包含目标字符串的最短子串算法

1. 引言 在字符串处理中&#xff0c;我们经常需要从一个较长的字符串中找到包含特定目标字符串的最短子串。这个问题在文本搜索、基因序列分析等领域有着广泛的应用。本文将介绍一种高效的算法来解决这个问题。 2. 问题描述 给定一个源字符串 source 和一个目标字符串 targe…

ThingsBoard规则链节点:RPC Call Reply节点详解

引言 1. RPC Call Reply 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 设备控制 3.2 状态查询 3.3 命令执行 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备管理…

动态规划(简单多状态 dp 问题 1.按摩师 2.打家劫舍 II 3. 删除并获得点数 4.粉刷房子 5.买卖股票的最佳时机(全系列))

面试题 17.16. 按摩师213. 打家劫舍 II740. 删除并获得点数LCR 091. 粉刷房子 &#xff08;原&#xff1a;剑指 Offer II 091. 粉刷房子&#xff09;309. 买卖股票的最佳时机含冷冻期714. 买卖股票的最佳时机含手续费123. 买卖股票的最佳时机 III188. 买卖股票的最佳时机 IV 1.…

【VBA实战】用Excel制作排序算法动画续

为什么会产生用excel来制作排序算法动画的念头&#xff0c;参见【VBA实战】用Excel制作排序算法动画一文。这篇文章贴出我所制作的所有排序算法动画效果和源码&#xff0c;供大家参考。 冒泡排序&#xff1a; 插入排序&#xff1a; 选择排序&#xff1a; 快速排序&#xff1a;…

关于Markdown的一点疑问,为什么很多人说markdown比word好用?

markdown和word压根不是一类工具&#xff0c;不存在谁比谁好&#xff0c;只是应用场景不一样。 你写博客、写readme肯定得markdown&#xff0c;但写合同、写简历肯定word更合适。 markdown和word类似邮箱和微信的关系&#xff0c;这两者都可以通信&#xff0c;但微信因为功能…

区块链技术在数字版权管理中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在数字版权管理中的应用 区块链技术在数字版权管理中的应用 区块链技术在数字版权管理中的应用 引言 区块链技术概述 …

基于Spring Boot的在线装修管理系统的设计与实现,LW+源码+讲解

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…