0

本番環境で、状況によってはログ ファイルがロールオーバーされないという問題に直面しています。Log4j バージョン 1.2.17 と apache.commons-logging を使用しています。ファイルをロールオーバーするためのカスタム アペンダーが作成されます。アペンダーは、Log4j の FileAppender を拡張しています。subAppend(LoggingEvent event) メソッドのアルゴリズムは次のとおりです。

long n = System.currentTimeMillis();
// Has the time come to roll the log file?
if (n >= nextCheck)
{
 now.setTime(n);
    nextCheck = rc.getNextCheckMillis(now);

    rollOver();
    reachedMaxSize = false;

 else
 {
     File f = new File(getFile());

     // Has the log file has exceeded its maximum size?
     if (!reachedMaxSize && f.length() > maxFileSize)
     {
         // Log file has reached it maximum size.
         reachedMaxSize = true;

         // Log one last message to the file stating the max has been reached.
         LoggingEvent exeededEvent = new LoggingEvent(
                      getClass().getName(),
                      Logger.getLogger(getClass().getName()),
                      Priority.ERROR,
                      "Maximum log file size has been reached ("+maxFileSize/1024+"KB)",
                      null);
       super.subAppend(exeededEvent);
     }

 // If the log has not reached its max size, write it. Otherwise,
 // send log event to stdout.
 if (!reachedMaxSize)
 {
     super.subAppend(event);
 }
 else
 {
     System.out.println(event.getRenderedMessage());
 }

Log4j.properties ファイルは次のとおりです。

log4j.rootLogger=INFO,RCFLog

log4j.appender.RCFLog=com.ge.medit.util.logging.MaxFileSizeRollingFileAppender
log4j.appender.RCFLog.File=runtime/logs/rcf.log
log4j.appender.RCFLog.DatePattern=yyyyMMdd'_'{0}
log4j.appender.RCFLog.Encoding=UTF-8
log4j.appender.RCFLog.Append=true

log4j.appender.ConsoleLog=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleLog.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleLog.layout.ConversionPattern=%p [%t] %c{1}: %m%n

log4j.appender.RCFLog.layout=org.apache.log4j.PatternLayout
log4j.appender.RCFLog.layout.ConversionPattern=@%d{yyyyMMdd HH:mm:ss.SSS}@ %p {%t} %c{1}: %m%n

log4j.logger.GUIEVT=INFO

観察によると、システムに日付の変更がありました。日付は、現在の日付の 3 か月前に設定されました。

Current Date- 10th May 2018
nextCheck - 11th May 2018 00:00
Changed Date- 10th March 2018
No backup is created as a condition at line 3 failed.

5 月 11 日の 12 時間後、日付は現在の日付に変更されました。その時までに、ファイルのタイムスタンプは 3 月 10 日に変更されました。RollOver がなかったため、次のチェックはまだ 2018 年 5 月 11 日 00:00 でした。しかし、5 月 12 日の 00:00 に、ファイルは 3 行目の条件に従ってロールオーバーされ、新しいファイルが作成されたはずですが、発生しませんでした。また、ファイルが最大サイズに達していました。それ以降、システムが再起動されるまでログはありませんでした。

Java のバージョンはjava8u162です。Javaに関連しているかどうかを示す投稿は見つかりませんでしたが。

同じシナリオをテスト環境で再現しようとしましたが、すべてが期待どおりに機能しています。

Log4jでこのような問題に直面した人はいますか? あなたの情報を共有してください。前もって感謝します。

4

2 に答える 2

0

最良の方法はコードをデバッグすることだと思います.log4jは他のコードと同じようにデバッグできます.これがなければ推測することしかできません.

あなたの構成から、あなたが使用しcom.ge.medit.util.logging.MaxFileSizeRollingFileAppender ているのはlog4jの標準的なローリングファイルアペンダーではないことがわかります(おそらく、バグのある可能性のあるあなたの会社のカスタムアペンダーです)。

デバッグできない場合は、いくつかのヒントしか提供できませんが、それが役立つことを願っています。

  1. アペンダーを変更し、アペンダー自体の作業に関する情報を出力するために使用org.apache.log4j.helpers.LogLogします。これは、「log4j 内のログ」のようなものです。重大度レベルに応じて System.out/System.err に移動します。

  2. 通常、ロールオーバー (「ロールオーバー」機能を参照) は、一連のファイルの「名前変更」として実装されます。このメソッドが機能するのは、次の場合に限られることを 1 回見たことがあります (これも推測のみです)。

    • あなたはファイルに対する権限を持っています
    • あなたのアプリケーションは、ファイル上の唯一のハンドルを所有しています (特に Windows OS に関連します)。

名前変更操作が成功したか失敗したかに応じてtrue/falsejava.io.File#renameToを返す技術的に名前変更はおそらく行われるため、デバッグで追跡するのは簡単です。

この状況をシミュレートするために、ログをメッセージで「フラッディング」するだけの「隠し」コードをデプロイできます (JMX、内部 Web サーブレット/メッセージ ハンドラーを使用できます。必要なものは何でも構いませんが、その内部には大量のメッセージを含めることができます)。次のようなループでメッセージ (偽) をログに記録します。

class MyHiddenMBean {
    Logger logger = ...
    public void doLogManyTimes(int times) {
         for(int i = 0; i < times; i++) {
             logger.info("Artificial Logging Message : " + i);
         }
    } 
}

すぐに最大ファイルに到達します (もちろん、シミュレートを高速化するために意図的に途方もなく小さくすることもできます)。その後、なぜrenameTo機能しないのかを確認できます。

于 2018-05-28T12:24:44.517 に答える