Springboot Logback日志使用,Springboot Logback詳細配置和日志分割
Springboot Logback springProperty使用,Springboot Logback區分環境
================================
©Copyright 蕃薯耀 2020-12-23
https://www.cnblogs.com/fanshuyao/
一、引入Logback日志的maven依賴:logback-classic
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency>
二、Springboot Logback 區分環境配置:
1、application.properties:
spring.profiles.active=dev server.port=6000 server.servlet.context-path=/logback
2、application-dev.properties:
logging.config=classpath:logback-spring-dev.xml
3、application-test.properties:
logging.config=classpath:logback-spring-test.xml
4、application-prod.properties:
logging.config=classpath:logback-spring-prod.xml
通過logging.config設置Springboot使用的日志配置文件,這樣每個環境都可以使用不能的配置。
如果不區分環境,可以直接命名為:logback-spring.xml,這樣Springboot會自動加載。
三、Springboot Logback.xml 配置文件詳細設置:
1、logback-spring-dev.xml
<?xml version="1.0" encoding="UTF-8"?> <!--默認每隔一分鍾掃描此配置文件的修改並重新加載--> <!-- <configuration scan="true" scanPeriod="60 seconds"> --> <configuration> <contextListener class="com.lqy.log.listener.LogbackStartupListener"/> <!--定義日志文件的存儲地址 勿在LogBack的配置中使用相對路徑--> <property name="projectName" value="logback"/> <property name="LOG_HOME" value="E:/logs"/> <property name="logDays" value="30"/> <property name="history" value="history"/> <property name="log_style" value="[%level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %thread %class.%method:%line%n%msg%n%n"/> <!-- 讀取spring配置文件的變量 --> <springProperty name="springProfilesActive" source="spring.profiles.active"/> <!--控制台輸出--> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <!--輸出日志到文件中--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/info.log</file> <!--不輸出ERROR級別的日志--> <!-- <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> --> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-info.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <!--警告日志輸出文件--> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/warn.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-warn.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <!--錯誤日志輸出文件--> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/error.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-error.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </configuration>
2、logback-spring-test.xml
<?xml version="1.0" encoding="UTF-8"?> <!--默認每隔一分鍾掃描此配置文件的修改並重新加載--> <!-- <configuration scan="true" scanPeriod="60 seconds"> --> <configuration> <contextListener class="com.lqy.log.listener.LogbackStartupListener"/> <!--定義日志文件的存儲地址 勿在LogBack的配置中使用相對路徑--> <property name="projectName" value="logback"/> <property name="LOG_HOME" value="E:/logs"/> <property name="logDays" value="30"/> <property name="history" value="history"/> <property name="log_style" value="[%level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %thread %class.%method:%line%n%msg%n%n"/> <!-- 讀取spring配置文件的變量 --> <springProperty name="springProfilesActive" source="spring.profiles.active"/> <!-- 測試環境不在控制台輸出 --> <!--輸出日志到文件中--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/info.log</file> <!--不輸出ERROR級別的日志--> <!-- <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> --> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-info.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <!--警告日志輸出文件--> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/warn.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-warn.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <!--錯誤日志輸出文件--> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/error.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-error.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE"/> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </configuration>
3、logback-spring-prod.xml
<?xml version="1.0" encoding="UTF-8"?> <!--默認每隔一分鍾掃描此配置文件的修改並重新加載--> <!-- <configuration scan="true" scanPeriod="60 seconds"> --> <configuration> <contextListener class="com.lqy.log.listener.LogbackStartupListener"/> <!--定義日志文件的存儲地址 勿在LogBack的配置中使用相對路徑--> <property name="projectName" value="logback"/> <property name="LOG_HOME" value="E:/logs"/> <property name="logDays" value="30"/> <property name="history" value="history"/> <property name="log_style" value="[%level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %thread %class.%method:%line%n%msg%n%n"/> <!-- 讀取spring配置文件的變量 --> <!-- <springProperty scope="context" name="loggingConfig" source="logging.config"/> --> <!-- 生產環境不在控制台輸出 --> <!--輸出日志到文件中--> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/info.log</file> <!--不輸出ERROR級別的日志--> <!-- <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> --> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/%d{yyyy-MM-dd}-info.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>${log_style}</pattern> </encoder> </appender> <!--警告日志輸出文件--> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/warn.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/${history}/%d{yyyy-MM-dd}-warn.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>${log_style}</pattern> </encoder> </appender> <!--錯誤日志輸出文件--> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${projectName}/${weblogicName}/error.log</file> <!--只輸出ERROR級別的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!--根據日期滾動輸出日志策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${projectName}/${weblogicName}/%d{yyyy-MM-dd}-error.log</fileNamePattern> <!--日志保留天數--> <maxHistory>${logDays}</maxHistory> </rollingPolicy> <encoder> <pattern>${log_style}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE"/> <appender-ref ref="WARN_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </configuration>
四、logback監聽器的使用(LogbackStartupListener.java)
在logback的xml配置文件中,有一個監聽器的配置:
<contextListener class="com.lqy.log.listener.LogbackStartupListener"/>
類文件:
package com.lqy.log.listener; import org.springframework.util.StringUtils; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.spi.LoggerContextListener; import ch.qos.logback.core.Context; import ch.qos.logback.core.spi.ContextAwareBase; import ch.qos.logback.core.spi.LifeCycle; public class LogbackStartupListener extends ContextAwareBase implements LoggerContextListener, LifeCycle { @Override public void start() { //log.info("LogbackStartupListener start()"); String userDir = System.getProperty("user.dir"); String osName = System.getProperty("os.name"); String osVersion = System.getProperty("os.version"); String javaVersion = System.getProperty("java.version"); String weblogicName = System.getProperty("weblogic.Name"); System.out.println("userDir===" + userDir); System.out.println("osName===" + osName); System.out.println("osVersion===" + osVersion); System.out.println("javaVersion===" + javaVersion); System.out.println("weblogicName===" + weblogicName); if(StringUtils.isEmpty(weblogicName)) { weblogicName = "notWeblogic"; } System.out.println("weblogicName2===" + weblogicName); Context context = getContext(); context.putProperty("weblogicName", weblogicName); } @Override public void stop() { //log.info("LogbackStartupListener stop()"); } @Override public boolean isStarted() { return false; } @Override public boolean isResetResistant() { return false; } @Override public void onStart(LoggerContext context) { //log.info("LogbackStartupListener onStart()"); } @Override public void onReset(LoggerContext context) { //log.info("LogbackStartupListener onReset()"); } @Override public void onStop(LoggerContext context) { //log.info("LogbackStartupListener onStop()"); } @Override public void onLevelChange(Logger logger, Level level) { //log.info("LogbackStartupListener onLevelChange()"); } }
1、為什么要使用監聽器:
通過監聽器,可以往logback的context注入變量,如系統環境變量(os.name),這樣在配置文件就能通過${os.name}直接引入使用變量的值。
如示例中引入了weblogic容器的服務名稱:weblogic.Name
String weblogicName = System.getProperty("weblogic.Name");
context.putProperty("weblogicName", weblogicName);
xml引入使用就是:${weblogicName}
使用如下:
<file>${LOG_HOME}/${projectName}/${weblogicName}/info.log</file>
五、logback通過springProperty標簽使用Springboot配置文件中的變量
1、logback引入Springboot配置文件的環境變量
name:自定義別名
source:對應Springboot配置文件中的屬性名
<!-- 讀取spring配置文件的變量 --> <springProperty name="springProfilesActive" source="spring.profiles.active"/>
使用:
${springProfilesActive}
示例:
<encoder> <pattern>[${springProfilesActive}]${log_style}</pattern> </encoder>
2、logback使用springProperty標簽可能存在的問題
報錯:
no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
詳細錯誤如下:
Logging system failed to initialize using configuration from 'classpath:logback-test.xml' java.lang.IllegalStateException: Logback configuration error detected: ERROR in ch.qos.logback.core.joran.spi.Interpreter@13:83 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169) at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:66) at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57) at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118) at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:310) at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:281) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:239) at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:216) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:80) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) at com.lqy.log.LogbackApplication.main(LogbackApplication.java:10) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [classpath:logback-test.xml][notWeblogic][ERROR] [2020-12-22 10:39:29.409] org.springframework.boot.SpringApplication.reportFailure:837 Application run failed
原因:
logback最開始使用的命名是:logback-test.xml,這樣會導致出錯。
SpringBoot 會在 classpath 下查找是否有logback的 jar包,存在jar包,然后檢查配置文件,包含 logback-test.groovy、logback-test.xml、logback.groovy 或者 logback.xml,如果都找不到的話,才會加載項目路徑下的 logback-spring.xml。
如果命名為logback-test.xml,logback會優先SpringBoot加載完,導致加載不到SpringBoot配置文件的變量而報錯。
解決方案:
方案一(首選):
簡單的解決方法,就是重命名,改成:logback-spring-test.xml
方案二:
不使用springProperty標簽,通過LogbackStartupListener注入相關的變量,上面已經說到。
六、測試logback日志:
import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/") @RestController public class LogController { private static final Logger log = LoggerFactory.getLogger(LogController.class); @RequestMapping("log") public String log() { String time = new Date().getTime() + ""; log.info(time); log.info("{} + {} is {}", 4, 1, 5); log.warn("{} + {} is not {}", 4, 1, 1); String weblogicName = System.getProperty("weblogic.Name"); log.error("weblogicName==={}", weblogicName); return "ok,時間=" + time + ",weblogicName=" + weblogicName; } }

(如果文章對您有幫助,歡迎捐贈,^_^)
================================
©Copyright 蕃薯耀 2020-12-23
https://www.cnblogs.com/fanshuyao/
