一、日志框架介绍
1、浅谈与slfj4、log4j、logback的关系
- Slf4j
SLF4J(Simple Logging Facade for Java)是一个日志框架的抽象层,可以与不同的日志实现进行绑定。它允许开发人员在代码中使用统一的日志接口,而无需关心具体的日志实现。
简单来讲就是slf4j是一系列的日志门面,也可以理解为 slf4j
是接口,而 logback
和 log4j
是具体实现了这些接口的日志框架,slf4j 具备很高的易用性和很好的抽象性。
- Log4j
Logback是Log4j的后继版本,由Log4j的作者开发。相比Log4j,Logback具有更好的性能和更丰富的功能,同时也更易于配置和扩展。
- Logback
Logback是Log4j的后继版本,由Log4j的作者开发。相比Log4j,Logback具有更好的性能和更丰富的功能,同时也更易于配置和扩展。
- Log4j2
log4j2是log4j的代替升级版,之前log4j曾爆出“核弹级”漏洞,现在已经不推荐使用了。
<br>
2、性能方面
在测试环境和条件相同的情况下,log4j2 全面优于 logback, log4j2性能是 logback的两倍。
建议使用Log4j2,因为它是三种框架中最快、最先进的。如果性能不是你的最高优先级,那么Logback仍然是一个不错的选择。
<br>
3、Slf4j使用方法
使用SLF4J编写日志消息非常简单。首先需要调用 LoggerFactory 上的 getLogger 方法来实例化一个新的 Logger 对象。一共有两种方法:
- 方法1:直接使用
使用 org.slf4j.LoggerFactory
的 getLogger
方法获取Logger实例,推荐 private static final
。然后就可以调用记录器上的 error
、 warn
、 info
、 debug
或 trace
方法之一,以编写具有相应日志级别的日志消息。
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"); } }
<br>
<br>
二、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>
<br>
<br>
三、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>
<br>
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>
<br>
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} --- [%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
启动应用,显示效果如下:
<br>
<br>
四、logback配置
Logback的架构分为三个模块,logback-core
、logback-classic
和 logback-access
。
Logback core提供了日志框架的核心功能。Logback classic为核心功能添加了更多功能,例如对SLF4J的本机支持。logback access将其与servlet容器集成,以便可以使用它编写HTTP访问日志。
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>
<br>
最佳实践
- 滚动日志,永远不让磁盘满
- 根据运行环境要求, 配置最大日志数量
- 根据运行环境要求, 配置日志文件最大大小
- 日志如何使用才方便统计和定位问题
- 统一日志格式,比如统一先打印方法名称,再打印参数列表
- 写好要打印参数的 toString方法
- 日志如何配置性能才比较高
- 日志配置应该遵循结构清晰,尽量简化的原则,能不让框架计算的,尽量不让框架计算, 比如方法名,行号等
- 全公司,或者个人使用习惯统一,这样有助于后续的日志收集、分析和统计
<br>