У меня есть постоянно работающий скрипт, который я вывожу в файл журнала:
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
Видеть ts
из Ubuntu moreutils
пакет:
command | ts
Или если $command
выполняет автоматическую буферизацию (требуется expect-dev
пакет):
unbuffer command | 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
Так будет легко сортировать по дате
Принятый ответ https://serverfault.com/a/310104 может быть немного медленным, если нужно обработать много строк, с накладными расходами на запуск date
процесс, позволяющий около 50 строк в секунду в Ubuntu и только около 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
Вы имеете в виду как:
(date && script.sh) >> /var/log/logfile
Попробуй это
timestamp()
{
date +"%Y-%m-%d %T"
}
Вызовите эту функцию отметки времени в каждой команде echo:
echo "$(timestamp): write your log here" >> /var/log/<logfile>.log
script.sh | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' >> /var/log/logfile
awk
быстро бегает и может работать как конвейерный фильтр Unix и напечатать дату отдельно.
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 -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) /"
Так как date
(который, кстати, медленнее) вызывается только один раз.
Ниже приведено содержимое моего файла журнала.
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}
Очень просто....
Введите "sed":
script.sh | sed "s|^|$('date') :: |" >> /var/log/logfile
Я просто так делаю (buddy
переменная - это просто пример, вы можете поместить туда что угодно):
#!/bin/bash
now=$( date +%Y%m%d-%H%M-%S )
buddy=`cat /proc/buddyinfo | grep Normal`
echo "$now, $buddy" >> /home/myuser/buddyinfo-logger.log
Это прекрасно работает.