로그 파일 라인과 함께 타임 스탬프 스탬프 추가


11

로그 파일이 있으며 타임 라인을 추가 할 때 각 줄에 타임 스탬프를 추가해야합니다. 그래서 로그 라인의 각 항목에 타임 스탬프를 추가하고 cron 작업으로 실행할 수있는 스크립트를 찾고 있습니다.

답변:


18

일반적인 방법

$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log

작동 방식 :

  1. cat호출 된 파일을 읽고 input.log표준 출력 스트림으로 인쇄합니다.

    일반적으로 표준 출력은 터미널에 연결되어 있지만이 작은 스크립트에는 |쉘이 표준 출력 cat을의 표준 입력으로 리디렉션합니다 sed.

  2. sed옵션 cat과 함께 제공된 스크립트에 따라 데이터를 읽고 처리 -e한 다음 표준 출력으로 인쇄합니다. 이 스크립트 "s/^/$(date -R) /"는 모든 줄의 시작을 date -R명령에 의해 생성 된 텍스트로 바꾸는 것을 의미합니다 (바꾸기 명령의 일반적인 구성은 다음과 같습니다 s/pattern/replace/).

  3. 그런 다음에 따르면 파일 >> bash의 출력 을 리디렉션합니다 ( 파일 내용 바꾸기 및 끝에 추가하는 것을 의미 함).sedoutput.log>>>

문제는 $(date -R)스크립트를 실행할 때 한 번 평가되므로 각 줄의 시작 부분에 현재 타임 스탬프 가 삽입 됩니다. 현재 타임 스탬프는 메시지가 생성 된 순간과는 거리가 멀 수 있습니다. 이를 피하려면 cron 작업이 아닌 파일에 메시지를 쓸 때 메시지를 처리해야합니다.

선입 선출

위에서 설명한 표준 스트림 리디렉션은 pipe 라고 합니다. |스크립트의 명령 사이뿐만 아니라 FIFO 파일 (일명 pipe )을 통해 리디렉션 할 수 있습니다 . 한 프로그램은 파일에 쓰고 다른 프로그램은 데이터를 읽고 첫 번째 전송으로 수신합니다.

예를 선택하십시오.

$ 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

작동 방식 :

  1. mkfifo 명명 된 파이프를 만듭니다.

  2. while true; do sed ... ; done무한 루프를 실행하고 모든 반복에서 표준 입력 sed으로 리디렉션 foo.log.fifo하여 실행됩니다 . sed 입력 데이터 대기를 차단 한 다음 수신 된 메시지를 처리하여로 리디렉션 된 표준 출력으로 인쇄합니다 foo.log.

    루프가 현재 터미널을 차지하므로이 시점에서 새 터미널 창을 열어야합니다.

  3. echo ... > foo.log.fifofifo 파일로 경로 재 지정된 표준 출력으로 메시지를 인쇄하고 sed이를 수신하여 처리하고 일반 파일에 씁니다.

중요한 점은 측면 중 하나가 프로세스에 연결되어 있지 않으면 다른 파이프가 의미가없는 것처럼 fifo입니다. 파이프에 쓰려고하면 누군가 파이프의 다른 쪽에서 데이터를 읽을 때까지 현재 프로세스가 차단 됩니다 . 파이프에서 읽으려면 누군가 파이프에 데이터를 쓸 때까지 프로세스가 차단 됩니다. sed당신이 할 때까지 예를 루프 위에 아무것도 (잠을) 않습니다 echo.

특정 상황에서는 fifo 파일에 로그 메시지를 쓰도록 응용 프로그램을 구성하기 만하면됩니다. 구성 할 수없는 경우 원본 로그 파일을 삭제하고 fifo 파일을 만드십시오. 그러나 sed어떤 이유로 루프가 죽으면 write파일을 누군가가 readfifo에서 나올 때까지 파일 을 시도 할 때 프로그램이 차단됩니다 .

장점은 프로그램에서 파일에 쓸 때 현재 타임 스탬프가 평가되어 메시지에 첨부되는 것입니다.

비동기 처리 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

작동 방식 :

  1. tailf쓰기를 수행 bar.raw.log하고 무한 while read ... echo루프로 리디렉션 된 표준 출력으로 인쇄하는 프로세스를 실행 합니다 . 이 루프는 표준 입력에서 호출 된 버퍼 변수로 데이터를 읽은 line다음 생성 된 타임 스탬프를 다음 버퍼링 된 데이터와 함께에 기록합니다 bar.log.

  2. 에 메시지를 작성하십시오 bar.raw.log. tailf쓰기 작업을 수행하고 작업을 수행 하는 첫 번째 터미널이 점유되므로 별도의 터미널 창에서이 작업을 수행해야합니다. 아주 간단합니다.

장점은 당신이 죽이면 응용 프로그램이 차단되지 않을 것 tailf입니다. 단점은 덜 정확한 타임 스탬프 및 복제 로그 파일입니다.


