Spring Boot多profile: logback配置的自动发现(仅单profile被**)

如果spring有多个profile, 则一般要根据profile的不同添加相应的logback配置. 实现的方法不止一种, 可以在各个profile中分别配置, 也可以在profile中指定logging.config配置, 第三个办法是让logback完全自动发现其配置.

 

本文说的就是第三个办法.

 

直接上图, 在源代码的resources下放一个logback.xml, 和针对每个profile的logback配置文件. 

Spring Boot多profile: logback配置的自动发现(仅单profile被**)

 

配置文件之间关系如下(箭头表示包含关系, 箭头指向被包含方):

Spring Boot多profile: logback配置的自动发现(仅单profile被**)
 

其中, 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://*.com/questions/29429073/spring-boot-logback-and-logging-config-property