51

以下を行うようにログバックを構成したいと思います。

  • ファイルにログを記録する
  • 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>
4

12 に答える 12

30

他の提案はどれも私の状況には適切ではありませんでした。サイズと時間に基づくソリューションは、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
        }
    }

}

秘訣は、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> 

お役に立てれば!

于 2012-09-13T14:20:49.417 に答える
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);
    }
}
于 2011-02-01T14:16:49.220 に答える
3

ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP で isTriggeringEvent() メソッドをオーバーライドすると、うまく機能するはずです。isTriggeringEvent() メソッドが最初に呼び出されたときに「true」を返すだけです。

于 2010-03-22T20:39:11.910 に答える
2

Cekiの解決策は私にはうまくいかないように見えますが、少なくとも部分的にはうまくいっているようです。

の起動時にローリング ポリシーが表示されないため、失敗しTimeBasedFileNamingAndTriggeringPolicyBaseます。いくつかのハッカーでログを記録し、さらにトリガーを観察しましたが、ファイル名のプロパティの1つを解決できなかったため、再び壊れました...パッケージはログバックパッケージなので、私は内部の一部にアクセスして、 のロジックの一部を複製し、SizeAndTimeBasedFNATP#isTriggeringEventを呼び出すことができますcomputeCurrentPeriodsHighestCounterValue。魔法の組み合わせがまだ見つかっていないだけで、これらの線に沿った何かが機能する可能性があると思います. そうしないと、サブクラス化のために詳細の一部を開くか、これを別のローリング/トリガーポリシーとしてログバックに直接入れることになると思うので、何かばかげたことをしていることを本当に願っています。

logback.xml: の内部と外部のさまざまな順序を試しtriggeringPolicyましTimeBasedFileNamingAndTriggeringPolicyrollingPolicy

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/${LOG_FILE_BASE}.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${LOG_DIR}/${LOG_FILE_BASE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <MaxHistory>7</MaxHistory>

        <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.RollOnStartupPolicy" />
    </rollingPolicy>

    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>

    <encoder>
        <pattern>%msg%n</pattern>
    </encoder>
</appender>

トリガー ポリシー:

package ch.qos.logback.core.rolling;
public class RollOnStartupPolicy<E> extends SizeAndTimeBasedFNATP<E> {
private final AtomicBoolean firstTime = new AtomicBoolean(true);

    @Override
    public boolean isTriggeringEvent(File activeFile, E event) {
        if (!firstTime.get()) { // fast path
            return false;
        }

        if (firstTime.getAndSet(false)) {
            return true;
        }
        return false;
    }
}

例外:

java.lang.NullPointerException
at  at ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicyBase.start(TimeBasedFileNamingAndTriggeringPolicyBase.java:46)
at  at ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP.start(SizeAndTimeBasedFNATP.java:36)
at  at ch.qos.logback.core.joran... [snip joran config]
于 2010-04-15T17:15:02.293 に答える
1

の独自のサブクラスを作成してch.qos.logback.core.rolling.TimeBasedRollingPolicyオーバーライドするstart

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

    public void start ( )
    {
        super.start( );
        rollover( );
    }
}
于 2010-03-22T12:25:42.880 に答える
1

私は以下を機能させました(以前の回答からのアイデアを組み合わせています)。時間ベースではなく、サイズベースのファイルを扱っていたことに注意してください。しかし、同じソリューションが機能すると推測しています。

public class StartupSizeBasedTriggeringPolicy<E> extends ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy<E> {

private final AtomicReference<Boolean> isFirstTime = new AtomicReference<Boolean>(true);

@Override
public boolean isTriggeringEvent(final File activeFile, final E event) {

    //this method appears to have side-effects so always call
    boolean result = super.isTriggeringEvent(activeFile, event);

    return isFirstTime.compareAndSet(true, false) || result;
}

}

于 2012-08-26T16:41:17.053 に答える
1

このソリューションは本当にうまくいきます。どうもありがとう。ただし、厄介な不具合が 1 つあります。最初にプログラムを実行すると、ログが作成された直後に、ログが空またはほとんど空になったときに、ログがロールバックされます。したがって、修正をお勧めします。メソッドが呼び出されたときにログファイルが存在し、空でないかどうかを確認してください。また、もう 1 つの表面的な修正: "started" 変数の名前を変更します。これは、継承されたメンバーが同じ名前で隠されているためです。

@NoAutoStart
public class StartupSizeTimeBasedTriggeringPolicy<E> extends     SizeAndTimeBasedFNATP<E> {

    private boolean policyStarted;

    @Override
    public boolean isTriggeringEvent(File activeFile, E event) {
        if (!policyStarted) {
            policyStarted = true;
            if (activeFile.exists() && activeFile.length() > 0) {
                nextCheck = 0L;
                return true;
            }
        }
        return super.isTriggeringEvent(activeFile, event);
    }
}

また、logback バージョン 1.1.4-SNAPSHOT (ソースを入手して自分でコンパイルしたもの) では適切に動作すると思いますが、1.1.3 リリースでは完全には動作しません。1.1.3 では、指定されたタイム ゾーンでファイルに適切な名前が付けられますが、ロールオーバーはデフォルトのタイム ゾーンの午前 0 時に発生します。

于 2015-07-10T03:46:33.617 に答える