스크립트 로그를 bash에 타임 스탬프를 추가하는 방법은 무엇입니까?


94

로그 파일로 출력되는 지속적으로 실행되는 스크립트가 있습니다.

script.sh >> /var/log/logfile

로그에 추가되는 각 줄 앞에 타임 스탬프를 추가하고 싶습니다. 처럼:

Sat Sep 10 21:33:06 UTC 2011 The server has booted up.  Hmmph.

사용할 수있는 jujitsu가 있습니까?


2
이 퀘스트를보십시오. serverfault.com/questions/80749/... . 여기에 몇 가지 답변이 적용됩니다.
Zoredache


다음은 bash에 대한 포괄적 인 로깅 구현입니다. github.com/codeforester/base/blob/master/lib/stdlib.sh
codeforester

답변:


88

현재 날짜와 시간을 앞에 붙이는 루프를 통해 스크립트 출력을 파이프 할 수 있습니다.

./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

3
@Nils read처음과 줄에서 공백을 자르는 것을 방지하는 것이 요령 입니다. read명령에 대해 IFS (bash의 내부 필드 구분 기호, 기본적으로 공백 문자 목록)를 비 웁니다 .
Gordon Davisson

2
...- r은 이스케이프 문자 "\"를 무시합니다. 이것은 모든 경우에 실제로 작동해야합니다-훌륭한 스크립팅.
Nils

7
@Nils는 echo해석 이스케이프 시퀀스 의 일부 구현으로 완전히 방탄이 아닙니다 . 당신이 경우 정말 하지 (날짜를 추가하는 것보다 다른) 내용에 엉망으로 원하는 바꾸기 echo로 명령을printf "%s %s\n" "$(date)" "$line"
고든 데이비슨

4
ISO-8601 호환 날짜 / 시간 소인 에 관심이 date -u +"%Y-%m-%dT%H:%M:%SZ"있거나 더 예쁘다 date +"%Y-%m-%d %T".
Pablo A

1
이 스크립트는 예상대로 작동하지만 로그 라인 date대해 새 프로세스 (execute )를 생성합니다. 이는 시스템과 로그 양에 따라 막대한 단점이 될 수 있습니다. ts가능한 경우 사용 하는 것이 좋습니다. @willem의 답변 참조
Michael Schaefers

56

ts우분투 moreutils패키지 에서 참조하십시오 :

command | ts

또는 $command자동 버퍼링을 수행하는 경우 ( expect-dev패키지 필요 ) :

unbuffer command | ts

18

날짜 명령은 해당 정보를 제공 할 것입니다

date -u
Sat Sep 10 22:39:24 UTC 2011

그래서 당신은 할 수 있습니다

echo $(date -u) "Some message or other"

그게 당신이 원하는 것입니까?


date 명령을 사용하는 것이 마음에 들었지만 실제로 스크립트 자체에 추가 할 수는 없으므로 "script.sh >> / var /를 변경하는 방법입니다. log / logfile "을 입력하여 날짜를 추가하십시오.
Antonius Bloch

이 경우 스크립트 출력을 명명 된 파이프로 리디렉션하고 출력을 수신하는 데몬이 있어야합니다.이 출력은 스크립트 출력을 가져 와서 로그 파일에 쓰기 전에 날짜를 추가합니다. 여기에 작성한 스크립트를 수정 하여이 작업을 수행 할 수 있습니다 . 그것은 나에게 관심이 있기 때문에 나는 그것을 할 것이다. 그러나 그것은 영국에서 늦었다. 그리고 나는 내일 빠른 출발을 가지고있다.
user9517

12

명령 출력을 로그 파일에 에코 할 수 있습니다 . 즉,

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]$ 

흠 나를 위해 작동하지 않습니다.
Antonius Bloch

명령을 실행할 때 무엇을 얻습니까?
SparX

8
그러면 각 줄이 아닌 ''./script.sh ''의 전체 출력 앞에 타임 스탬프가 표시됩니다.
clacke

8

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

날짜별로 쉽게 정렬 할 수 있습니다.


8
''config.sh ''는 ''source ... / config.sh ''에서 ''date ''를 정확히 한 번만 실행합니다.
clacke

5

당신은 다음과 같은 것을 의미합니다 :

(date && script.sh) >> /var/log/logfile

내 신, 사람, 모두가 진드기 교체, 명명 된 파이프 등을 수행하고 있습니다. 날짜 명령과 스크립트를 모두 괄호로 묶습니다! 여러 줄 출력이 있고 로그가 모든 줄의 날짜와 함께 예쁘게 보일 필요가있는 경우 함수를 가진 사람은 합법적 인 사례를 갖지만 이러한 솔루션의 대부분은 쉘 의미를 사용하지 않는 과잉입니다.
cjc

8
실행마다 타임 스탬프를 한 번만 추가합니다 script.sh. OP에는 라인 당 타임 스탬프가 필요합니다.
Dave Forgac

1
이것은 OP 질문에 대답하지 않지만 여전히 유용한 정보를 찾았습니다.
사용자

4

이 시도

timestamp()
{
 date +"%Y-%m-%d %T"
}

모든 echo 명령에서이 타임 스탬프 함수를 호출하십시오.

echo "$(timestamp): write your log here" >> /var/log/<logfile>.log

@ shazbot : 편집 해 주셔서 감사합니다. 오타 오류였습니다.
Sanjay Yadav

4

많은 라인을 처리 해야하는 경우 허용되는 https://serverfault.com/a/310104 응답 이 약간 느려질 수 있습니다. 프로세스를 시작하는 오버 헤드로 date인해 우분투에서 초당 약 50 라인이 허용됩니다. 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

1

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) /"

1
이것은 "s/^/$(date -R) /"sed 전에 한 번 평가 하고 실행하는 bash이기 때문입니다 . Sed는 정적 문자열로 전달됩니다.
Evan Benn

일반 배쉬 : yes | head -5000000 | while read line; do echo $((SECONDS)); done | uniq -c개크보다 훨씬 느립니다. ts유틸리티는 bash 루프와 비슷한 성능을 가지고 있습니다.
akhan

Perl : yes |head -5000000 |perl -ne 'print localtime."\t".$_' |uniq -cawk보다 약간 느립니다.
akhan

1

아래는 내 로그 파일 내용입니다

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 

1

이 스크립트는 출력을 터미널에 인쇄하고 로그 파일에도 저장합니다.

#!/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

첫 번째 날짜 명령은 큰 따옴표가 아닌 작은 따옴표를 사용해야합니다.
Jason Harrison

1

다른 옵션은 코드에서 데이터를 출력 할 때마다 호출 할 함수를 설정하는 것입니다.

PrintLog(){
  information=$1
  logFile=$2
  echo "$(date +'%Y-%m-%d %H:%M:%S" $information} >> $logFile
}

그런 다음 코드에서 매번 로그 파일 호출로 보내려고합니다.

PrintLog "Stuff you want to add..." ${LogFileVariable}

쉬워요....


0

"sed"파이프 :

script.sh | sed "s|^|$('date') :: |" >> /var/log/logfile

다른 답변에 관해서는, 이것은 bash running date입니다. sed가 라인 당 시간을 업데이트하지 않습니다.
Evan Benn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.