如何在logback中启动时滚动日志文件

Mik*_*e Q 44 java startup logback appender

我想配置logback来执行以下操作.

  • 登录到文件
  • 达到50MB时滚动文件
  • 只保留7天的日志
  • 在启动时总是生成一个新文件(滚动)

除了最后一项,启动滚动,我已经完成了所有工作.有谁知道如何实现这一目标?这是配置......

  <appender name="File" class="ch.qos.logback.core.rolling.RollingFileAppender">

    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg \(%file:%line\)%n</Pattern>
    </layout>

    <File>server.log</File>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>server.%d{yyyy-MM-dd}.log</FileNamePattern>
      <!-- keep 7 days' worth of history -->
      <MaxHistory>7</MaxHistory>

      <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <MaxFileSize>50MB</MaxFileSize>
      </TimeBasedFileNamingAndTriggeringPolicy>

    </rollingPolicy>
  </appender>
Run Code Online (Sandbox Code Playgroud)

Dav*_*ave 26

没有其他建议适合我的情况.我不想使用基于大小和时间的解决方案,因为它需要配置MaxFileSize,我们使用严格的基于时间的策略.以下是我使用TimeBasedRollingPolicy在启动时滚动文件的方法:

@NoAutoStart
public class StartupTimeBasedTriggeringPolicy<E> 
        extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {

    @Override
    public void start() {
        super.start();
        nextCheck = 0L;
        isTriggeringEvent(null, null);
        try {
            tbrp.rollover();
        } catch (RolloverFailure e) {
            //Do nothing
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

诀窍是将nextCheck时间设置为0L,这样isTriggeringEvent()就会认为是时候滚动日志文件了.因此,它将执行计算文件名所需的代码,以及方便地重置nextCheck时间值.随后对rollover()的调用会导致日志文件被滚动.由于这仅在启动时发生,因此它比在isTriggerEvent()内执行比较的解决方案更优化.无论比较小,它在每条日志消息上执行时仍会略微降低性能.这也会强制在启动时立即发生翻转,而不是等待第一个日志事件.

@NoAutoStart注释对于防止Joran在所有其他初始化完成之前执行start()方法非常重要.否则,您将获得NullPointerException.

这是配置:

  <!-- Daily rollover appender that also appends timestamp and rolls over on startup -->
  <appender name="startupDailyRolloverAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_FILE}.%d{yyyyMMdd}_%d{HHmmss,aux}</fileNamePattern>
      <TimeBasedFileNamingAndTriggeringPolicy class="my.package.StartupTimeBasedTriggeringPolicy" />
    </rollingPolicy>
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender> 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 由于我的要求是命令行工具,我根本不需要基于时间的触发,所以我能够通过切换到`FixedWindowRollingPolicy`和一个带有`isTriggering`方法的自定义`TriggeringPolicy`类来实现它.只返回一次`true`. (2认同)

pro*_*tif 7

它适用于我,使用以下类作为timeBasedFileNamingAndTriggeringPolicy:

import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;

import ch.qos.logback.core.joran.spi.NoAutoStart;
import ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP;

@NoAutoStart
public class Trigger<E> extends SizeAndTimeBasedFNATP<E>
{
    private final AtomicBoolean trigger = new AtomicBoolean();

    public boolean isTriggeringEvent(final File activeFile, final E event) {
        if (trigger.compareAndSet(false, true) && activeFile.length() > 0) {
            String maxFileSize = getMaxFileSize();
            setMaxFileSize("1");
            super.isTriggeringEvent(activeFile, event);
            setMaxFileSize(maxFileSize);
            return true;
        }
        return super.isTriggeringEvent(activeFile, event);
    }
}
Run Code Online (Sandbox Code Playgroud)


duf*_*356 5

当应用程序启动时,我找到了另一种滚动logFile的解决方案.

我使用logback的RollingFileAppenderlogback FixedWindowRollingPolicy和我自己的a实现TriggeringPolicy<E>.

FixedWindowRollingPolicy新的日志文件,在那里得到fileNamePattern %1是文件的新号码.maxIndex代表我的"历史"的最大数量.更多信息:FixedWindowRollingPolicy

当isTriggeringEvent(...)被调用时,我的实现一次TriggeringPolicy返回true .因此,当第一次调用策略时,WindowRollingPolicy将覆盖日志文件,之后它将不再翻转.

xml配置RollingFileAppender:

<configuration>
    ...
    <appender name="FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logFile.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>logFile.%i.log</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>4</maxIndex>
        </rollingPolicy>

        <triggeringPolicy class="my.classpath.RollOncePerSessionTriggeringPolicy"/>
    </appender>
...
</configuration>
Run Code Online (Sandbox Code Playgroud)

TriggeringPolicy:

package my.classpath;

import ch.qos.logback.core.rolling.TriggeringPolicyBase;

import java.io.File;

public class RollOncePerSessionTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
    private static boolean doRolling = true;

    @Override
    public boolean isTriggeringEvent(File activeFile, E event) {
        // roll the first time when the event gets called
        if (doRolling) {
            doRolling = false;
            return true;
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)


rai*_*tin 5

对于使用现有组件的解决方案,logback建议使用唯一命名的文件:http://logback.qos.ch/manual/appenders.html#uniquelyNamed

在应用程序开发阶段或短期应用程序(例如批处理应用程序)的情况下,需要在每次新的应用程序启动时创建新的日志文件.在<timestamp>元素的帮助下,这很容易做到.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <timestamp key="startTimestamp" datePattern="yyyyMMddHHmmssSSS"/>
    <appender name="File"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg \(%file:%line\)%n</Pattern>
        </layout>

        <file>server-${startTimestamp}.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>server-${startTimestamp}-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
            <!-- keep 7 days' worth of history -->
            <MaxHistory>7</MaxHistory>

            <TimeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <MaxFileSize>1KB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="File" />
    </root>
</configuration>
Run Code Online (Sandbox Code Playgroud)

更新为logback-1.2.1

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <timestamp key="startTimestamp" datePattern="yyyyMMddHHmmssSSS"/>
    <appender name="File"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg \(%file:%line\)%n</Pattern>
        </layout>

        <file>server-${startTimestamp}.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>server-${startTimestamp}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <!-- keep 7 days' worth of history -->
            <maxHistory>7</maxHistory>
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="File" />
    </root>
</configuration>
Run Code Online (Sandbox Code Playgroud)

  • 这种方法以及这里几乎所有方法的问题是,由于“fileNamePattern”已更改,logback 将无法在重新启动时进行清理。仅当实例运行时才会发生清理,因为时间戳将保持不变。我能看到的唯一解决方案是修改 TimeBaseArchiveRemover。 (2认同)

Ale*_*yak 1

创建您自己的子类ch.qos.logback.core.rolling.TimeBasedRollingPolicy并覆盖它start

public class MyPolicy
    extends ch.qos.logback.core.rolling.TimeBasedRollingPolicy
{

    public void start ( )
    {
        super.start( );
        rollover( );
    }
}
Run Code Online (Sandbox Code Playgroud)