package com.cpp.web.service.alarm;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.ThresholdFilter;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.OptionHelper;
import com.cpp.web.utils.ParsingFileUtil;
import org.slf4j.LoggerFactory;

/**
 * 创建动态日志
 *
 * @author xsl
 * @version 3.0
 */
public class AppenderFactory {
    private final String logLevel = "debug";
    private final String totalSizeCap = "20480MB";
    private final String maxFileSize = "50MB";
    private final String maxHistory = "90";

    /**
     * 通过传入的名字和级别，动态设置appender
     *
     * @return
     */
    public Logger getAppender() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        //这里是可以用来设置appender的，在xml配置文件里面，是这种形式：
        RollingFileAppender appender = new RollingFileAppender();
        //这里设置级别过滤器
        ThresholdFilter levelFilter = createLevelFilter(this.logLevel);
        levelFilter.start();
        appender.addFilter(levelFilter);
        // 但可以使用<contextName>设置成其他名字，用于区分不同应用程序的记录。一旦设置，不能修改。
        appender.setContext(context);
        //appender的name属性
        appender.setName("alarm");
        appender.setAppend(true);
        appender.setPrudent(false);
        //设置文件创建时间及大小的类
        SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
        //文件名格式
        String fp = OptionHelper.substVars(ParsingFileUtil.getLogsPath() + "/" + "%d{yyyy-MM-dd}" + "/" + "alarm.%d{yyyy-MM-dd}.%i.log", context);
        //最大日志文件大小
        policy.setMaxFileSize(FileSize.valueOf(this.maxFileSize));
        //设置文件名模式
        policy.setFileNamePattern(fp);
        //设置日志文件保留天数
        policy.setMaxHistory(Integer.parseInt(this.maxHistory));
        //总大小限制
        policy.setTotalSizeCap(FileSize.valueOf(this.totalSizeCap));
        //设置父节点是appender
        policy.setParent(appender);
        // 但可以使用<contextName>设置成其他名字，用于区分不同应用程序的记录。一旦设置，不能修改。
        policy.setContext(context);
        policy.setCleanHistoryOnStart(true);
        policy.start();
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        //设置上下文，每个logger都关联到logger上下文，默认上下文名称为default。
        // 但可以使用<contextName>设置成其他名字，用于区分不同应用程序的记录。一旦设置，不能修改。
        encoder.setContext(context);
        //设置格式
        encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n");
        encoder.start();
        //加入下面两个节点
        appender.setRollingPolicy(policy);
        appender.setEncoder(encoder);
        appender.start();
        Logger logger = context.getLogger("alarm");
        //设置不向上级打印信息
        logger.setAdditive(false);
        logger.addAppender(appender);
        return logger;
    }

    private ThresholdFilter createLevelFilter(String level) {
        ThresholdFilter levelFilter = new ThresholdFilter();
        levelFilter.setLevel(level);
        levelFilter.start();
        return levelFilter;
    }
}