고맙습니다 .Fifo는 내 사용에 매우 적합한 것 같습니다 .my 프로그램은 이미 file.txt 로그에 기록하지만이 파일은 foo.log.fifo.But $ tailf file.txt> foo.log.fifo 중단으로 리디렉션해야합니다. ! 업데이트 로그 파일의 내용을이 foo.log.fifo로 어떻게 리디렉션하여 시간을 추가 할 수 있습니까?
Kratos

답을 개선했습니다. fifo가 귀하를 차단하는 이유를 설명 tailf하고 올바른 사용법을 추가했습니다. 실제로와 함께하는 방법 tailf이 더 우아해 보이지만 나는 fifo를 떠나 누군가에게 유용 할 수 있기를 바랍니다.
Dmitry Vasilyanov

sed 응답을 사용하여 vmstat 출력에 주석을 달면 변경되지 않는 타임 스탬프가 생성됩니다. vmstat 1 | sed -e "s / ^ / $ (date -R) /"
ChuckCottrill


2

Dmitry Vasilyanov의 답변에서 수정되었습니다.

bash 스크립트에서는 타임 스탬프를 사용하여 출력을 한 줄씩 재지 정하고 줄 바꿈 할 수 있습니다.

사용시기 :

  • bash 스크립트 작업의 경우 기본 스크립트 앞에 줄을 삽입하십시오.
  • 비 스크립트 작업의 경우 프로그램을 호출하는 스크립트를 작성하십시오.
  • 시스템별로 서비스를 제어하려면 tailfDmitry Vasilyanov가 말한 것처럼 로그 파일 에 사용 하는 것이 좋습니다 .

예를 들면 foo.sh:

#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)

echo "foo"
sleep 1
echo "bar" >&2
sleep 1
echo "foobar"

그리고 결과 :

$ bash foo.sh
$ cat foo.log
May 12 20:04:11 foo
May 12 20:04:12 bar
May 12 20:04:13 foobar

작동 원리

  1. exec &> stdout 및 stderr를 동일한 위치로 리디렉션
  2. >( ... ) 파이프 출력을 비동기 내부 명령으로
  3. 나머지 부분은 Dmitry Vasilyanov가 확장되면서 작동합니다.

예를 들면 다음과 같습니다.

  • 파이프 타임 스탬프 및 파일에 로그

    #!/bin/bash        
    exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
    
    echo "some script commands"
    /path-to/some-thrid-party-programs
    
  • 또는 타임 스탬프를 인쇄하고 stdout에 기록

    #!/bin/bash        
    exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line"; done;)
    
    echo "some script commands"
    /path-to/some-thrid-party-programs
    

    그런 다음 /etc/crontab설정에 저장하십시오.

    * * * * * root /path-to-script/foo.sh >> /path-to-log-file/foo.log
    

1

내가 사용하는 ts내가 선인장 원격 호스트의 통계를 가득 얻을하는 데 사용하는 스크립트에 대한 오류 로그의 시간 스탬프 항목을 얻기 위해 이런 식으로.

Cacti를 테스트 rand하기 위해 시스템 온도를 모니터링하기 위해 온도 그래프에 사용하는 임의의 값을 추가합니다.

Pushmonstats.sh는 내 PC의 시스템 온도 통계를 수집하여 Cacti가 실행되는 Raspberry Pi로 전송하는 스크립트입니다. 얼마 전에 네트워크가 중단되었습니다. 오류 로그에 SSH 시간 초과가 발생했습니다. 불행히도, 해당 로그에 시간 항목이 없습니다. 로그 항목에 타임 스탬프를 추가하는 방법을 몰랐습니다. 그래서 인터넷에서 검색을 한 후이 게시물을 우연히 발견했으며 이것이 내가 사용 한 것 ts입니다.

그것을 테스트하기 위해 알 수없는 옵션을 사용했습니다 rand. stderr에 오류가 발생했습니다. 이를 캡처하기 위해 임시 파일로 리디렉션합니다. 그런 다음 cat을 사용하여 파일의 내용을 표시하고로 파이프 ts하고이 게시물에서 찾은 시간 형식을 추가하고 오류 파일에 기록합니다. 그런 다음 임시 파일의 내용을 지우십시오. 그렇지 않으면 동일한 오류에 대한 이중 항목이 나타납니다.

크론 탭 :

* * * * * /home/monusr/bin/pushmonstats.sh 1>> /home/monusr/pushmonstats.log 2> /home/monusr/.err;/bin/cat /home/monusr/.err|/usr/bin/ts %F-%H:%M:%.S 1>> /home/monusr/pushmonstats.err;> /home/monusr/.err

이것은 내 오류 로그에 다음을 제공합니다.

2014-03-22-19:17:53.823720 rand: unknown option -- '-l'

어쩌면 이것이 매우 우아한 방법은 아니지만 효과가 있습니다. 더 우아한 접근 방식이 있는지 궁금합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.