3

ログフレームワークとしてログバックを使用していて、同じmain関数を異なるパラメーターで実行するジョブがいくつかあり、ジョブごとにログファイルを作成し、ログファイルにジョブの名前を付けたいと考えています。

たとえば、a,b,cすべて実行さMyClass.main()れているがパラメータが異なるジョブがある場合は、を表示しますa-{date}.log, b-{date}.log, c-{date}.log

でaを{date}指定することでこの部分を実現できますが、ファイル名のプレフィックスを動的に(ジョブの名前になるように)作成する方法がわかりません(または可能かどうかもわかりません)。<fileNamePattern>myjob-%d{yyyy-MM-dd}.log</fileNamePattern>logback.xml

ログバックでログファイルに動的に名前を付ける方法はありますか?これを可能にする別のロギングフレームワークはありますか?

mainフォローアップの質問として、異なるパラメーターで同じ関数を呼び出す複数のジョブがあり、各ジョブにちなんで名付けられたログファイルが必要な場合、私は悪いアプローチを取っていますか?もしそうなら、この場合の標準/ベストプラクティスソリューションはありますか?

編集:ジョブの名前にちなんで各ログファイルに名前を付けたい理由は、各ジョブが自然に「作業単位」を定義し、ジョブの1つが失敗した場合に適切なログファイルを見つけるのが簡単だからです。単純にローリングログファイルをジョブに使用することもできa,b,cましたが、ログを調べて各ジョブの開始位置と終了位置を特定するのが難しいことがわかりました。

4

4 に答える 4

2

私はあなた自身のロギングを使用します。

public static PrintWriter getLogerFor(String prefix) {
     SimpleDatFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     String filename= prefix + sdf.format(new Date());
     return new PrintWriter(filename, true); // auto flush.
}

LinkedHashMapを使用して単純なLRUキャッシュを記述し、PrintWriterを再利用できます。

于 2012-12-19T22:34:51.257 に答える
1

ログバックでログファイルに動的に名前を付ける方法はありますか?これを可能にする別のロギングフレームワークはありますか?

標準のlogback.xmlファイルで構成されたアペンダーout of the boxFileなど)を使用してこれが可能であるとは思いません。RollingFileやりたいことを行うには、その場で動的にアペンダーを作成し、ロガーを別のアペンダーに割り当てる必要があります。または、ロガー名に基づいて、同時に複数のファイルに書き込むのに十分スマートな新しいアペンダーを発明する必要があります。

異なるパラメーターを使用して同じメイン関数を呼び出す複数のジョブがあり、各ジョブにちなんで名付けられたログファイルが必要な場合、私は悪いアプローチを取っていますか?

ログバックの作成者は、この問題と、マップされた診断コンテキストslightly discourageのセクションで対処します。

あるクライアントのログ出力を別のクライアントと区別するための、考えられるが少し推奨されないアプローチは、クライアントごとに新しい個別のロガーをインスタンス化することです。この手法はロガーの急増を促進し、ロガーの管理オーバーヘッドを増加させる可能性があります。...より軽い手法は、特定のクライアントにサービスを提供する各ログ要求に一意のスタンプを付けることで構成されます。

次に、この問題の解決策として、マップされた診断コンテキストについて説明します。それらは、さまざまなスレッドのさまざまなクライアントに対して同時に数値を処理しているNumberCruncherServerの例を示しています。マップされた診断コンテキストと適切なログパターンを設定することにより、どのログイベントがどのクライアントから発生したかを簡単に判別できます。次に、grepツールを使用して、関心のあるログイベントを別のファイルに分割し、詳細な分析を行うことができます。

于 2012-12-19T23:05:50.957 に答える
0

はい、できます。

まず、ロガーとアペンダーという2つの概念に慣れておく必要があります。一般的に、コードはロガーを取得し、debug()、warn()、info()などのロギングメソッドを呼び出します。ロガーにはAppenderがアタッチされており、Appenderは次のように設定された構成に従ってロギング情報をユーザーに提示します。それ。

慣れてきたら、ジョブの種類ごとに異なるファイル名でFileAppenderを動的に作成し、それをロガーにアタッチする必要があります。

上記のいずれにも意味がない場合は、ログバックマニュアルを使用することをお勧めします。

于 2012-12-19T23:03:49.037 に答える
0

タグでディスクリミネーターのキーを使用できるため、ログバックディスクリミネーターを利用できます<FileNamePattern>。私は2つのオプションを考えることができます:

オプション1:

マップされた診断コンテキストディスクリミネーターを使用して、ログの分離を実装できます。を使用して、各ジョブから個別の値を設定する必要があります。MDC.put();

これを実行すると、ログバック構成のアペンダーは次のようになります。

<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
        <key>jobName</key> <!-- the key you used with MDC.put() -->
        <defaultValue>none</defaultValue>
    </discriminator>
    <sift>
        <appender name="jobsLogs-${jobName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${jobName}.%d{dd-MM-yyyy}.log.zip</FileNamePattern>
                .
                .
                .
            </rollingPolicy>
            <layout class="ch.qos.logback.classic.PatternLayout">
                <Pattern>...</Pattern>
            </layout>
        </appender>
    </sift>
</appender>

オプション2:

ch.qos.logback.core.sift.Discriminatorスレッド名に基づいて判別するために、独自の判別子-implementing-を実装します。次のようになります。

public class ThreadNameDiscriminator implements Discriminator<ILoggingEvent> {

    private final String THREAD_NAME_KEY = "threadName";

    @Override
    public String getDiscriminatingValue(ILoggingEvent event) {
    return Thread.currentThread().getName();
    }

    @Override
    public String getKey() {
    return THREAD_NAME_KEY;
    }

    // implementation for more methods
    .
    .
    .
}

ロギングアペンダーは、ディスクリミネータークラスがThreadNameDiscriminatorでキーがであるオプション1のようになりますthreadName。このオプションでは、ジョブからMDCに値を設定する必要がないため、ジョブを変更する必要はありません。

于 2013-02-13T16:12:44.247 に答える