web-dev-qa-db-ja.com

JBossとLogrotateがNUL文字でいっぱいのログファイルを作成するのはなぜですか?

JBoss Application Server4.2.2.GAログを毎晩ローテーションするようにLogrotateを設定しました。ログファイルがローテーションされ、JBossが再び書き込みを開始すると、新しいログファイルは前のログファイルの文字数と同じ数のNUL文字で始まり、その後に新しいログメッセージが続きます。たとえば、JBoss server.logファイルの長さが5000バイトの場合、ローテーション後、新しいserver.logファイルは5000NUL文字で始まります。数日後、server.logは、前日のすべてのログファイルの文字を結合したものに相当するNUL文字で始まります。 JBossがログファイル内での位置を覚えていて、切り捨てられたファイルで中断した場所を取得しているようです。これがJBossのlogrotate設定です:

/apps/jboss-4.2.2.GA/server/default/log/*log {
    daily
    rotate 30
    compress
    notifempty
    copytruncate
    missingok
    nocreate
}

ダウンタイムが多すぎるため、JBossを毎晩再起動することはできません。また、log4j DailyRollingFileAppenderは古いログファイルを削除しないため、使用できません。誰かがlogrotateをJBossで正しく動作させましたか?

7
Ben Williams

Log4jによって書き込まれるファイルについても同じ問題が発生しました。解決策は、FileAppenderのプロパティ「Append」を「true」に設定することでした。この変更後、logrotateなどの外部プログラムによってローテーションされたときにNULを含むファイルでこの問題が発生することはありません。

7
Maitreya

私の経験から-そしてLog4jでlogrotateを使用しない理由は、logrotateが機能する方法は、ファイルの名前を変更し、プログラムにログを閉じて古いファイル名(もう存在しない)で再度開くように指示するためです。 )、通常はHUP信号を使用します。

しかし、Log4jはログファイルを再度開くように指示できないため、代わりにcopytruncateを使用してファイルをコピーします。問題は、Log4jが、書き込まれているファイルの現在の位置を追跡するバッファ付きライターを使用することです。また、ログファイルを切り捨てると、log4jは、切り捨てる前に書き込みを停止した場所から書き込みを続けます。ファイルシステムの実装に応じて、これにより「穴のあるファイル」が作成されます。つまり、そこに表示されるNULL文字は実際には存在しません。ファイルは実際には実際のデータと同じ大きさであり、NULL文字はビューアが穴。一方、一部のファイルシステムはホールをサポートしておらず、Log4jが書き込みを再開すると、実際にファイルがNULL文字で埋められます。

私は提案します-logrotateを使用せず、RollingFileAppender(古いファイルの削除をサポートします)を使用するか、DailyRollingFileAppenderと古いファイルを外部から削除するcronjobを使用してLog4j内のファイルを回転させる方法を見つけます(それが行われることを意図していたため) )。

5
Guss

これは完全に機能します。 @Gussが提案したことを要約すると:

1。 「log4j.xml」を開き、次のアペンダーを追加します(DailyRollingAppenderクラスを使用し、毎日ロールオーバーするように構成しました)。

*注:ロールオーバーの頻度は「DatePattern」に基づいています。参照: http://www.codejava.net/coding/configure-log4j-for-creating-daily-rolling-log-files

<appender name="RollingAppender" class="org.Apache.log4j.DailyRollingFileAppender">
       <param name="File" value="/logging_directory_path_here/server1.log" />
       <param name="DatePattern" value="'.'yyyy-MM-dd" />
       <layout class="org.Apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>          
       </layout>
    </appender>

    <root>
            <priority value="info" />
            <appender-ref ref="RollingAppender" />
    </root>
  1. ロールオーバーされたログファイルを圧縮するシェルスクリプトを作成します。
  2. そのシェルスクリプトをUnixサーバーのCrontabにインストールして、毎日実行します。例えば毎日午前12:10に実行されます(なぜ午前12:10ですか?これにより、ログファイルが大きすぎる場合、またはログファイルが多すぎる場合に備えて、log4jがロールオーバーを完了するための十分な時間が与えられます。圧縮)。
  3. 最後に、log4jロールオーバーが12:00 a.m.(デフォルト)で実行され、シェルスクリプトを実行するcronジョブが12:10 a.m.であることを確認します。
0
Michael Co