ログファイルがあり、各行が追加されるたびにタイムスタンプを追加する必要があります。だから私はログ行の各エントリにタイムスタンプを追加し、cronジョブとして実行できるスクリプトを探しています。
ベストアンサー1
一般的な方法
$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log
仕組み:
cat
呼び出されたファイルを読み取り、input.log
標準出力ストリームとして印刷します。通常、標準出力は端末に接続されますが、この小さなスクリプトには、シェルが標準出力を
|
標準cat
入力にリダイレクトする内容が含まれていますsed
。sed
データを読み込み(cat
生成されたとおり)、データを処理し(-e
オプションで提供されているスクリプトに従って)、標準出力に印刷します。このスクリプトは、"s/^/$(date -R) /"
各行の先頭をdate -R
コマンドによって生成されたテキストに置き換えるためのものです(代替コマンドの一般的な構造は次のとおりです)s/pattern/replace/
。その後、出力は名前付きファイルに
>>
bash
リダイレクトされます(これはファイルの内容を置き換えて最後に追加することを意味します)。sed
output.log
>
>>
問題は、$(date -R)
スクリプトの実行時に一度だけ評価されるため、スクリプトが挿入されることです。現在の各行の先頭にあるタイムスタンプです。現在のタイムスタンプは、メッセージが生成された瞬間から離れている可能性があります。これを防ぐには、cronジョブを使用するのではなく、メッセージがファイルに書き込まれたときに処理する必要があります。
先入選出
上記の標準ストリームリダイレクトは次のとおりです。管路。スクリプト内のコマンド間でリダイレクトできるだけでなく、次のように|
リダイレクトすることもできます。先入れ先出しファイル(別名名前付きパイプ)。あるプログラムはファイルに書き込み、もう一方のプログラムはデータを読み取り、最初に送信されたときにそれを受け取ります。
例を選択してください:
$ mkfifo foo.log.fifo
$ while true; do cat foo.log.fifo | sed -e "s/^/$(date -R) /" >> foo.log; done;
# have to open a second terminal at this point
$ echo "foo" > foo.log.fifo
$ echo "bar" > foo.log.fifo
$ echo "baz" > foo.log.fifo
$ cat foo.log
Tue, 20 Nov 2012 15:32:56 +0400 foo
Tue, 20 Nov 2012 15:33:27 +0400 bar
Tue, 20 Nov 2012 15:33:30 +0400 baz
仕組み:
mkfifo
名前付きパイプの作成while true; do sed ... ; done
無限ループを実行して、繰り返しごとに標準入力にsed
リダイレクトします。foo.log.fifo
sed
入力データを待つブロックその後、受信したメッセージが処理され、にリダイレクトされた標準出力に印刷されますfoo.log
。この時点で、ループは現在の端末を占有するため、新しい端末ウィンドウを開く必要があります。
echo ... > foo.log.fifo
fifoファイルにリダイレクトされた標準出力にメッセージを印刷し、sed
それを受信して処理し、それを通常のファイルに書き込みます。
重要なことは、fifoは他のパイプと同様に、片側がプロセスに接続されていない限り意味がないことです。パイプに書き込もうとすると、現在のプロセスは詰まった誰かがパイプの反対側の端にあるデータを読み取るまでです。パイプからデータを読み取ろうとすると、プロセスは次のことを行います。詰まった誰かがパイプにデータを書き込むまで。上記の例のループは、sed
実行されるまで何もしません(休止状態)echo
。
場合によっては、fifoファイルにログメッセージを書き込むようにアプリケーションを簡単に構成できます。設定できない場合は、元のログファイルを削除してfifoファイルを作成してください。ただし、sed
何らかの理由でループが終了すると、誰かがfifoからファイルにアクセスするwrite
までファイルにアクセスしようとするプログラムがブロックされます。read
特典は現在のプログラムがファイルにメッセージを書き込むと、タイムスタンプが評価され、メッセージに追加されます。
非同期処理tailf
ログの書き込みと処理をさらに独立させるために、両方のプロセスを使用できますtailf
。アプリケーションはメッセージをソースファイルに書き込み、他のプロセスは新しい行を読み取り(非同期書き込み後)、データを処理して2番目のファイルに書き込みます。ファイル。
たとえば、見てみましょう。
# will occupy current shell
$ tailf -n0 bar.raw.log | while read line; do echo "$(date -R) $line" >> bar.log; done;
$ echo "foo" >> bar.raw.log
$ echo "bar" >> bar.raw.log
$ echo "baz" >> bar.raw.log
$ cat bar.log
Wed, 21 Nov 2012 16:15:33 +0400 foo
Wed, 21 Nov 2012 16:15:36 +0400 bar
Wed, 21 Nov 2012 16:15:39 +0400 baz
仕組み:
実行は、無限ループにリダイレクトされる標準出力にそれを書き込んで
tailf
印刷するプロセスに従います。このループは2つのことを行います。つまり、標準入力のデータをバッファ変数と呼ばれるバッファ変数に読み込み、次にバッファリングされたデータを含む結果のタイムスタンプを書き込みます。bar.raw.log
while read ... echo
line
bar.log
にメッセージを記入してください
bar.raw.log
。最初のターミナルウィンドウがいっぱいになり、書き込みに従い操作が完了するtailf
ため、別のターミナルウィンドウでこれを実行する必要があります。とても簡単です。
利点は、終了してもアプリケーションがブロックされないことですtailf
。欠点は、正確性の低いタイムスタンプと重複したログファイルです。