web-dev-qa-db-ja.com

logrotateを使用せずにログファイルサイズを固定する

新しい空のファイルでログファイルをローテーションしたり、古いファイルを削除(またはアーカイブ)したりせずに、ログファイルのファイルサイズを一定に保つ方法はありますか。たとえば、ログファイルの最大サイズを1MBに設定した場合、ファイルサイズがその制限を超えて増加すると自動的にクランプされ、テキストが「末尾」に追加され、テキストの最も古い部分がポップアウトされてファイルサイズを1MBに保ちます。

13
uray

これを行うための小さなbashスクリプトを書くことができます。 tail -cを使用してファイルを特定のバイト数に調整し、ファイルを上書きします。

man tailから:

-c, --bytes=N
              output the last N bytes; alternatively, use +N to  output  bytes
              starting with the Nth of each file

   If  the  first  character of N (the number of bytes or lines) is a `+',
   print beginning with the Nth item from the start of each  file,  other‐
   wise, print the last N items in the file.  N may have a multiplier suf‐
   fix:  b  512,  kB  1000,  K  1024,  MB  1000*1000,  M   1024*1024,   GB
   1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.
4
jjclarkson

元のポスターが8年後に解決策を見つけたと私は確信しています。これは、このスレッドを読む可能性がある他の人のための別のものです...

次のコマンドを使用して、プログラムの出力のサイズを制限し、最後の200MBの出力を保持します。

run_program | curtail -s 200M myprogram.log

https://github.com/Comcast/Infinite-File-Curtailer

0
Dave Wolaver
 *プルーン-
 *ファイル/ etc/default/Pruneに記述されているファイルのリストの先頭から切り取ります。定期的に実行するように設計されています
 * cronからのアイデアは、ログファイルを自動的に短縮することです。このファイルには、
 *ファイル(完全パス名)のリストと、保持する必要があるブロック数
 *が含まれます。健全性を保つために、Pruneは次の改行の後にファイルをクリップします
 *。ファイル
 */etc/default/Pruneは次のようになります。
 * 
 */usr/adm/aculog 10 
 */usr/adm/leo .log 5 
 */usr/adm/messages 200 
 */usr/adm/sup_log 5 
 * 
 * Pruneのinfoswxのcrontabエントリは次のようになります:
 * 
 * 0 5 * * */etc/Prune> /usr/adm/Prune.log 2>&1 
 * 
 *コンパイル:cc -O -​​o Prune prune.c 
 * 
 *次の定義は、好みに合わせて調整できます
 *およびシステムブロックサイズ。
 * 
 *レイ・デイビスinfoswx!bees 09/25/85 

https://groups.google.com/group/mod.sources/browse_thread/thread/b2136b3ab7e924e/f785b37c218bb576?hl=ja&ie=UTF-8&q=Prune+log+file&pli=1

多くの(ほとんど?すべて?)デーモンは、HUPシグナル(たとえば、Pruneを実行する同じcronジョブによって)が送信されると、ログファイルを再度開きます。

0
RedGrittyBrick

唯一の解決策は、独自のユーザースペースファイルシステムを作成するか、既存のファイルシステムに貢献することです。 Filesystem in Userspace の部分的なリストを見てください。

貢献するスキルがない場合は、プロジェクトの広報または$$$またはその両方を提供して、プロジェクトを追加してください。

私はそれをする時間があればいいのにと思っています。私はいつもこれとまったく同じものを望んでいました。

0

FIFOを使用して同様のことができます。これは、サイズが0バイトのファイルのようなものです。

ただし、このファイルから何も読み取っていない場合、syslogプロセスがブロックされ、すべてのログファイルへの書き込みが停止することに注意してください。 Ubuntu/CentOSの新しいバージョンでこの動作が変更されたかどうかはわかりません。

一例 ここ

別の例として、次のようなものを試してください。

FIFOを作成します。

Sudo mkfifo /var/log/everything.fifo

これを(r)syslog.confに追加し、syslogを再起動します。

*.*     |/var/log/everything.fifo

次に、FIFOを1つのウィンドウから表示します。

cat /var/log/everything.fifo

そして別のウィンドウで、いくつかのものをsyslogに送信します:

logger Test1
logger Test2
logger Test3

上記のcatの出力に「Test *」行が表示されます。

この機能は、特にデータを長期間保持する必要がない場合に、デバッグに最適です。たとえば、ファイアウォールスパム以外のすべてを表示したい場合は、次のようにします。

grep -vi "kernel: .* on wan" /var/log/everything.fifo
0

これが私の2番目の答えです。これはかなりハックです。

Watch(1)を使用してtail --bytes=1024を繰り返し実行します(@jjclarksonの回答により、ログファイルの最後の1024バイトです)。

watch --no-title tail --bytes=1024 /var/log/messages >/tmp/messages.watch

そして、次のコマンドでファイルを表示します。

less --raw-control-chars /tmp/messages.watch

watchとwhileループの違いは、watchは/ var/log/messagesに変更があった場合にのみ/tmp/messages.watchを更新するということです。

while true; do
    tail --bytes=1024 /var/log/messages > /tmp/messages.watch
    sleep 1
done

また、whileループにtestを入れて、/ var/log/messagesが更新された場合にのみテールが実行されるようにできると思いますが、今はわかりません。

0