Perl을 사용하여 로그 구문 분석

Perl을 사용하여 로그 구문 분석

로그를 구문 분석하기 위해 설계한 Perl 명령을 사용하고 싶습니다. 지금까지 내가 달성하려고 하는 것은 특정 타임스탬프 형식을 추출하고 호스트를 검색하는 것입니다. 로그는 다음과 같습니다

2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"

내 명령은 원하는 날짜 형식을 구문 분석할 수 있지만 출력에 호스트를 추가하는 방법을 알 수 없는 것 같습니다. 어떤 제안이라도 좋을 것입니다!

cat test.log  |
perl -lne 'print $1 if  /^([0-9]+[-]+[0-9]+[0-9]+[-]+[0-9]+[0-9]+[T]+[0-9]+[0-9]+[:]+[0-9]+[0-9]+[:]+[0-9]+[0-9])/'

답변1

이 시도:

perl -nle'($time, $host) = /^(\S+)\s(?:\S+\s+){8}\S+="(\S+?)"/; print "$time $host"'

산출:

2016-05-07T09:07:04.933343+00:00 jamaican.com
  • \S비공간을 나타냄
  • \s공간이다
  • (?:)잡히지 않은 논리적 그룹화입니다.
  • {8}건너뛴 "단어"입니다.
  • \S+="(\S+?)"=의미: 두 따옴표 사이에 있는 내용 까지 건너뛰고 캡처합니다."
  • ($time, $host) = /.../캡처된 두 그룹을 $time$host

답변2

호스트 이름을 캡처하려면 두 번째 캡처 그룹을 사용해야 합니다.

예를 들어 예제 입력을 사용하면 다음과 같습니다.

$ cat test.log 
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"

이 perl one-liner는 타임스탬프와 호스트 이름 필드를 추출합니다. 또한 \d각 숫자에 일치 횟수가 있는 숫자 에 대한 정규식을 일부 개선했습니다 .

$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^ ]+) /)' test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]:

또 다른 옵션:

$ perl -lne 'print "$1 $2 $3" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^[]+)\[([^]]+)\]/)' test.log
2016-05-07T09:07:04.933343+00:00 heroku router

host="jamaican.com"나는 당신이 당신의 로컬 컴퓨터의 호스트 이름을 원한다고 가정합니다. (저는 로그 항목 부분 도 눈치 채지 못했습니다 ). 이는 원하는 것이 아닐 수 있으므로 호스트 이름 뒤에 큰따옴표를 사용하려면 host=다음을 수행하세요.

$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com 

또는 (더 쉽게):

$ perl -lne 'print "$1 $2" if (m/(^\S+).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com

또는 타임스탬프를 추출하고 .를 Date::Parse사용하여 구문 분석한 다음 Date::Format.

$ perl -MDate::Parse -MDate::Format -lne \
  'if (m/(^\S+).*host="([^"]+)"/) {
     print join(" ", time2str("%Y-%m-%d %R %z",str2time($1)), $2)
   }' test.log
2016-05-07 19:07 +1000 jamaican.com

참고: 타임스탬프는 현지 시간대로 변환됩니다(나의 경우 +1000 또는 호주 동부 표준시). time2str()기본적으로 현지 시간대가 사용되지만 세 번째 인수( time2str(TEMPLATE, TIME [, ZONE]))를 지정하여 다른 시간대의 시간을 출력하도록 할 수 있습니다.

$ perl -MDate::Parse -MDate::Format -lne   'if (m/(^\S+).*host="([^"]+)"/) {
     print join(" ", time2str("%Y-%m-%d %R %z",str2time($1),"+0"), $2)
   }' test.log
2016-05-07 09:07 +0000 jamaican.com

관련 정보