다양한 타임스탬프 형식의 로그 파일 병합

다양한 타임스탬프 형식의 로그 파일 병합

두 가지 유형의 로그 파일이 있습니다.

표준 시스템 로그 형식

타임 스탬프는 다음과 같습니다

5:2015 Dec 21 07:35:06:ABC:foo1:1559: common.c:946:Enabling filter
6:2015 Dec 21 07:35:08:ABC:bar1:1461: api.c:124:Trigger activated
6:2015 Dec 21 07:35:16:BMC:kernel:-:<6>drivers/usb1_1.c:598:Error processing request on endpoint 0

사용자 정의 로그 형식

날짜와 시간은 파일의 첫 번째 줄에 표시됩니다. 다음 줄은 첫 번째 줄의 "반대"입니다. 예는 다음과 같습니다:

Timestamp H:M:S 15:4:1 D:M:Y 16:1:2015
Firmware Version: 121020150140
[04:01]------------[ Logs ]------------
[04:03]Device Data: -> Supported Attributes -> 0x8033B
[04:01]Device Cleanup

[04:19]SendClearMsg ...
[04:23]Param:GetData failed
[04:51]Current Update Count:7
[05:01]MODECHK:Normal mode

타임스탬프 4:01은 15:4:1 이후 4분 1초이므로 15:08:2로 변환해야 합니다.

이를 달성하기 위한 제안이 있습니까?

  • 상대 시간을 절대 시간으로 변환
  • syslog와 시간별로 정렬된 하나의 큰 파일로 병합

답변1

이 솔루션은 awk 스크립트를 사용하여 첫 번째 파일의 날짜를 에포크 이후의 초 단위로 변환하고 해당 숫자를 출력 앞에 추가합니다. 우리는 awk 함수를 호출하여 힘든 작업을 수행하고 date +%s --date명령의 출력을 awk 변수에 캡처합니다. (awk 구문은 다음과 같습니다.secsgetline주문하다 | getline 바꾸다).

awk <log1 >log1.new '
{ y = substr($0,3,4); m = $2; d = $3; hms = substr($0,15,8)
  "date \"+%s\" --date \"" d " " m " " y " " hms "\"" | getline secs
  print secs " " $0
}'

두 번째 awk 스크립트는 두 번째 파일에서 동일한 작업을 수행하지만 awk 변수에 저장된 타임스탬프가 있는 첫 번째 줄에서만 수행됩니다 base. 다른 줄에서는 해당 기준에 분과 초 오프셋을 추가하고 date첫 번째 파일의 형식을 사용하여 에포크 이후의 초를 실제 날짜로 변환합니다.

awk <log2 >log2.new '
/^Timestamp/{ split($5,x,":"); dmy = sprintf("%04d/%02d/%02d",x[3],x[2],x[1])
              split($3,x,":"); hms = sprintf("%02d:%02d:%02d",x[1],x[2],x[3])
              "date \"+%s\" --date \"" dmy " " hms "\"" | getline base
}
/^\[/ { mins = substr($0,2,2); secs = substr($0,5,2);
        tot = base + mins*60+secs
        "date \"+%Y %b %d %H:%M:%S\" --date @" tot | getline date
        print tot " -:" date " " substr($0,8)
}'

그런 다음 숫자 필드를 정렬하여 두 파일을 병합하고 마지막으로 sed를 통해 숫자를 제거합니다.

sort -m -n -k1,1 log1.new log2.new |
sed 's/^[^ ]* //'

답변2

그러면 사용자 정의 로그 파일에서 생성된 상대 번호가 원래 베이스에 추가되고 모든 행이 업데이트됩니다.

#!/usr/bin/env bash

f=$(head -n 1 custom_log_format.log)
base=$(sed 's/.*H:M:S \(.*\) D:M:Y.*/\1/' <<<$f)

OLDIFS=$IFS
IFS=$'n' 
readarray lines < custom_log_format.log
IFS=$OLDIFS
for i in ${!lines[@]}
do
    b="${lines[$i]}"
    if [[ $b == "["* ]]
    then
        rel_time=$(sed 's/^\[\(.*[^ ]\)\].*/\1/' <<<$b)
        time=$(echo $rel_time | awk -F: '{ print ($1 * 60) + $2 * 60 }')
        # convert base to seconds
        base_seconds=$(date -d"$base" +"%s")
        new_time_seconds=$(( base_seconds + time ))

        new_time=$(date -d"@$new_time_seconds" +"%H:%M:%S")
    fi
    echo ${b/$rel_time/$new_time}
done

산출

Timestamp H:M:S 15:4:1 D:M:Y 16:1:2015
Firmware Version: 121020150140
[15:09:01]------------[ Logs ]------------
[15:11:01]Device Data: -> Supported Attributes -> 0x8033B
[15:09:01]Device Cleanup

[15:27:01]SendClearMsg ...
[15:31:01]Param:GetData failed
[15:59:01]Current Update Count:7
[15:10:01]MODECHK:Normal mode

답변3

Rust 기반 도구를 사용해 보세요초고속 시스템 로그 검색기

(당신이 가지고 있다고 가정러스트 설치됨)

cargo install super_speedy_syslog_searcher

그 다음에

s4 log1 log2

초고속 시스템 로그 검색기다양한 로그 메시지 날짜/시간 형식은 해석된 날짜/시간을 기준으로 정렬됩니다.

관련 정보