[ 分包打印日志 ] logback指定某包或类下的日志记录到不同文件中、分Level记录日志记录文件

本文介绍了如何使用logback配置文件实现分Level记录日志到不同文件,以及分包记录日志的功能。讲解了additivity、filter和滚动策略的作用,并提供了配置示例。注意,指定日志输出目录时,相对路径可能导致日志文件出现在系统根目录下。

1.logback配置文件标签解释

SpringBoot中的日志插件slf4j继承了 log4j、logback,所以在打印日志的时候,注意log变量的所属类库。
在这里插入图片描述

2、additivity的作用
additivity的作用在于children-logger是否使用 rootLogger配置的appender进行输出。

false:表示只用当前logger的appender-ref。不会向上一层级传递日志。

true:表示当前logger的appender-ref和rootLogger的appender-ref都有效。也就是说会打印至少两遍。

root 级别设置为debug,是一个全局的日志级别控制。
有显示指定了包的logger按照指定的,没有就跟随root的
root 中appender-ref 表示日志输出到哪些目标处。
logger 中additivity=true 表此logger对应级别的日志也附加到root下。默认是true。
没有设置logger的packagexxx,其打印级别跟随root设置的级别
设置additivity=false 表示此 logger 的打印日志不附加到root下,但可以在logger中指定独立的appender。
注意:如果设置additivity=false ,那日志选择了指定appender后就不会走root的指定了。

3、filter的作用
过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;返回ACCEPT,日志会被立即处理,不再经过剩余过滤器。
过滤器被添加到 中,为 添加一个或多个过滤器后,可以用任意条件对日志进行过滤。 有多个过滤器时,按照配置顺序执行。

4、滚动策略
RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。
有以下子节点:
      <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
      <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。
      <rollingPolicy>:当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类
      class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy": 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。有以下子节点:
        :必要节点,包含文件名及“%d”转换符,“%d”可以包含一个java.text.SimpleDateFormat指定的时间格式,如:%d{yyyy-MM}。
如果直接使用 %d,默认格式是 yyyy-MM-dd。RollingFileAppender的file字节点可有可无,通过设置file,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变;
如果没有设置file,活动文件的名字会根据fileNamePattern 的值,每隔一段时间改变一次。“/”或者“\”会被当做目录分隔符。

2.分Level记录到不同文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <contextName>soc-service</contextName>
    <property name="app.name" value="soc-statistic-service" />

    <property name="log.level.path" value="D:/mylog/export/app-log/level"></property>
    <property name="log.level.file.debug" value="${log.level.path}/debug_%d.log"/>
    <property name="log.level.file.info" value="${log.level.path}/info_%d.log"/>
    <property name="log.level.file.error" value="${log.level.path}/error_%d.log"/>


    <!-- 彩色日志配置 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){green} %clr([${PID:-}]){magenta} %clr([%25.25t]){yellow} %clr([${LOG_LEVEL_PATTERN:-%5p ]}){red} %clr(%-40.40logger{39}){blue} %clr(:){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />



    <!--    控制台日志的配置    -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <!-- 彩 色日志格式    -->
                <!--%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n-->
                ${CONSOLE_LOG_PATTERN}
            </pattern>
        </layout>
    </appender>

    <!--     文件日志: info级别      -->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--  日志过滤级别: INFO级别的会被处理,非INFO级别的会被过滤掉  -->
            <level>INFO</level>
            <!--  符合条件的日志,立即处理,不再经过剩余的过滤器-->
            <onMatch>ACCEPT</onMatch>
            <!--  不符合条件的日志,被抛弃不再经过其他过滤器-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--   路径  -->
<!--            <fileNamePattern>D:/mylog/info_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.info}</fileNamePattern>

        </rollingPolicy>
    </appender>

    <!--     文件日志: error级别      -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
<!--            <fileNamePattern>D:/mylog/error_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.error}</fileNamePattern>
        </rollingPolicy>
    </appender>


    <!--     文件日志: Debug级别      -->
    <appender name="fileDebugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
<!--            <fileNamePattern>D:/mylog/debug_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.debug}</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--    这里指定包下的的日志使用指定appender , 没有指定的包将跟随root级别的日志配置  -->
<!--    <logger name="com.jd.soc.statistic.service" value="DEBUG"  additivity="false" >-->
<!--        <appender-ref ref="fileInfoLog"/>-->
<!--    </logger>-->



    <!--    全局的日志配置,所有包下的日志所使用的append     -->
    <!--    日志优先级: ERROR、WARN、INFO、DEBUG、TRACE、 ALL -->
    <root level="INFO">
        <appender-ref ref="consoleLog" />
        <appender-ref ref="fileInfoLog" />
        <appender-ref ref="fileErrorLog" />
        <appender-ref ref="fileDebugLog" />

    </root>

