```xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="1 seconds" debug="false">
<!--定义参数,后面可以通过${log.file.size}使用-->
<property name="log.file.size" value="100MB"></property>
<property name="log.history.days" value="7"></property>
<!--定义日志输出位置:${LOG_PATH:-LOGS}中 LOGS是日志的文件夹名,如果想为空使用${LOG_PATH:-.} -->
<property name="log.path" value="${LOG_PATH:-LOGS}"></property>
<!--use spring config kv. -->
<!--<springProperty scope="context" name="log.path" source="project.log.path" defaultValue="./logs"/>-->
<!-- <springProperty scope="context" name="log.level" source="project.log.level" />-->
<!--数据库地址-->
<springProperty scope="context" name="log.dburl" source="project.log.dbPath"/>
<!--数据库用户名-->
<springProperty scope="context" name="log.user" source="project.log.username"/>
<!--数据库密码-->
<springProperty scope="context" name="log.password" source="project.log.password"/>
<!-- output format -->
<property name="consoleLayoutPattern"
value="%-20(%d{yyyyMMdd_HH:mm:ss.SSS} [%logger{10}][%F:%L])[%level] %msg%n"/>
<property name="fileLayoutPattern"
value="%-20(%d{yyyyMMdd_HH:mm:ss.SSS} [%logger{10}]) [%level] %msg%n"/>
<!--<contextName>${project.name}</contextName>-->
<!--output to console -->
<!--ConsoleAppender 用于在屏幕上输出日志-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--定义了一个过滤器,在LEVEL之下的日志输出不会被打印出来-->
<!--这里定义了DEBUG,也就是控制台不会输出比ERROR级别小的日志-->
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter> -->
<!-- encoder 默认配置为PatternLayoutEncoder -->
<!--定义控制台输出格式-->
<encoder>
<Pattern>${consoleLayoutPattern}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--output to debug file -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/debug/%d{yyyy-MM-dd}/debug-log.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- output info file -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/info/%d{yyyy-MM-dd}/info-log.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- output warn file -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录WARN级别的日志 -->
<!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>WARN</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>${log.path}/warn/%d{yyyy-MM-dd}/warn-log.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- output error file -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录WARN级别的日志 -->
<!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>ERROR</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>${log.path}/error/%d{yyyy-MM-dd}/error-log.log</fileNamePattern>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6, 则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
<!-- 设置日志输出格式 --> %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- output custom database table-->
<appender name="CUSTOM_DB" class="net.cnki.cbcm.ems.common.log.LoggerDBAppender">
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.cj.jdbc.Driver</driverClass>
<url>${log.dburl}</url>
<user>${log.user}</user>
<password>${log.password}</password>
</connectionSource>
</appender>
<!--root是默认的logger 这里设定输出级别是INFO-->
<!-- non assign profile model -->
<root >
<level value="INFO"/>
<!--定义了两个appender,日志会通过往这两个appender里面写-->
<!--DB为logback默认的数据库日志表,CUSTOM_DB为我们自定义的数据日志表,可以只使用一个-->
<!-- <appender-ref ref="DB" />-->
<appender-ref ref="CUSTOM_DB"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!--通过 LoggerFactory.getLogger("mytest") 可以获取到这个logger-->
<!--由于这个logger自动继承了root的appender,root中已经有CUSTOM_DB的appender了,自己这边又引入了CUSTOM_DB的appender-->
<!--如果没有设置 additivity="false" ,就会导致一条日志在控制台输出两次的情况-->
<!--additivity表示要不要使用rootLogger配置的appender进行输出-->
<!-- <logger name="mytest" level="info" additivity="false">
<appender-ref ref="CUSTOM_DB"/>
</logger>-->
<!--由于设置了 additivity="false" ,所以输出时不会使用rootLogger的appender-->
<!--但是这个logger本身又没有配置appender,所以使用这个logger输出日志的话就不会输出到任何地方-->
<!-- <logger name="mytest2" level="info" additivity="false"/>-->
</configuration>