SpringBoot多环境日志配置
SpringBoot 默认使用 LogBack 日志系统
默认情况下,SpringBoot项目的日志只会在控制台输入。
如果想查询历史日志则无法找到,我们需要一个日志系统来统一管理日志。
一般正式项目会有单独日志系统,将日志操作存入数据库。
第一种方式是
在
application.properties
或application.yml
文件 中添加同时设置
logging.file.name
和logging.file.path
,则logging.file.name
会被忽略。
# 设置日志文件的具体名称 logging.file.name=./logfile.log # 或者设置日志文件的目录 logging.file.path=/logfile/
更详细的配置也可在这个配置文件中写
第二种方式 使用配置文件
1、引入依赖
引入slf4j-api 是为了使用 @Slf4j 注解简化操作
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
2、多环境配置
3、创建 logback xml
在 resource 下创建 logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <springProperty scope="context" name="applicationName" source="spring.application.name" defaultValue="spring-restful-api"/> <!-- 单个日志文件的最大,尺寸 --> <springProperty scope="context" name="maxFileSize" source="logging.file.max-size" defaultValue="10MB"/> <!-- 日志保留时长 (天) --> <springProperty scope="context" name="maxHistory" source="logging.file.max-history" defaultValue="180"/> <!-- 日志文件路径 --> <springProperty scope="context" name="logDir" source="logging.file.path" defaultValue="./logs"/> <contextName>${applicationName}</contextName> <!-- 彩色日志 --> <!-- 彩色日志依赖的渲染类 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> <!-- 彩色日志格式 --> <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }) %clr(---){faint} %clr([%10t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex"/> <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n%wex"/> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8"> <pattern>${CONSOLE_LOG_PATTERN}</pattern> </encoder> </appender> <!-- info日志 appender --> <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${logDir}/info.log</file> <!-- 追加方式记录日志默认是true 日志被追加到文件结尾 --> <append>true</append> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 --> <fileNamePattern>${logDir}/info/info-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 日志最大的历史 180天 --> <maxHistory>${maxHistory}</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,这里设置为20MB --> <maxFileSize>1MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8"> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 只打印info日志 --> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- DEBUG日志 appender --> <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${logDir}/debug.log</file> <!-- 追加方式记录日志默认是true 日志被追加到文件结尾 --> <append>true</append> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${logDir}/debug/debug-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 日志最大的历史 180天 --> <maxHistory>${maxHistory}</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,这里设置为20MB --> <maxFileSize>${maxFileSize}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8"> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 只打印DEBUG日志 --> <level>DEBUG</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- WARN日志 appender --> <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${logDir}/warn.log</file> <!-- 追加方式记录日志默认是true 日志被追加到文件结尾 --> <append>true</append> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${logDir}/warn/warn-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 日志最大的历史 180天 --> <maxHistory>${maxHistory}</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,这里设置为20MB --> <maxFileSize>${maxFileSize}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8"> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 只打印WARN日志 --> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- error 日志 appender --> <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${logDir}/error.log</file> <!-- 追加方式记录日志默认是true 日志被追加到文件结尾 --> <append>true</append> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${logDir}/error/error-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 日志最大的历史 180天 --> <maxHistory>${maxHistory}</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,这里设置为20MB --> <maxFileSize>1MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8"> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- 只打印错误日志 --> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 开发环境和测试环境,日志输出到控制台 --> <springProfile name="dev|test"> <!--控制台和日志文件输出级别--> <root level="INFO"> <appender-ref ref="STDOUT"/> </root> <logger name="com.pyb.demo" level="debug"/> <!-- 开发和测试环境, 指定某包日志为debug级 --> </springProfile> <!-- 生产环境,日志输出到文件 --> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="INFO"/> <appender-ref ref="ERROR"/> <appender-ref ref="DEBUG"/> <appender-ref ref="WARN"/> </root> <logger name="com.pyb.demo" level="warn"/> <!-- 生产环境, 指定某包日志为warn级 --> <logger name="com.pyb.demo.Application" level="info"/> <!-- 特定某个类打印info日志, 比如application启动成功后的提示语 --> </springProfile> </configuration>
解释
<!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。<logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 还有一个特殊值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前logger将会继承上级的级别。 addtivity:是否向上级logger传递打印信息。默认是true。 <logger name="org.springframework.web" level="info"/> <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/> --> <!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: 第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: 【logging.level.org.mybatis=debug logging.level.dao=debug】 --> <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能设置为INHERITED或者同义词NULL。默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 -->
4.使用
完整策略
缺点(启动项目可能会报错)
spring会优先加载项目中或者jar包中的logback.xml并读取里边的路径(/workspace/api-default.log),然后再加载application.yml之后再加载我们的日志文件logback-spring.xml,项目部署在服务器上运行一般不会用root这种权限很大的用户执行,权限小的会对logback.xml里的路径可能会没有操作权限就会导致项目启动失败。