アクティブなログファイルから最初のN行を削除する


26

Nアプリケーションによってアクティブに追加されているログから最初の行を削除する方法はありますか?

回答:


10

いいえ、Linuxなどのオペレーティングシステム、およびそのファイルシステムは、ファイルの先頭からデータを削除するためのプロビジョニングを行いません。つまり、ファイルのストレージの開始点は固定されています。

ファイルの先頭から行を削除するには、通常、残りのデータを新しいファイルに書き込み、古いファイルを削除します。プログラムが古いファイルを書き込み用に開いている場合、そのファイルの削除は、アプリケーションがファイルを閉じるまで延期されます。


コメント者が述べたように、私の前の文で与えられた理由のために、通常、ログを書き込むプログラムとログファイルの整理を調整する必要があります。正確にこれを行う方法は、プログラムによって異なります。いくつかのプログラムは、シグナル(HUPなど)を送信するとログファイルを閉じて再度開きます。これを使用すると、サービスを中断することなく、ログレコードが「削除された」ログファイルに書き込まれないようにできます。

logrotateなど、ログファイルのサイズを管理するための多くのユーティリティがあります。

一部のプログラムには独自のユーティリティがあります。たとえば、Apache Webサーバーにはrotatelogsユーティリティが含まれています。


3
ただし、ファイルがまだ開いていて追加されている間は、これを実行しないでください。削除されたファイルに書き込みが行われ、ログメッセージが失われるためです。
タルネイカルマン

本当です。同じファイル名を使用した場合でも。
ヘネス

OSがあなたにそれを許していないのは残念です。これは、ログローターがローテーション後にプロセスをリロードする必要がないことは確かに便利でしょう。
rogerdpack

25

このタスクは次の方法で達成できると思います sed

sed -i '1,10d' myfile

1から行削除しますSTを 10に目のファイル形式のライン。

少なくとも誰もがこのsed 1ライナーを見るべきだと思う。

これは、アプリケーションによってアクティブに追加されているログファイルでは機能しないことに注意してください(質問で述べたように)。

sed -i新しいファイルを作成し、書き込まれているファイルを「削除」します。ほとんどのアプリケーションは、削除されたログファイルにログレコードを書き込み続け、ディスクスペースを使い続けます。切り捨てられた新しいログファイルは追加されません。これは、アプリケーションが再起動されるか、ログファイルを閉じて再度開くように指示された場合にのみ停止します。sedの使用とアプリケーションの再起動の間にログ可能なアクティビティがあった場合、新しいログファイルにギャップ(ログレコードの欠落)が生じます。

これを行う安全な方法は、アプリケーションを停止し、sedを使用してログを切り捨ててから、アプリケーションを再起動することです。このアプローチは、一部のサービス(たとえば、高スループットと高いサービス継続性要件を備えたWebサーバー)では受け入れられない場合があります。


2
追加しているアプリケーションに何が起こるか知っていますか?
アダムマタン

1
時々行を追加してフラッシュする通常のファイルハンドラーを想定してみましょう。
アダムMatan

1
私はsedを回避する方法を知っていますが、新しいファイルに行を抽出するのはsedで簡単です。問題は、すべてを同じファイルに保存することです。
アダムマタン

10
いいえ、これは機能しません。 編集したコンテンツで新しいファイルsed -i作成し、古いファイルを削除して、アクティブなファイルを編集しないようにします$ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile。------動作を確認してくださいsed -i。なぜこの間違った答えに非常に多くの賛成票があるのですか?
パブーク

1
質問は、「アプリケーションによってアクティブに追加されているログから」と述べています。有効な言葉は「積極的に」です。おそらくあなたの答えが現れた後にその説明が追加されたのでしょう。しかし、現状では、「ほとんどの賛成票」に惹かれている読者は誤解を招きます。一度だけ投票できました。
スコットプライヴ

5

いいえ。ログファイルの増大というこの一般的な問題の解決策は、ログのローテーションです。これには、既存のログファイルを他のファイル名に定期的に(通常は毎晩または毎週)移動し、空のログファイルから新たに開始することが含まれます。しばらくすると、古いログファイルは破棄されます。

参照:http : //www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm


2