</configuration>

上面的配置,console控制台的日志使用了彩色的输出格式。
三个 level的日志:erro、info、debug分别记录到指定目录中。执行后的结果会在磁盘中看到新建的文件出来。

在这里插入图片描述

3.分包记录到不同文件

4.注意

指定日志文件的输出目录时,/export的形式会在系统目录下创建 export,我的工程在本机的D盘,那么日志文件就会生成在D盘根目录下面

如果只想保存日志文件到当前工程的目录下 使用: export/ 的形式即可
使用Logback日志保存到相对路径记录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

疑问:
我设置了把日志记录到相对路径后,在系统根目录下还是出现了一个export文件夹,里面的结构张这样,不太清楚是发生了什么
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <contextName>soc-service</contextName>
    <property name="app.name" value="xxx-statistic" />
    <property name="packagename.service" value="xxx-statistic-service"></property>
    <property name="packagename.dao" value="xxx-statistic-dao"></property>
    <property name="packagename.api" value="xxx-statistic-api"></property>
    <property name="packagename.rpc" value="xxx-statistic-rpc"></property>
    <property name="packagename.message" value="xxx-statistic-message"></property>




    <property name="log.all.path" value="export/app-log/all"></property>
    <property name="log.level.path" value="export/app-log/level"></property>
    <property name="log.packages.path" value="export/app-log/packages"></property>

    <property name="log.all.file" value="${log.all.path}/${app.name}.log"></property>
    <property name="log.level.file.debug" value="${log.level.path}/debug_%d.log"/>
    <property name="log.level.file.info" value="${log.level.path}/info_%d.log"/>
    <property name="log.level.file.error" value="${log.level.path}/error_%d.log"/>
    <property name="log.packages.file" value="${log.packages.path}/${packagename.service}.log"></property>

    <!--    滚动策略文件名 -->
    <property name="log.rollingFile" value="${log.all.path}/${app.name}.%d{yyyyMMdd}.%i.log"/>
    <property name="log.rollingFile.service" value="${log.packages.path}/${packagename.service}.%d{yyyyMMdd}.%i.log"/>
    <property name="log.rollingFile.message" value="${log.packages.path}/${packagename.message}.%d{yyyyMMdd}.%i.log"/>
    <property name="log.rollingFile.dao" value="${log.packages.path}/${packagename.dao}.%d{yyyyMMdd}.%i.log"/>
    <property name="log.rollingFile.api" value="${log.packages.path}/${packagename.api}.%d{yyyyMMdd}.%i.log"/>
    <property name="log.rollingFile.rpc" value="${log.packages.path}/${packagename.rpc}.%d{yyyyMMdd}.%i.log"/>
    <!-- 彩色日志配置 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!--自定义颜色配置类-->
    <conversionRule conversionWord="customcolor" converterClass="com.jd.soc.statistic.service.other.LogbackColorful"/>
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){green} %clr([${PID:-}]){magenta} %clr([%25.25t]){yellow} %customcolor([${LOG_LEVEL_PATTERN:-%5p ]}) %clr(%-40.40logger{39}){blue} %clr(:){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />



    <!--    控制台日志的配置    -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <!-- 彩色日志格式    -->
                <!--%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n-->
                ${CONSOLE_LOG_PATTERN}
            </pattern>
        </layout>
    </appender>

    <!--     Level: info级别      -->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--  日志过滤级别: INFO级别的会被处理,非INFO级别的会被过滤掉  -->
            <level>INFO</level>
            <!--  符合条件的日志,立即处理,不再经过剩余的过滤器-->
            <onMatch>ACCEPT</onMatch>
            <!--  不符合条件的日志,被抛弃不再经过其他过滤器-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--   路径  -->
<!--            <fileNamePattern>D:/mylog/info_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.info}</fileNamePattern>

        </rollingPolicy>
    </appender>

    <!--     Level: error级别      -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
