Ant*_*och 124 linux shell bash logging
我有一个不断运行的脚本,我输出到日志文件:
script.sh >> /var/log/logfile
Run Code Online (Sandbox Code Playgroud)
我想在附加到日志的每一行之前添加一个时间戳。喜欢:
Sat Sep 10 21:33:06 UTC 2011 The server has booted up. Hmmph.
Run Code Online (Sandbox Code Playgroud)
有什么柔术可以用吗?
Gor*_*son 110
您可以通过带有当前日期和时间前缀的循环来管道脚本的输出:
./script.sh | while IFS= read -r line; do printf '%s %s\n' "$(date)" "$line"; done >>/var/log/logfile
Run Code Online (Sandbox Code Playgroud)
如果你经常使用它,很容易制作一个 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
Run Code Online (Sandbox Code Playgroud)
Wil*_*lem 75
ts从 Ubuntumoreutils包中查看:
command | ts
Run Code Online (Sandbox Code Playgroud)
或者,如果$command自动缓冲(需要expect-dev包):
unbuffer command | ts
Run Code Online (Sandbox Code Playgroud)
use*_*517 33
该日期的命令将提供信息
date -u
Sat Sep 10 22:39:24 UTC 2011
Run Code Online (Sandbox Code Playgroud)
这样你就可以
echo $(date -u) "Some message or other"
Run Code Online (Sandbox Code Playgroud)
那是你想要的吗?
Spa*_*arX 11
您可以简单地将命令输出回显到日志文件中。IE,
echo "`date -u` `./script.sh`" >> /var/log/logfile
Run Code Online (Sandbox Code Playgroud)
真的行 :)
例子:
[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]$
Run Code Online (Sandbox Code Playgroud)
小智 10
制作config.sh文件
#!/usr/bin/env bash
LOGFILE="/path/to/log.log"
TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"`
Run Code Online (Sandbox Code Playgroud)
当您需要发送到日志文件时使用
#!/usr/bin/env bash
source /path/to/config.sh
echo "$TIMESTAMP Say what you are doing" >> $LOGFILE
do_what_you_want >> $LOGFILE
Run Code Online (Sandbox Code Playgroud)
日志文件看起来像
2013-02-03 18:22:30 Say what you are doing
Run Code Online (Sandbox Code Playgroud)
所以按日期排序会很容易
接受的答案https://serverfault.com/a/310104可能有点慢,如果必须处理很多行,启动date过程的开销在 Ubuntu 中每秒允许大约 50 行,而只有大约 10 -20 在 Cygwin。
什么时候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
Run Code Online (Sandbox Code Playgroud)
评论。在我目前的 OpenSuse 工作 PC(2021 年 7 月)上,性能显着提高,每秒执行 1200 行,date使用printf. 不完全清楚,与 5 年前的笔记本电脑相比,这种特殊的性能如何提高了近两个数量级。
script.sh | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' >> /var/log/logfile
Run Code Online (Sandbox Code Playgroud)
awk运行速度快,能够作为 Unix 管道过滤器工作并自行打印日期。
gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'
Run Code Online (Sandbox Code Playgroud)
让我们对其进行基准测试:
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
然而,仔细观察,设置似乎并没有改变时间,
vmstat 1 | sed -e "s/^/$(date -R) /"
Run Code Online (Sandbox Code Playgroud)
因为date(顺便说一句,速度较慢)只被调用一次。
你的意思是:
(date && script.sh) >> /var/log/logfile
Run Code Online (Sandbox Code Playgroud)
小智 5
尝试这个
timestamp()
{
date +"%Y-%m-%d %T"
}
Run Code Online (Sandbox Code Playgroud)
在每个 echo 命令中调用这个时间戳函数:
echo "$(timestamp): write your log here" >> /var/log/<logfile>.log
Run Code Online (Sandbox Code Playgroud)