これは答えであり、解決策ではありません。質問に対する解決策はありません。質問者は「アプリケーションによってアクティブに追加されているログから」と明確に述べています。続き を読んで理解を深め、最後までスキップして、このコードがロギングのベストプラクティスに従っていない理由を推測して、提案を行うことができます。

明確にするために、ここの他の「答え」は虚偽の約束を提供します。名前を変更しても、アプリケーションが新しいファイルを使用するようにだますことはありません。最も有用な情報は、これらの誤った回答に対するコメントに埋もれています。

ACTIVEファイルは、単にデータを入れるだけのコンテナではありません。ファイル名は1つのiノード(ファイルの先頭)を指し、すべてのiノードには別のiノードへのポインターがあります(さらにデータがある場合)。つまり、継続的に書き込まれるファイルには、追加されるiノードの一定のストリームがあり、「ファイル」について考えるのは、実際にはiノードのログシーケンスです。

Googleマップで誰かを追跡していて、その人がいつでも世界中のどこにでもテレポートでき、これらのドットを接続しようとしていると想像してください。

Linuxツール「truncate」は、iノードツリーを単純にたどることにより(指定した場所/サイズで)ファイル内のデータを破棄でき、スタック内の後続のポインターをすべて破棄します。ファイルの先頭でデータを破棄するという逆の操作を行うと、リアルタイムで iノードツリーを書き換えるという恐ろしく複雑で危険なプロセスになります。データロス。ウィキiノード短いですが、これらの概念のいくつかを説明します。

**私のアドバイス:この問題を回避する-なぜこのアプリケーションはこのように動作するのでしょうか?多くのロギングベストプラクティスがありますが、多くの場合、それらは実際のロギングシステム(syslogなど)に関係しています。コアでは、アプリケーションはファイルへのハンドルを「解放」することが期待されるため、logrotate(など)は古いデータのさらなる処理を処理できます。

「ACTIVEログファイルへ」と聞くたびに、すぐにその人にこのアプリケーションの背後にある「特別な物語」を教えてくれるように頼みます。通常、開発者は終了し、コードを変更できません。これは実際には安全性の逆であり、独自のリスクがあります。しかし、ソースコードに触れないようにするソリューションが必要です。ケースでは、より具体的な質問が必要です。


0

崇高なテキストで開くファイルが追加されている場合でも、行を削除してファイルを保存すると何らかの形で機能しますが、コマンドラインソリューションのソリューションを検索するためにここに来たので、この作業は役に立たないソリューションをここに残します!!


-1

たぶん、コピー、切り捨て、コピーを末尾に戻してsize = 0の切り捨て、コピーを削除しますか?

テールからテールへのコピーを改善し、オリジナルを切り捨て、テールコピーをオリジナルに連結します。

ログの行の末尾の長さはバイト長の制限よりも優れています。

コメントから詳細を修正:

まず、Python3のロガースクリプトがあります。

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

次に、トランケーターがあります

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.logは80から89を示しています

ログには90から終了までが表示されます

とにかく意志があるところには方法があります。

コンソリデーターのより複雑な例と書き込みストリームのオープンまたはクローズ方法は、CPUコアごとに調整する必要がある場合があります。ロギングプロセスなどのロガーでできる場合は、書き込みを一時停止してキューに入れるだけです。


「アプリケーションによってアクティブに追加されているログから」。ソリューションが見落としている問題は、ログファイルがアプリケーションによって「永続的に」使用されていることです。つまり、ログファイルのiノードが引き続き使用されているということです。あなたのソリューションはログファイルのデータを「バックアップ」しますが、これはこの質問以外の用途があるかもしれません。
スコットプライヴ

あなたのコメントと投票をありがとう?あなたの状況についてもっと深く考えなければならないだろうが、意志があるところには方法があるという考えのための食べ物として、簡単な安価な例を修正しました。
マスタージェームズ

それが私の反対票だとは思わないが、他の答えのコメントの要点は次のようになっていると思う。アプリケーションのファイルハンドルは、常に元のログファイルのiノードを指します。このように考えてください。非標準のログ機能を使用し、開いているファイルに継続的にバイトを追加するアプリケーションがあります。
スコットプライヴ

1
推測してすみません。はい、inodeは同じままにする必要があるため、指定された例/証明ではtruncateを使用します。これも状況に依存します(すべてのオプションは明らかにプレーンサイトに隠れています)。
マスタージェームズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.