如果存在多个%d,则需要在不是作为分割时间的里面加上aux

    <springProperty scope="context" name="appLogPath"  source="appLogPath" defaultValue="/data/backup" />
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${appLogPath}/%d{yyyy-MM-dd,aux}/logFile.%d{yyyy-MM-dd_HH}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>[%date{yyyy-MM-dd HH:mm:ss.SSS}][%-5level]-[%thread][requestId:%X{requestId}][imei:%X{imei}][%logger][username:%X{userName}]-%msg
                %rootException %n</pattern>
        </encoder>
    </appender>

处理日志丢失

    <appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志。默认情况下,如果队列的 80% 已满,则会丢弃 TRACT 、DEBUG 、INFO 级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的 appender,最多只能添加一个 -->
        <appender-ref ref="FILE"/>
    </appender>

按自定义分钟进行拆分日志、按30分钟进行拆分日志

@Data
public class MyRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
    private int periodMinutes;
    @Override
    public void start() {
        MyTriggeringPolicy<E> triggeringPolicy = new MyTriggeringPolicy<E>();
        triggeringPolicy.setPeriodMinutes(periodMinutes);
        setTimeBasedFileNamingAndTriggeringPolicy(triggeringPolicy);
        super.start();
    @Override
    public String toString() {
        return "MyRollingPolicy";
public class MyTriggeringPolicy<E>  extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {
    protected int periodMinutes = 1;
    public int getPeriodMinutes() {
        return this.periodMinutes;
    public void setPeriodMinutes(int minutes) {
        if (minutes > 0) {
            this.periodMinutes = minutes;
    private long roundTimestamp(long time) {
        int periodTicks = periodMinutes * 60000;
        return periodTicks * (time / periodTicks);
    @Override
    public void setDateInCurrentPeriod(long now) {
        dateInCurrentPeriod.setTime(roundTimestamp(now));
    @Override
    public void setDateInCurrentPeriod(Date _dateInCurrentPeriod) {
        dateInCurrentPeriod = new Date(roundTimestamp(_dateInCurrentPeriod.getTime()));
    @Override
    public void computeNextCheck() {
        rc.setTime(dateInCurrentPeriod);
        rc.set(Calendar.SECOND, 0);
        rc.set(Calendar.MILLISECOND, 0);
        rc.add(Calendar.MINUTE, periodMinutes);
        nextCheck = rc.getTime().getTime();
    @Override
    public String toString() {
        return "MyTriggeringPolicy";
        <rollingPolicy class="com.peony.electric.server.config.MyRollingPolicy">
            <periodMinutes>30</periodMinutes>
            <fileNamePattern>${appLogPath}/%d{yyyy-MM-dd,aux}/logFile.%d{yyyy-MM-dd_HH_mm}.log</fileNamePattern>
            <maxHistory>720</maxHistory>
         </rollingPolicy>