logback自定义变量及表达式实现多环境个性化配置

原创
2020/10/07 08:53
阅读数 1.1K

本文通过一个业务场景,演示如何通过自定义变量,并且在logback.xml中使用if then else语句判断多环境时读取不同的配置。

业务场景

  • 1、如果当前是研发环境,日志只在控制台输出,而不打印输出到文件,因为一般情况下研发的电脑环境是win或者mac,按照服务器日志输出目录,容易造成没有权限等问题;
  • 2、可以通过自定义变量,设置日志输出目录自定义(当然还可以有很多不同玩法)

配置文件

logback读取配置文件规则

下面内容来自:http://www.logback.cn/03%E7%AC%AC%E4%B8%89%E7%AB%A0logback%E7%9A%84%E9%85%8D%E7%BD%AE.html

以下是 logback 的初始化步骤:

    logback 会在类路径下寻找名为 logback-test.xml 的文件。
    如果没有找到,logback 会继续寻找名为 logback.groovy 的文件。
    如果没有找到,logback 会继续寻找名为 logback.xml 的文件。
    如果没有找到,将会通过 JDK 提供的 ServiceLoader 工具在类路径下寻找文件 META-INFO/services/ch.qos.logback.classic.spi.Configurator,该文件的内容为实现了 Configurator 接口的实现类的全限定类名。
    如果以上都没有成功,logback 会通过 BasicConfigurator 为自己进行配置,并且日志将会全部在控制台打印出来。

最后一步的目的是为了保证在所有的配置文件都没有被找到的情况下,提供一个默认的(但是是非常基础的)配置。

创建普通logback.xml文件

在项目的resources/logback.xml文件,文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="30 minutes">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <charset class="java.nio.charset.Charset">UTF-8</charset>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%thread] %-5level %logger{50} - %msg%n</pattern>-->
            <pattern>[%X{short_uuid}] %d{HH:mm:ss} %-5level %logger [%line] - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 按照每天生成日志文件 -->
    <appender name="File"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/logs/gongstring-sample/out.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>/logs/gongstring-sample/out.log.%i.%d{yyyy-MM-dd}</fileNamePattern>
            <maxHistory>30</maxHistory>
            <maxFileSize>300MB</maxFileSize>
        </rollingPolicy>
        <encoder charset="UTF-8"><!-- 必须指定,否则不会往文件输出内容 -->
            <pattern>[%X{uuid}] %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} [%line][%thread] - %msg%n</pattern>
        </encoder>
        <append>false</append>
        <prudent>false</prudent>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="File"/>
    </root>
</configuration>

基于此配置文件,所有环境都会输出到file文件中,如果/logs目录没有读写权限,会造成项目启动失败。

自定义变量配置

1.添加依赖

按照官方文档的配置说明,可以通过在xml中自定义变量和使用if表达式的方式自定义生效配置块,参考文档: http://www.logback.cn/04%E7%AC%AC%E5%9B%9B%E7%AB%A0Appenders.html 其中需要添加依赖包:http://logback.qos.ch/setup.html#janino

<!-- The org.codehaus.janino:commons-compiler:3.0.6 dependency -->
<!-- will be automatically pulled in by Maven's transitivity rules -->
<dependency>
  <groupId>org.codehaus.janino</groupId>
  <artifactId>janino</artifactId>
  <version>3.0.6</version>
</dependency>

2.编写配置类

package com.gongstring.log.config;

import ch.qos.logback.core.PropertyDefinerBase;
import com.gongstring.util.SystemUtil;

/**
 * 研发环境配置
 */
public class LogbackDevDefiner extends PropertyDefinerBase {

    @Override
    public String getPropertyValue() {
		//区分当前环境,如果是mac或者windows,默认是研发环境
        if(SystemUtil.isMac() || SystemUtil.isWindows())
            return "true";

		//此处可以自定义规则
        return "dev".equalsIgnoreCase(System.getProperty("spring.application.env","dev")) ? "true" : null;
    }
}

3.配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="30 minutes">
	<define name="isDev" class="com.gongstring.log.config.LogbackDevDefiner" />
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <charset class="java.nio.charset.Charset">UTF-8</charset>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] [%thread] %-5level %logger{50} - %msg%n</pattern>-->
            <pattern>[%X{short_uuid}] %d{HH:mm:ss} %-5level %logger [%line] - %msg%n</pattern>
        </encoder>
    </appender>

    <if condition='isNull("isDev")'>
        <then>
            <!-- 按照每天生成日志文件 -->
            <appender name="File"  class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>/logs/gongstring-sample/out.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                    <fileNamePattern>/logs/gongstring-sample/out.log.%i.%d{yyyy-MM-dd}</fileNamePattern>
                    <maxHistory>30</maxHistory>
                    <maxFileSize>300MB</maxFileSize>
                </rollingPolicy>
                <encoder charset="UTF-8"><!-- 必须指定,否则不会往文件输出内容 -->
                    <pattern>[%X{uuid}] %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} [%line][%thread] - %msg%n</pattern>
                </encoder>
                <append>false</append>
                <prudent>false</prudent>
            </appender>

            <root level="info">
                <!--appender-ref ref="STDOUT"/-->
                <appender-ref ref="File"/>
            </root>

        </then>
        <else>
            <root level="info">
                <appender-ref ref="STDOUT"/>
            </root>

            <logger name="com.gongstring" additivity="false" level="debug">
                <appender-ref ref="STDOUT"/>
            </logger>
        </else>
    </if>
</configuration>

4.自定义日志输出目录

参考上面自定义配置的做法,可以编写一个实现类,继承PropertyDefinerBase,在getPropertyValue()方法中返回自定义的目录地址,并在xml中将/logs/gongstring-sample改成变量即可;

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部