Spring Boot多profile: logback配置的自动发现(仅单profile被**)
如果spring有多个profile, 则一般要根据profile的不同添加相应的logback配置. 实现的方法不止一种, 可以在各个profile中分别配置, 也可以在profile中指定logging.config配置, 第三个办法是让logback完全自动发现其配置.
本文说的就是第三个办法.
直接上图, 在源代码的resources下放一个logback.xml, 和针对每个profile的logback配置文件.
配置文件之间关系如下(箭头表示包含关系, 箭头指向被包含方):
其中, logback.xml的内容如下:
<configuration> <include resource="logback-${spring.profiles.active}.xml"/> </configuration>
${spring.profiles.active}是当前**的单个profile, 对于笔者而言, 只有local和kubernetes两个profile, 分别表示开发人员的本机开发环境和集成到kubernetes的环境. 所以, logback.xml根据${spring.profiles.active}的不同可能指向两个文件: logback-local.xml和logback-kubernetes.xml.
logback-local.xml:
<included> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>logback-local %date{HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern> </layout> </appender> <include resource="logback-level-config.xml"/> <root level="DEBUG"> <appender-ref ref="STDOUT"/> </root> </included>
logback-kubernetes.xml:
<included> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <Encoding>UTF-8</Encoding> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>jetty.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>jetty.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>1024MB</maxFileSize> </TimeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <Encoding>UTF-8</Encoding> </encoder> </appender> <include resource="logback-level-config.xml"/> <root level="DEBUG"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </included>
注意到上面的两个xml都include了一个logback-level-config.xml.这是为避免重复书写, 而将其共同的部分单独写到一个文件中.
<include resource="logback-level-config.xml"/>
logback-level-config.xml:
<included> <logger name="javax.activation" level="INFO"/> <logger name="javax.mail" level="WARN"/> <logger name="com.sun" level="INFO"/> <logger name="org.hibernate" level="INFO"/> <logger name="org.springframework" level="INFO"/> <logger name="org.eclipse" level="INFO"/> <logger name="org.apache.http" level="INFO"/> <logger name="org.thymeleaf" level="INFO"/> </included>
写到这里, 基本的配置就完成了.
不过, 这里还需要提到一个小技巧, 或者说小伎俩, 来应对没有添加JVM参数"-Dspring.profile.active"的情况, 一般出现这种情况是开发人员的本机环境, 开发人员的这个疏忽容易导致应用无法启动.
当${spring.profiles.active}为空的时候, 其实会返回"spring.profiles.active_IS_UNDEFINED"字符串, 所以再新建一个logback-spring.profiles.active_IS_UNDEFINED.xml文件, 内容可与logback-local.xml相同, 恰好就解决了应用不能启动的问题, 也算是将错就错吧.
本文的提到的方式仅适用于当前仅有一个active profile的情况; 如果有多个active profile, 应用就无法启动, 因为找不到对应的logback的xml. 笔者个人觉得应该避免多profile**的情况, 不论是local环境还是production环境, 都应该保持profile的配置尽可能简单, 多profile带来的好处或许还少于其增加的维护成本.
如果一定要使用多个active的profile, 则需要使用条件表达式, 参见: https://logback.qos.ch/setup.html#janino
参考文档:
https://logback.qos.ch/setup.html#janino
http://stackoverflow.com/questions/29429073/spring-boot-logback-and-logging-config-property