USING LOGBACK WITH SPRING BOOT
Logback 为企业应用程序制作了一个优秀的日志框架-它的速度快, 具有简单但功能强大的配置选项, 而且内存占用小。在我的入门帖子中已经介绍了 logback , logback 介绍: 企业日志框架。在 Logback 的一系列帖子中, 我还讨论了如何使用 XML 和 Groovy 配置 Logback。这些帖子可用作 Logback 配置: 使用 XML 和 Logback 配置: 使用 Groovy。
在这篇文章中, 我将讨论在Spring Boot中如何使用 Logback。虽然 Java 有许多日志框架选项, 但 Spring boot选择了使用 Logback 作为默认记录器。像Spring boot 里的许多东西一样, 默认情况下, Logback 会使用合理的默认值进行配置。开箱即用, Spring Boot 使 Logback 易于使用。
Creating Loggers
在上一个帖子中, 我写了有关使用 Spring boot创建 web 应用程序的内容。我们将为这个应用程序配置 logback。该应用程序包含一个控制器, 加日志代码到IndexController控制器。IndexController的最终代码如下:
package guru.springframework.controllers; import guru.springframework.helpers.SpringLoggingHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @RequestMapping("/") String index(){ logger.debug("This is a debug message"); logger.info("This is an info message"); logger.warn("This is a warn message"); logger.error("This is an error message"); new SpringLoggingHelper().helpMethod(); return "index"; } }
package guru.springframework.helpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SpringLoggingHelper { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public void helpMethod(){ logger.debug("This is a debug message"); logger.info("This is an info message"); logger.warn("This is a warn message"); logger.error("This is an error message"); } }
以下是从git上找到spring-boot用的base.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Base logback configuration provided for compatibility with Spring Boot 1.1 --> <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>
Configuration via Spring Boot’s application.properties File
在 Spring boot应用程序中, 可以将配置具体化为在不同环境中使用相同的应用程序代码。application.properties文件很可能是几种不同的方式来外部化 Spring boot配置属性的最流行的方法。在 Spring boot web 应用程序的默认结构中, 可以在 "Resources" 文件夹下定位application.properties文件。在application.properties文件中, 可以定义 Spring boot日志级别、应用日志日志级别、Hibernate日志级别、Thymeleaf 日志级别等。还可以定义一个日志文件, 以将日志消息写入到控制台之外。logging.level.org.springframework.web=INFO logging.level.guru.springframework.controllers=DEBUG logging.level.org.hibernate=ERROR logging.file=logs/spring-boot-logging.log
在输出中, 请注意, IndexController 的DEBUG和更高级别的消息被记录到控制台和文件中。这是因为在application.properties文件中, 我们指定了DEBUG作为 guru.springframework.controllers 包的日志级别, IndexController 是其中的一部分。由于我们没有显式配置 SpringLoggingHelper 类, 所以使用了base.xml 文件的默认配置。因此, 仅记录了 SpringLoggingHelper 的信息和更高级别的消息。
当需要为特定类或包获取更详细的日志消息时, 可以看到这是多么简单。
Logback Configuration through an External File
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml"/> <logger name="guru.springframework.controllers" level="WARN" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </logger> <logger name="guru.springframework.helpers" level="WARN" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </logger> </configuration>
logging.config=classpath:logback-spring.xml
Spring Boot Profiles in Logging
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml" /> <springProfile name="dev,staging"> <logger name="guru.springframework.controllers" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE" /> </logger>> </springProfile> <springProfile name="production"> <logger name="guru.springframework.controllers" level="WARN" additivity="false"> <appender-ref ref="FILE" /> </logger> </springProfile> </configuration>在上面的配置代码中, 对于dev和staging profiles, 我们配置了 guru.springframework.controllers 记录器, 以便将DEBUG和更高级别的消息记录到控制台。对于生产配置文件, 我们配置了相同的记录器, 以便将警告和更高级别的消息记录到文件中。
若要将配置文件传递给应用程序, 请使用 -Dspring.profiles.active= JVM 参数运行应用程序。
对于本地开发, 在 IntelliJ 中, 选择 "运行-编辑配置", 然后在 "运行/调试配置" 对话框中设置 JVM 参数, 如下所列。
在上述输出中, 观察 IndexController 的测井输出。根据dev文件的配置, 调试和更高的日志消息被记录到控制台。您可以使用production文件重新启动应用程序, 以确保将警告和更高的日志消息记录到文件中。
Conditional Processing of Configuration File
Logback 支持在 Janino 库的帮助下对配置文件进行条件处理。可以使用配置文件中的 <if>、<then> 和 <else> 元素来针对多个环境。要执行条件处理, 请将 Janino 依赖项添加到您的 Maven POM, 如下所愿。
<dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> <version>2.7.8</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<springProfile name="dev,staging">
<logger name="guru.springframework.controllers" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>>
</springProfile>
<springProfile name="production">
<logger name="guru.springframework.controllers" level="WARN" additivity="false">
<appender-ref ref="FILE" />
</logger>
</springProfile>
<if condition='property("spring.profiles.active").contains("dev")'>
<then>
<logger name="guru.springframework.helpers" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
</then>
<else>
<logger name="guru.springframework.helpers" level="WARN" additivity="false">
<appender-ref ref="FILE" />
</logger>
</else>
</if>
</configuration>
在上面的代码中, 我们在 <if> 元素中指定了一个条件, 以检查当前active profile 是否包dev。如果条件计算结果为 true, 则 <then> 元素内的配置代码将执行。在 <then> 元素中, 我们配置 guru.springframework.helpers 将DEBUG和更高的消息记录到控制台。我们使用 <else> 元素来配置记录器, 以便将WARN和更高的消息记录到日志文件中。<else> 元素为dev以外的任何配置文件执行。当您使用生产配置文件运行应用程序并对其进行访问时, 两个记录器都会将警告和更高的消息记录到日志文件中, 类似于此。
对于开发人员配置文件, 两个记录器都会将调试和更高的消息记录到控制台, 类似于此。
Logback Auto-Scan Issue with Spring Boot
<configuration debug="true" scan="true" scanPeriod="10 seconds" > ... </configuration>
Spring boot Logback 的一个限制是, 使用 springProfile 和 springProperty, 设置自动扫描会导致错误。
//Error on using auto-scan with springProfile -ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:39 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]] //Error on using auto-scan with springProperty -ERROR in ch.qos.logback.core.joran.spi.Interpreter@12:125 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
错误是由于不兼容问题而发生的。Spring boot使用 JoranConfigurator 子类支持 springProfile 和 springProperty。不幸的是, Logback 的 ReconfigureOnChangeTask 并没有提供一个钩子插入它。
Conclusion
翻译自:https://springframework.guru/using-logback-spring-boot/
我现在用的配置方式(每天晚上对当天log进行压缩存储,一天一个压缩包)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%t] [%C#%M:%L] - %msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${root}/logs/stream-collector-%d{yyyyMMdd}.log.zip</fileNamePattern> <maxHistory>10</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%t] [%C#%M:%L] - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration>