私はログファイルに出力するスクリプトを常に実行しています:
script.sh >> /var/log/logfile
ログに追加される各行の前にタイムスタンプを追加したいと思います。好む:
Sat Sep 10 21:33:06 UTC 2011 The server has booted up. Hmmph.
使用できる柔術はありますか?
私はログファイルに出力するスクリプトを常に実行しています:
script.sh >> /var/log/logfile
ログに追加される各行の前にタイムスタンプを追加したいと思います。好む:
Sat Sep 10 21:33:06 UTC 2011 The server has booted up. Hmmph.
使用できる柔術はありますか?
回答:
スクリプトの出力を、現在の日付と時刻の前に付けるループを介してパイプできます。
./script.sh | while IFS= read -r line; do printf '%s %s\n' "$(date)" "$line"; done >>/var/log/logfile
これを頻繁に使用する場合、ループを処理するbash関数を簡単に作成できます。
adddate() {
while IFS= read -r line; do
printf '%s %s\n' "$(date)" "$line";
done
}
./thisscript.sh | adddate >>/var/log/logfile
./thatscript.sh | adddate >>/var/log/logfile
./theotherscript.sh | adddate >>/var/log/logfile
read
は、行頭と行頭の空白を切り取らないようにするのがコツです。read
コマンドに対してIFS(bashの内部フィールド区切り、基本的には空白文字のリスト)を空に設定します。
echo
。エスケープシーケンスを解釈する実装がいくつかあるためです。あなたがいる場合、実際にはない(日付を追加すること以外の)コンテンツを台無しにそれをしたい、置き換えecho
てコマンドをprintf "%s %s\n" "$(date)" "$line"
date
)を生成します。これは、マシンとログの量によっては大きな欠点になる可能性があります。可能であれば使用することをお勧めします。@ willemからの回答を参照してくださいts
日付のコマンドは、その情報を提供します
date -u
Sat Sep 10 22:39:24 UTC 2011
だからあなたはできる
echo $(date -u) "Some message or other"
それはあなたが欲しかったことですか?
コマンド出力をログファイルにエコーするだけです。すなわち、
echo "`date -u` `./script.sh`" >> /var/log/logfile
それは実際に動作します :)
例:
[sparx@E1]$ ./script.sh
Hello Worldy
[sparx@E1]$ echo "`date -u` `./script.sh`" >> logfile.txt
[sparx@E1]$ cat logfile.txt
Mon Sep 12 20:18:28 UTC 2011 Hello Worldy
[sparx@E1]$
作成しconfig.sh
たファイルを
#!/usr/bin/env bash
LOGFILE="/path/to/log.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
ログファイルに送信する必要がある場合
#!/usr/bin/env bash
source /path/to/config.sh
echo "$TIMESTAMP Say what you are doing" >> $LOGFILE
do_what_you_want >> $LOGFILE
ログファイルは次のようになります
2013-02-03 18:22:30 Say what you are doing
日付で並べ替えるのは簡単です
あなたは次のような意味です:
(date && script.sh) >> /var/log/logfile
script.sh
ます。OPでは、行ごとにタイムスタンプが必要です。
多くの行を処理する必要がある場合、受け入れられた回答https://serverfault.com/a/310104は少し遅くなります。プロセスを開始するオーバーヘッドによりdate
、Ubuntuでは1秒あたり約50行、わずか約10行Cygwinで-20。
ときは、bash
より高速な代替だろうと想定することができprintf
、その持つ組み込み%(...)T
書式指定子。比較する
>> while true; do date; done | uniq -c
47 Wed Nov 9 23:17:18 STD 2016
56 Wed Nov 9 23:17:19 STD 2016
55 Wed Nov 9 23:17:20 STD 2016
51 Wed Nov 9 23:17:21 STD 2016
50 Wed Nov 9 23:17:22 STD 2016
>> while true; do printf '%(%F %T)T\n'; done | uniq -c
20300 2016-11-09 23:17:56
31767 2016-11-09 23:17:57
32109 2016-11-09 23:17:58
31036 2016-11-09 23:17:59
30714 2016-11-09 23:18:00
awkは高速で実行されることに注意してください。
gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'
yes |head -5000000 |gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' |uniq -c
461592 [2017-02-28 19:46:44] y
488555 [2017-02-28 19:46:45] y
491205 [2017-02-28 19:46:46] y
498568 [2017-02-28 19:46:47] y
502605 [2017-02-28 19:46:48] y
494048 [2017-02-28 19:46:49] y
493299 [2017-02-28 19:46:50] y
498005 [2017-02-28 19:46:51] y
502916 [2017-02-28 19:46:52] y
495550 [2017-02-28 19:46:53] y
73657 [2017-02-28 19:46:54] y
しかし、sedははるかに高速に実行され、
sed -e "s/^/$(date -R) /"
yes |head -5000000 |sed -e "s/^/$(date -R) /" |uniq -c
5000000 Tue, 28 Feb 2017 19:57:00 -0500 y
ただし、詳細な検査では、セットは時間を変更しないようです。
vmstat 1 | sed -e "s/^/$(date -R) /"
"s/^/$(date -R) /"
sedの前に日付を1回評価して実行するbashであるためです。Sedには静的な文字列が渡されます。
yes | head -5000000 | while read line; do echo $((SECONDS)); done | uniq -c
gawkよりもはるかに遅いです。ts
ユーティリティは、bashループと同様のパフォーマンスを発揮します。
yes |head -5000000 |perl -ne 'print localtime."\t".$_' |uniq -c
awkよりも少し遅いです。
以下は私のログファイルの内容です
xiongyu@ubuntu:~/search_start_sh$ tail restart_scrape.log
2017-08-25 21:10:09 scrape_yy_news_main.py got down, now I will restart it
2017-08-25 21:10:09 check_yy_news_warn.py got down, now I will restart it
2017-08-25 21:14:53 scrape_yy_news_main.py got down, now I will restart it
シェルの内容の一部は以下のとおりです
log_file="restart_scrape.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
echo "$TIMESTAMP $search_py_file got down, now I will restart it" | tee -a $log_file
このスクリプトは、出力を端末に出力し、ログファイルにも保存します。
#!/bin/bash
MY_LOG=/var/log/output.log
echolog(){
if [ $# -eq 0 ]
then cat - | while read -r message
do
echo "$(date +"[%F %T %Z] -") $message" | tee -a $MY_LOG
done
else
echo -n "$(date +'[%F %T %Z]') - " | tee -a $MY_LOG
echo $* | tee -a $MY_LOG
fi
}
echolog "My script is starting"
whoami | echolog
サンプル出力:
[2017-10-29 19:46:36 UTC] - My script is starting
[2017-10-29 19:46:36 UTC] - root
別のオプションは、コードでデータを出力するたびに呼び出す関数をセットアップすることです。
PrintLog(){
information=$1
logFile=$2
echo "$(date +'%Y-%m-%d %H:%M:%S" $information} >> $logFile
}
その後、コード内でログファイル呼び出しに送信するたびに
PrintLog "Stuff you want to add..." ${LogFileVariable}
簡単に...