ログファイル行でタイムスタンプを追加する

ログファイル行でタイムスタンプを追加する

ログファイルがあり、各行が追加されるたびにタイムスタンプを追加する必要があります。だから私はログ行の各エントリにタイムスタンプを追加し、cronジョブとして実行できるスクリプトを探しています。

ベストアンサー1

一般的な方法

$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log

仕組み:

  1. cat呼び出されたファイルを読み取り、input.log標準出力ストリームとして印刷します。

    通常、標準出力は端末に接続されますが、この小さなスクリプトには、シェルが標準出力を|標準cat入力にリダイレクトする内容が含まれていますsed

  2. sedデータを読み込み(cat生成されたとおり)、データを処理し(-eオプションで提供されているスクリプトに従って)、標準出力に印刷します。このスクリプトは、"s/^/$(date -R) /"各行の先頭をdate -Rコマンドによって生成されたテキストに置き換えるためのものです(代替コマンドの一般的な構造は次のとおりです)s/pattern/replace/

  3. その後、出力は名前付きファイルに>> bashリダイレクトされます(これはファイルの内容を置き換えて最後に追加することを意味します)。sedoutput.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

仕組み:

  1. mkfifo名前付きパイプの作成

  2. while true; do sed ... ; done無限ループを実行して、繰り返しごとに標準入力にsedリダイレクトします。foo.log.fifosed 入力データを待つブロックその後、受信したメッセージが処理され、にリダイレクトされた標準出力に印刷されますfoo.log

    この時点で、ループは現在の端末を占有するため、新しい端末ウィンドウを開く必要があります。

  3. echo ... > foo.log.fifofifoファイルにリダイレクトされた標準出力にメッセージを印刷し、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

仕組み:

  1. 実行は、無限ループにリダイレクトされる標準出力にそれを書き込んでtailf印刷するプロセスに従います。このループは2つのことを行います。つまり、標準入力のデータをバッファ変数と呼ばれるバッファ変数に読み込み、次にバッファリングされたデータを含む結果のタイムスタンプを書き込みます。bar.raw.logwhile read ... echolinebar.log

  2. にメッセージを記入してくださいbar.raw.log。最初のターミナルウィンドウがいっぱいになり、書き込みに従い操作が完了するtailfため、別のターミナルウィンドウでこれを実行する必要があります。とても簡単です。

利点は、終了してもアプリケーションがブロックされないことですtailf。欠点は、正確性の低いタイムスタンプと重複したログファイルです。

おすすめ記事