- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: awk, sort, uniq
키워드: 접속 로그, 로그 분석, 페이지 뷰
사용처: 아파치 접속 로그에서 페이지 뷰를 집계하고 싶을 때
실행예제
$ cat access.log
xx.xx.xx.xx - - [06/Jan/2014:05:58:35 +0900] "GET / HTTP/1.1" 200 83 "-" "-"
yy.yy.yy.yy - - [06/Jan/2014:06:01:43 +0900] "GET /index.html HTTP/1.1" 200 304
yy.yy.yy.yy - - [06/Jan/2014:06:01:44 +0900] "GET /title.gif HTTP/1.1" 200 763
(생략)
$ ./log-accessfile.sh
29 /news.html
22 /
18 /favicon.ico
8 /menu
8 /title.gif
(생략)
스크립트
#!/bin/sh
logfile="access_log"
# 로그 파일이 존재하지 않으면 종료
if [ ! -f "$logifle" ]; then #----------------------------------------- 1(if문)
echo "대상 로그 파일이 존재하지 않습니다 : $logfile" >&2
exit 1
fi
# 로그 파일에서 GET 메소드로 취득한 파일 접속 횟수 집계
# awk 명령어로 파일을 추출해서 sort+uniq으로 카운트해서 역순 정렬
awk '$6=="\"GET" {print $7}' "$logfile" | sort | uniq -c | sort -nr #-- 2
해설
이 스크립트는 아파치 접속 로그에서 파일별 접속 수를 집계합니다. 웹 페이지를 운영할 때 페이지 뷰(PV)를 조사하는 것은 무척 중요한 업무입니다. 우선 이런 간단한 스크립트로 집계 리포트를 정기적으로 취득해두면 많은 정보를 얻을 수 있을 겁니다.
이 예제에서는 아파치 아파치 접속 로그가 아래와 같다고 가정합니다.
파일1
아파치 common 형식 로그 예192.168.1.1 - - [06/Jan/2014:05:58:35 +0900] "GET /index.html HTTP/1.1" 200 83
스크립트에서는 “ “로 둘러싼 HTTP 리퀘스트에서 파일명을 취득합니다. HTTP 리퀘스트에는 다양한 메소드가 있지만 여기에서는 GET 메소드로 취득한 접속만 집계합니다. 자주 보는 HTTP 메소드는 아래와 같습니다. 이것은 RFC 2616에 정의되어 있습니다.
-
흔히 볼 수 있는 HTTP 메소드
메소드명 이용 장면 GET URI로 지정한 파일 취득 HEAD HTTP 헤더만 취득하고 메시지 보디는 취득하지 않음 POST 메시지 투고 등을 함 PUT 파일 송신 CONNECT SSL 통신을 하는 등 프록시에 터널을 요구함
1
에서 대상 로그 파일 존재를 확인합니다. -f는 대상이 일반 파일인지 확인하는 연산자입니다. 거기에 부정 연산자 !와 함께 써서 대상이 디렉터리이거나 파일이 존재하지 않으면 에러를 표시하고 종료합니다.
2
에서 파일마다 접속 수를 카운트합니다. 여기서 GET 메소드로 취득한 리퀘스트만이 대상이므로 awk 명령어 필터로 HTTP 메소드가 들어 있는 여섯 번째 컬럼에 대해 “GET” 으로 필터를 지정합니다. 그리고 2
에서는 따옴표를 이스케이프하므로 실제로는 $6==”"GET”이 됩니다. 정상적으로 메소드가 지정되면 접속 로그에서 7번째 컬럼이 파일명이므로 awk 명령어를 실행하면 {print $7}로 출력합니다.
그리고 2
에서는 awk 명령어 출력을 일단 sort 명령어로 정렬해서 파이프 마지막에 한번 더 sort 명령어 -n 옵션(숫자 정렬)과 -r 옵션(역순 정렬)으로 실행해서 접속이 많은 순서대로 표시합니다. 이 sort 명령어와 uniq 명령어 조합을 사용해서 파일별 접속 로그 줄 수 즉, 파일별 페이지 뷰가 많은 순서대로 파일명을 표시할 수 있습니다.
그리고 여기에서는 “GET”이라는 필터를 걸어서 조금 이상한 접속 로그를 제거하려고 합니다. 실제로 웹 서버를 운용하다 보면 다음과 같은 이상한 접속을 볼 수 있습니다.
xx.xx.xx.xx - - [12/Apr/2021:18:34:56 +0900] "\x80w\x10\x03\x01" 501 294
원래라면 HTTP 사양에 따라 리퀘스트는 GET이나 POST 같은 메소드명으로 시작해야 하지만 이 로그는 갑자기 이상한 문자열로 접속하고 있습니다.
이것은 http 포트에 https 접속을 하려고 하는 SSL 통신을 그대로 http에 보냈을 때 나타나는 접속 로그입니다. 단순히 클라이언트가 잘못했거나 또는 공격자가 의도적으로 스캔했을 수도 있습니다. 그 외에도 공격을 위해 HTTP 사양을 위반해서 에러가 발생해야 할 리퀘스트를 보내는 접속 로그가 있을 수도 있습니다. 따라서 이 예제에는 필터로 이런 로그를 제거했습니다.
공개된 웹 서버에는 다양한 접속이 발생하므로 집계할 때 어느 정도 잘못된 정보가 들어갈 수도 있다는걸 감수해야 합니다.
주의사항
- 웹 서버 아파치는 널리 사용되는 소프트웨어로 로그 분석툴도 많습니다. 자주 사용하는 유명한 툴로 AWStats가 있습니다. 로그를 그래프화하거나 시각적으로 알기 쉽게 만들어주므로 이용해보기 바랍니다.