Logrotate成功、元のファイルが元のサイズに戻る


11

logrotateでログファイルがローテーションされ、元のサイズに戻るという問題が発生する前に誰かがいましたか?私の発見は次のとおりです。

Logrotateスクリプト:

/var/log/mylogfile.log {
    回転7
    毎日
    圧縮する
    olddir / log_archives
    行方不明
    気づかない
    切り捨てる
}

Logrotateの詳細な出力:

/var/log/mylogfile.logを/log_archives/mylogfile.log.1にコピーする
/var/log/mylogfile.logの切り捨て
/ bin / gzipでログを圧縮する
古いログの削除/log_archives/mylogfile.log.8.gz

切り捨てが発生した後のログファイル

[root @ server〜]#ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 part1 part1 0 Jan 11 17:32 /var/log/mylogfile.log

文字通り数秒後:

[root @ server〜]#ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 part1 part1 3.5G Jan 11 17:32 /var/log/mylogfile.log

RHELバージョン:

[root @ server〜]#cat / etc / redhat-release 
Red Hat Enterprise Linux ESリリース4(Nahant Update 4)

Logrotateバージョン:

[root @ DAA21529WWW370〜]#rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

いくつかのメモ:

  • サービスをその場で再起動できないため、copytruncateを使用しています
  • 毎晩olddirログファイルが格納されているディレクトリに従って、ログは毎晩回転しています。

回答:


18

これはおそらく、ファイルを切り捨てたとしても、ファイルへの書き込みプロセスは、最後にオフセットになったところから書き込みを続けるためです。そのため、logrotateはファイルを切り捨て、サイズは0になり、プロセスはファイルに再度書き込みを行い、残りのオフセットでファイルを書き込み、切り捨てた時点までにNULLバイトのファイルと新しいファイルを追加します。ログに書き込まれたエントリ。

od -c切り捨て+突然の成長の後、次の行に沿って出力を生成しました。

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

これは、オフセット0から33255657600までで、ファイルはヌルバイトで構成され、その後、読みやすいデータで構成されます。この状態に到達するのに、実際にすべてのヌルバイトを書き込むのにかかる時間はかかりません。ext {2,3,4}ファイルシステムはスパースファイルと呼ばれるものをサポートしているため、何も含まれていないファイルの領域を検索すると、その領域はnullバイトを含むと見なされ、スペースを占有しませんディスク上。これらのヌルバイトは実際には書き込まれず、単にそこにあると想定されるため、0〜3.5GBに移動するのにかかる時間はそれほどかかりません。(のような処理を行うことにより、所要時間をテストできdd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1ます。これにより、数ミリ秒で3GBを超えるファイルが生成されるはずです)。

ls -lsログファイルが切り捨てられ、再び急成長した後にログファイルを実行すると、実際のサイズ(ディスク上で占有されているブロック単位)を表す行の先頭に数字が表示されるはずです。だけで報告されるサイズよりも小さいls -l


私はそうは思いません-数秒で、ログファイルは0バイトから3.5GBになります。logrotateが完了するのにかかる合計時間は約5分です。ログファイルはそれほど速く書き込まれず、サイズは常に元のサイズになりますが、これは偶然のようです。
ドリューロックシャード

これを簡単に確認し、ファイルを調べて、実際に何かが含まれているかどうかを確認する簡単な方法が必要です。od -c filenameを実行して開始します| head -n100。数行で、nullバイトのトラック負荷に加えて、最新のログエントリがあることがわかります。
ジェチルヨルゲンセン

この場合、cat / dev / null> /var/log/mylogfile.logがcopytruncateに組み込まれたlogrotateを使用するのではなく、この問題を解決する方法でファイルを切り捨てるかどうかをテストできますか?
mtinberg

2
問題はファイルが切り捨てられる方法にあるのではなく、問題はプログラムがログファイルを書き込む方法にあります。ログファイルを切り捨てて実行可能なアプローチにするためには、プログラムにログファイルへの書き込みを何らかの方法で0の位置にシークさせる必要があります。スパースファイルをサポートしないファイルシステムでは、この問題が発生しない可能性があります今のところそれをテストする方法はありません。
はKjetil Joergensen

1
この最終的な回答は実際にはより意味があり、おそらく修正はアプリケーションを再起動することになるでしょう。
ドリューロックシャード

2

私は非常にはKjetilがそれを襲っていることを確信。ドリュー、あなたはまだ彼の説明に納得していないかもしれませんが、私はあなたが彼の言ったことを注意深く読むことをお勧めします。

受け入れた場合、修正はログがローテーションされたときにアプリケーションを停止して再起動するか、Apacheの「rotatelogs」のようなツールを使用することです。ログファイルを頻繁にローテーションします。たとえば、私のApacheインスタンスの1つは

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

次のような名前の多くのログファイルが作成されます

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

Apacheを再起動せずに表示されます。事後、それらを手動で圧縮できます。ローテーションが毎週行われる方法、つまり604800秒ごとに、引数がに渡されることに注意してくださいrotatelogs

アプリを停止して再起動できず、パイプ経由でログに記録できない場合は、本当の問題があると思います。おそらく他の人が提案をするでしょう。


0

logrotate全体を送信できれば本当に素晴らしいでしょう。

なぜkill -HUPを使用しようとするのですか?(再起動せずにクラシックリロード)メソッド。

また、... lsof ファイルにアクセスしているユーザーを確認します。


kill -HUPこのアプリケーションは一切触れられないため使用できません-それは私が所有していない機密性の高いアプリケーションです(管理していません-OS側のみを管理しています)。仕方。
ドリューロックシャード

1
申し訳ありませんが、元のメッセージは早めに送信されました。元のメッセージの残りの部分は次のとおりです。今朝、システムにログインしました/etc/cron.daily。すべての質問:logrotateスクリプトがlogrotateを手動で実行するのとは異なることはありますか 私のlogrotateスクリプトは文字通りのように見えます/usr/sbin/logrotate /etc/logrotate.conf。これは非常に不可解です。
ドリューロックシャード

-1

このファイルに書き込むスクリプトから作成することを意味する「>」ではなく、追加を意味する「>>」を使用します。まったく同じ問題があり、スクリプトでappendを使用して修正しました。

SomeScript.sh >> output.txt

それがより明確であることを願っています。


ログファイルへの書き込みが>スクリプトを使用して行われたことを示すものはありません。さらに、スクリプト>>( )スクリプトには大きな違いがあるため、この答えは混乱を招きます。最後に、書き込みを行うコードが更新された場合、新しいログファイルへの書き込みを開始した後logrotate、そのログファイルへの書き込みを開始する方がはるかに良いでしょう。
カスペルド

答えを編集して、わかりやすくします。
user578558
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.