가끔 아파치 로그를 이용하여
시분초 단위로 어느정도 처리하는지 숫자를 뽑는 경우가 있는데
그때 사용하는 awk 입니다.
더 이쁘게 만들어 주시면 감사하겠습니다.
#####################################################################
초단위 리퀘스트
awk -F ' ' '{ gsub(/\[/,"");split($4,ret,":");printf ("%s%02d%02d%02d\n",ret[1],ret[2],ret[3],ret[4])}' <access_log file> | uniq -c
분단위 리퀘스트
awk -F ' ' '{ gsub(/\[/,"");split($4,ret,":");printf ("%s%02d%02d\n",ret[1],ret[2],ret[3])}' <access_log file> | uniq -c
시간단위 리퀘스트
awk -F ' ' '{ gsub(/\[/,"");split($4,ret,":");printf ("%s%02d\n",ret[1],ret[2])}' <access_log file> | uniq -c
주의
conf 상 log 포맷이 "%h %l %u %t \"%r\" %>s %b" 이어야 합니다. 아니면 수정해야됨..
(112.156.90.240 - - [26/Jan/2012:15:51:17 +0900] "GET /favorite_api.php?szBjId=hummer9427&szWork=SELECTBOX&szScriptVar=oFavoriteList HTTP/1.1" 200 2119)
예제
awk -F ' ' '{ gsub(/\[/,"");split($4,ret,":");printf ("%s%02d\n",ret[1],ret[2])}' /logs/access_log| uniq -c
결과
476 26/Jan/20121554
455 26/Jan/20121555
456 26/Jan/20121556
461 26/Jan/20121557
452 26/Jan/20121558
451 26/Jan/20121559
437 26/Jan/20121600
445 26/Jan/20121601
425 26/Jan/20121602
423 26/Jan/20121603
440 26/Jan/20121604
432 26/Jan/20121605
456 26/Jan/20121606
528 26/Jan/20121607
492 26/Jan/20121608
551 26/Jan/20121609
654 26/Jan/20121610
491 26/Jan/20121611awk -v q=\' 'BEGIN{print q}'
awk 'BEGIN{print "\x27"}'
awk 'BEGIN{print "\047"}'
Linux 서버를 운영하다 보면, 아파치 또는 톰캣의 Access로그를 이용하여, 접속 통계를 추출하고자 할 때가 있다.
특정 IP가 유난히 많이 유입된다거나, 시간대별로 유입 건수 또는 파라미터 값 별로 유입되는 건 수
HTTP 결과 코드별로 에러가 몇건인지 등을 파악하기 위해서다.
분석을 위해서는 grep명령과 awk명령이 사용된다. 물론, 통계 추출 후 데이터 정렬을 위해 sort명령도 사용된다.
아래와 같은 형식으로 쓰여진 아파치 Access로그 파일 access.log가 있다고 하자.
access.log 파일을 분석하여 통계를 추출해 보자.
221.62.138.27 - - [16/Mar/2017:13:18:22 +0900] "POST /app/service.jsp?COMMAND=12&SVC_TYPE=2&SONG_ID=8045575 HTTP/1.1" 200 601 59213 "-" "-"
1. IP별로 접속 건 수 구하기
cat access.log | awk '{print $1}' | awk '{ arr[$1]+=1} END{ for (i in arr) {print i "\t" ":" arr[i]}}'
위와 같이 명령어를 입력하면, 출력되는 결과는 다음과 같다.
221.62.138.72 : 543
223.35.12.46 : 24
223.64.210.156 : 2341
명령을 분석하자면,
cat으로 access.log 파일을 열고, awk로 IP데이터인 첫번째 필드를 추출한 뒤,
첫번째 필드가 같은 데이터면 +1 하여 count하고 그 결과를 for loop 돌면서
"필드값 [탭] : count된 값" 형태로 출력하는 명령이다.
2. 시간대별 접속 건 수 구하기
cat access.log | awk '{print $4}' | awk -F":" '{ arr[$2]+=1} END{ for (i in arr) {print i "\t" ":" arr[i]}}' | sort
위와 같이 명령어를 입력하면, 출력되는 결과는 다음과 같다.
01 : 8431
01 : 3921
02 : 2314
03 : 1341
...
22 : 71932
23 : 24932
명령을 분석하자면, 위와 같은 방식으로
cat으로 access.log 파일을 열고, awk로 시간 데이터인 4번째 필드를 추출하 뒤, 추출한 필드에서 다시 ":"를 구분자로 2번째 필드(시간)를 추출하여 해당 필드가 같은 데이터면 +1 하여 count하고 그 결과를 for loop 돌면서 "필드값 [탭] : count된 값" 형태로 출력하고 이를 첫번째 필드 기준으로 정렬하는 명령이다.
3. HTTP 결과 코드별 접속 건 수 구하기
cat access.log | awk '{print $9}' | awk '{ arr[$1]+=1} END{ for (i in arr) {print i "\t" ":" arr[i]}}' | sort
위와 같이 명령어를 입력하면, 출력되는 결과는 다음과 같다.
200 : 2434314
401 : 921
404 : 8314
500 : 15
명령을 분석하자면, 같은 방식으로
cat으로 access.log 파일을 열고, awk로 HTTP 결과 코드인 9번째 필드를 추출하여 해당 필드가 같은 데이터면 +1 하여 count하고 그 결과를 for loop 돌면서 "필드값 [탭] : count된 값" 형태로 출력하고 이를 첫번째 필드 기준으로 정렬하는 명령이다.
여기에서, 여러 파일의 파일 예를 들어, 2월 한달간의 access.log 파일들 등에서 통계를 구하고자 한다던가 특정 값이 포함된 접속 이력만을 대상으로 하고자 할 경우에는
grep명령으로 대상이 되는 라인만을 추출한 뒤, 파이프 라인으로 위의 명령어를 응용하여 구성하면 된다.
이상 끝.