附加時間戳以及日誌文件行
我有一個日誌文件,我需要在每行添加時間戳時附加它們。因此,我正在尋找將時間戳附加到日誌行中的每個條目並且可以作為 cron 作業執行的腳本。
一般方式
$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log
這個怎麼運作:
cat
讀取呼叫的文件input.log
並將其列印到其標準輸出流。通常標準輸出連接到終端,但是這個小腳本包含
|
所以 shell 將標準輸出重定向cat
到標準輸入sed
。 2.sed
讀取數據(cat
生成它),處理它(根據隨-e
選項提供的腳本),然後將其列印到其標準輸出。該腳本"s/^/$(date -R) /"
意味著將每個行首替換為由命令生成的文本date -R
(替換命令的一般結構是:)s/pattern/replace/
。 3. 然後根據>>
bash
將輸出重定向sed
到一個名為output.log
(>
表示替換文件內容並>>
表示追加到末尾)的文件。問題是
$(date -R)
在您執行腳本時評估一次,因此它將目前時間戳插入到每行的開頭。目前時間戳可能與生成消息的時刻相去甚遠。為避免這種情況,您必須在將消息寫入文件時處理它們,而不是使用 cron 作業。先進先出
上面描述的標準流重定向稱為pipe。您不僅可以
|
在腳本中的命令之間重定向它,還可以通過FIFO 文件(又名管道)來重定向它。一個程序將寫入文件,另一個程序將讀取數據並在第一次發送時接收它。舉個例子:
$ 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
。此時您必須打開一個新的終端視窗,因為循環佔用了目前終端。 3.
echo ... > foo.log.fifo
將消息列印到重定向到 fifo 文件的標準輸出並sed
接收它並處理並寫入正常文件。重要的注意事項是先進先出,就像任何其他管道如果其一側未連接到任何程序就沒有意義一樣。如果您嘗試寫入管道,目前程序將阻塞,直到有人讀取管道另一端的數據。如果您想從管道中讀取,該程序將阻塞,直到有人將數據寫入管道。上例中的
sed
循環在您執行之前什麼都不做(睡眠)echo
。對於您的特定情況,您只需將應用程序配置為將日誌消息寫入 fifo 文件。如果您無法配置它 - 只需刪除原始日誌文件並創建一個 fifo 文件。但是請再次注意,如果
sed
循環由於某種原因而終止 - 您的程序將在嘗試訪問write
文件時被阻止,直到有人read
從 fifo 中。好處是在程序將其寫入文件時評估並附加到消息的目前時間戳。
非同步處理
tailf
為了使寫入日誌和處理更加獨立,您可以使用兩個帶有
tailf
. 應用程序將消息寫入原始文件,其他程序讀取新行(隨後非同步寫入)並通過寫入第二個文件來處理數據。舉個例子:
# 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
將遵循寫入bar.raw.log
並將它們列印到重定向到無限while read ... echo
循環的標準輸出的過程。這個循環執行兩個動作:從標準輸入讀取數據到一個名為的緩衝區變數line
,然後將生成的帶有以下緩衝數據的時間戳寫入bar.log
.- 寫一些消息到
bar.raw.log
. 您必須在單獨的終端視窗中執行此操作,因為第一個視窗將被其占用tailf
,它將跟隨寫入並完成其工作。非常簡單。優點是如果你 kill ,你的應用程序不會阻塞
tailf
。缺點是不太準確的時間戳和重複的日誌文件。