在项目中,存在使用条件判断的场景,例如想为测试和生产设置不同的日志记录级别。幸好的是,logback本身已经支持这种场景。
一、引入依赖
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.6</version>
</dependency>
二、条件表达式
2.1 语法
if-then语法:
<if condition="some conditional expression">
<then>
...
</then>
</if>
if-then-else语法:
<if condition="some conditional expression">
<then>
...
</then>
<else>
...
</else>
</if>
2.2 条件表达式
2.2.1 Using property() or p()
只能访问上下文属性或者系统属性。对于作为参数传递的键,property()
或p()
方法返回属性的String的值。
property("someKey").contains("someValue")
或者
p("someKey").contains("someValue")
2.2.2 Using isDefined()
用来检查属性是否定义
isDefined("someKey")
2.2.3 Using isNull()
用来检查属性是否为空
isNull("someKey")
三、简单案例
2.2中条件表达式如何读取变量的值,下面介绍两种方案:
3.1 方式一:读取上下文变量的值
需要配置springProperty
标签,即配置上下文变量。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--注意点:获取上下文变量的值-->
<springProperty scope="context" name="PV_LOG" source="my.pvlog"/>
<contextName>logback</contextName>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="log.path" value="/Users/libai/Documents/log"/>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<!--<pattern>%d %p (%file:%line\)- %m%n</pattern>-->
<!--格式化输出:%d:表示日期 %thread:表示线程名 %-5level:级别从左显示5个字符宽度 %msg:日志消息 %n:是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/main.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>main.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<!--格式化输出:%d:表示日期 %thread:表示线程名 %-5level:级别从左显示5个字符宽度 %msg:日志消息 %n:是换行符-->
<pattern>文件记录-%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--条件判断-->
<if condition='property("PV_LOG").equals("true")'>
<then>
<appender name="logAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/pv.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>pv.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<!--格式化输出:%d:表示日期 %thread:表示线程名 %-5level:级别从左显示5个字符宽度 %msg:日志消息 %n:是换行符-->
<pattern>文件记录-%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 输出拦截器的pv日志-->
<logger name="com.tellme.interceptor.PvLogInterceptor" level="info" additivity="false">
<appender-ref ref="logAppender"/>
</logger>
</then>
</if>
</configuration>
在application.yml
的配置如下:
my:
pvlog: true
3.2 方式二:读取系统变量的值
这一种方案就是读取JVM启动的值。无需配置springProperty
标签。
![](https://img.haomeiwen.com/i16013479/b94e0e2b1408ed35.png)
网友评论