logback简介、spring boot 配置logback,logback不打印日志

spring boot 日志简介

spring boot只依赖 Commons Logging API,而不依赖其他日志(jul、logback、log4j)。

方法1

要想使用logback,必须引入jcl-over-slf4j( 实现了 Commons Logging API),将jcl转接到slf4j。所有的spring boot starter都依赖了spring-boot-starter-webpom如下

<dependencies>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-to-slf4j</artifactId>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jul-to-slf4j</artifactId>
		</dependency>
	</dependencies>

可以看到spring-boot-starter-logging引入了logback,同时将log4j、jul都转接到slf4j,这就是为什么引入jcl-over-slf4j就能使logback生效的原因。

方法2

除了上述操作,还有另外一个办法,根据spring boot 2.1.13文档说明,不用引入上述那么多的依赖,只要引入spring-boot-starter-web即可

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

如想修改日志级别,在application.properties中设置logging.level即可。

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

通过logging.file修改日志文件位置。

spring boot 配置logback

类路径下新建logback.xml或者logback-spring.xml,推荐使用后者。

  • logback.xml还是用logback-spring.xml?
    • 根据,springboot中配置logback所说,logback.xml是标准的logback配置文件,但不支持spring boot logback扩展

    • logback-spring.xml可以使用springboot logback 扩展,支持spring profile、Spring Environment,也就是通常所说的能获取yml、properties中的值。

spring boot提供了logback的默认配置org/springframework/boot/logging/logback/base.xml,除了base.xml还有defaults.xml、console-appender.xml、file-appender.xml,提供了log_pattern、consoleAppender、FileAppender,在自定义的logback-spring.xml中,都可以引入这些文件,加以利用,

<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>

defaults.xml配置了tomcat、hibernate的日志级别,规定了控制台及文件的输出格式。

<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="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}}"/>

	<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"/>
</included>

console-appender.xml使用了defaults.xml规定的控制台输出格式。

<included>
	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
		</encoder>
	</appender>
</included>

file-appender.xml使用了defaults.xml规定的文件输出格式,并会按照大小和时间分片,文件最大10M。

<included>
	<appender name="FILE"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<encoder>
			<pattern>${FILE_LOG_PATTERN}</pattern>
		</encoder>
		<file>${LOG_FILE}</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
			<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
			<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
			<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
		</rollingPolicy>
	</appender>
</included>

配置logback只输出到文件

新建logback-spring.xml 引入 file-appender.xml,没有引入 console-appender.xml,所以不会输出到控制台。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <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/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

开发环境输出到控制台、线上环境输出到文件

那么就可以使用logback-spring.xml中的springProfile来实现

 <springProfile name="dev">
        <root level="debug">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>
 <springProfile name="!dev">
        <root level="info">
            <appender-ref ref="asyncFileAppender"/>
        </root>
    </springProfile>

logback不起作用,使用了其他日志

在实践中,往往遇到logback不起作用的情况,通过mvn dependency:tree 查看依赖,一般来说都是因为引入了其它日志实现(log4j、apache commons log)导致,控制台一般会有提示,这种情况,排除掉其他日志实现 即可。比如

 <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

问题

笔者在实践中,遇到了root配置的debug级别,过滤器目标级别是INFO,实际info、warn、error都输出的问题;

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>INFO</level>
		</filter>
	</appender>
	<springProfile name="dev">
		<root level="debug">
			<appender-ref ref="CONSOLE"/>
		</root>
	</springProfile>

LevelFilter过滤器只有INFO级别才会匹配,这个从源码可以得知

ch.qos.logback.classic.filter.LevelFilter
public FilterReply decide(ILoggingEvent event) {
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }

        if (event.getLevel().equals(level)) {
            return onMatch;
        } else {
            return onMismatch;
        }
    }

不禁想到info、warn等会产生mismatch,mistach采用的是NEUTRAL(中立),

ch.qos.logback.core.filter.AbstractMatcherFilter
protected FilterReply onMismatch = FilterReply.NEUTRAL;

查阅官方文档Filters,当结果是NEUTRAL时,如果没有下一个filter则正常输出,否则交给下一个filter处理,至此真相大白;

Filters are organized as an ordered list and are based on ternary
logic. The decide(ILoggingEvent event) method of each filter is called
in sequence. This method returns one of the FilterReply enumeration
values, i.e. one of DENY, NEUTRAL or ACCEPT. If the value returned by
decide() is DENY, then the log event is dropped immediately without
consulting the remaining filters. If the value returned is NEUTRAL,
then the next filter in the list is consulted. If there are no further
filters to consult, then the logging event is processed normally. If
the returned value is ACCEPT, then the logging event is processed
immediately skipping the invocation of the remaining filters.

要想自定义mismatch,添加onMismatch标签即可,这样配置就会只输出INFO级别;

<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>INFO</level>
			<onMismatch>DENY</onMismatch>
</filter>

除了LevelFilter过滤器,还有ch.qos.logback.classic.filter.ThresholdFilter,这种是大于等于指定级别才会输出,这个可以从源码中得知。

ch.qos.logback.classic.filter.ThresholdFilter
public FilterReply decide(ILoggingEvent event) {
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }

        if (event.getLevel().isGreaterOrEqual(level)) {
            //大于等于指定级别返回中立
            return FilterReply.NEUTRAL;
        } else {
            return FilterReply.DENY;
        }
    }

总结

spring boot使用logback

  • 引入spring-boot-starter-web
  • 如果只改变日志级别,在application.properties中配置logging.level即可
  • 细粒度的控制,新建logback-spring.xml,酌情引入defaults.xmlconsole-appender.xmlfile-appender.xml

LevelFilter和ThresholdFilter

  • LevelFilter只有等于指定级别才会输出
  • ThresholdFilter大于等于指定级别才会输出

参考

spring boot howto-logging

Spring Boot中使用logback打印日志非常简单,只需要以下几个步骤: 1. 添加依赖 在pom.xml文件中添加logback的依赖 ```xml <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> ``` 2. 配置logback.xml 在src/main/resources下新建logback.xml文件配置logback日志输出格式和输出位置等信息。 例如,以下是一个简单的logback.xml配置文件: ```xml <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <logger name="com.example" level="DEBUG"/> <root level="INFO"> <appender-ref ref="CONSOLE"/> </root> </configuration> ``` 其中,`appender`定义了日志输出的方式,这里使用的是`ConsoleAppender`,即输出到控制台;`encoder`定义了日志的输出格式;`logger`定义了日志输出的级别,这里设置为DEBUG级别;`root`定义了日志输出的根级别,这里设置为INFO级别。 3. 在应用程序中使用logback 在需要打印日志的类中使用logback即可,例如: ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyService { private static final Logger logger = LoggerFactory.getLogger(MyService.class); public void doSomething() { logger.debug("Debug log"); logger.info("Info log"); logger.warn("Warn log"); logger.error("Error log"); } } ``` 这里使用了`LoggerFactory.getLogger()`方法获取Logger对象,然后使用`debug()`、`info()`、`warn()`和`error()`等方法输出不同级别的日志信息。 以上就是在Spring Boot中使用logback打印日志的基本步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值