```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>