一、引入Logback日志的maven依赖:logback-classic
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
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会自动加载。公众 号Java精选,回复java面试,获取面试资料,支持在线刷题。
三、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,这样会导致出错。面试宝典:https://www.yoodb.com
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注入相关的变量,上面已经说到。
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;
}
}
作者:蕃薯耀
https://www.cnblogs.com/fanshuyao/p/14177544.html
公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!
Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!
------ 特别推荐 ------
特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。
点击“阅读原文”,了解更多精彩内容!文章有帮助的话,点在看,转发吧!

1万+

被折叠的 条评论
为什么被折叠?