<!--            <fileNamePattern>D:/mylog/error_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.error}</fileNamePattern>
        </rollingPolicy>
    </appender>


    <!--     Level: Debug级别      -->
    <appender name="fileDebugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} - %msg%n
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
<!--            <fileNamePattern>D:/mylog/debug_%d.log</fileNamePattern>-->
            <fileNamePattern>${log.level.file.debug}</fileNamePattern>
        </rollingPolicy>
    </appender>


    <!--    所有文件日志的配置    -->
    <appender name="allFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--        <File>${log.all.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--     所有的日志立即输出到磁盘文件  -->
            <ImmediateFlush>true</ImmediateFlush>
            <!--     格式化日志打印-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--   输出的路径/文件名-->
            <FileNamePattern>${log.rollingFile}</FileNamePattern>
            <!--   日志保留天数   -->
            <MaxHistory>60</MaxHistory>
            <!--   日志文件最大大小   -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>


    <!--    Service包日志    -->
    <appender name="serviceFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--        <File>${log.packages.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <ImmediateFlush>true</ImmediateFlush>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.rollingFile.service}</FileNamePattern>
            <MaxHistory>60</MaxHistory>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!--    Message包日志    -->
    <appender name="messageFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--        <File>${log.packages.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <ImmediateFlush>true</ImmediateFlush>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.rollingFile.message}</FileNamePattern>
            <MaxHistory>60</MaxHistory>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!--    Dao包日志    -->
    <appender name="daoFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--        <File>${log.packages.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <ImmediateFlush>true</ImmediateFlush>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.rollingFile.dao}</FileNamePattern>
            <MaxHistory>60</MaxHistory>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!--    api包日志    -->
    <appender name="apiFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--        <File>${log.packages.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <ImmediateFlush>true</ImmediateFlush>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.rollingFile.api}</FileNamePattern>
            <MaxHistory>60</MaxHistory>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>


    <!--    rpc包日志    -->
    <appender name="rpcFileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--        <File>${log.packages.file}</File>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <ImmediateFlush>true</ImmediateFlush>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | %logger{10} | %5p | %msg%n</pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${log.rollingFile.rpc}</FileNamePattern>
            <MaxHistory>60</MaxHistory>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>


    <!--    这里指定包下的的日志使用指定appender , 没有指定的包将跟随root级别的日志配置 -->
    <!--    additivity="true" 这里希望分包输出日志之后,这些已执行过的还需要参与root的日志处理 -->
    <logger name="com.jd.xxx.xxxxxx.service" value="INFO"  additivity="true" >
        <appender-ref ref="serviceFileLog"/>
    </logger>
    <logger name="com.jd.xxx.message" value="INFO"  additivity="true" >
        <appender-ref ref="messageFileLog"/>
    </logger>
    <logger name="com.jd.xxxx.dao" value="INFO"  additivity="true" >
        <appender-ref ref="daoFileLog"/>
    </logger>
    <logger name="com.jd.xx.api" value="INFO"  additivity="true" >
        <appender-ref ref="apiFileLog"/>
    </logger>
    <logger name="com.jd.xxx.xxxx" value="INFO"  additivity="true" >
        <appender-ref ref="rpcFileLog"/>
    </logger>

    <!--    全局的日志配置,所有包下的日志所使用的append     -->
    <!--    日志优先级: ERROR、WARN、INFO、DEBUG、TRACE、 ALL -->
    <root level="INFO">
        <appender-ref ref="consoleLog" />
        <appender-ref ref="fileInfoLog" />
        <appender-ref ref="fileErrorLog" />
        <appender-ref ref="fileDebugLog" />
        <appender-ref ref="allFileLog"/>

    </root>

</configuration>

自定义日志级别对应的颜色配置类


import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.color.ForegroundCompositeConverterBase;
import ch.qos.logback.classic.Level;
import ch.qos.logback.core.pattern.color.ANSIConstants;

/**
 * 自定义日志颜色
 */
public class LogbackColorful extends ForegroundCompositeConverterBase<ILoggingEvent> {
    @Override
    protected String getForegroundColorCode(ILoggingEvent event) {
        Level level = event.getLevel();
        switch (level.toInt()) {
            //ERROR等级为红色
            case Level.ERROR_INT:
                return ANSIConstants.RED_FG;
            //WARN等级为黄色
            case Level.WARN_INT:
                return ANSIConstants.YELLOW_FG;
            //INFO等级为蓝色
            case Level.INFO_INT:
                return ANSIConstants.BLUE_FG;
            //DEBUG等级为绿色
            case Level.DEBUG_INT:
                return ANSIConstants.GREEN_FG;
            //其他为默认颜色
            default:
                return ANSIConstants.DEFAULT_FG;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_popo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值