내 Apache 로그 파일에는 other_vhosts_access.log
다음과 같습니다.
www.example.com:80 12.34.56.78 - - [01/Aug/2017:00:42:18 +0200] "GET /page1.html HTTP/1.1" 200 1542 " "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
www.example.com:80 99.99.99.99 - - [02/Aug/2017:06:19:44 +0200] "GET /test.jpg HTTP/1.1" 200 90749 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
www.anotherwebsite.com:80 11.11.11.11 - - [04/Aug/2017:09:39:01 +0200] "GET /test.jpg HTTP/1.1" 200 90749 "" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
...
www.example.com:80 12.34.56.78 - - [23/Aug/2017:01:12:11 +0200] "GET /somethingelse2.html HTTP/1.1" 200 21161 "http://www.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
방문한 방문객을 찾고 싶습니다./page1.html
그리고 /somethingelse2.html
, 이 예에서는 12.34.56.78입니다.
내가 사용하는 경우:
grep page1.html other_vhosts_access.log
나머지 줄에 가 포함되어 있지 않기 때문에 더 이상 출력을 필터링할 수 없습니다 somethingelse2.html
.
특정 페이지 + 다른 페이지를 방문한 방문자를 어떻게 찾을 수 있나요?
답변1
bash
, grep
및 awk
:을 사용하십시오 .
page1.html
파일과 관련된 모든 IP 번호를 얻는 방법은 다음과 같습니다 .
awk '/page1\.html/ { print $2 }' log
예를 들어 데이터가 출력됩니다 12.34.56.78
.
이는 해당 IP 주소가 포함된 모든 로그 항목을 가져오는 데 사용할 수 있습니다.
grep -wF -f <( awk '/page1\.html/ { print $2 }' log ) log
이는 명령의 결과를 awk
패턴으로 사용하고 로그 파일을 다시 스캔하여 해당 IP가 포함된 모든 행을 출력합니다. 그러면 예제의 첫 번째 행과 마지막 행이 반환됩니다.
플래그는 다음과 같이 해석될 패턴(IP 주소)을 -w
알려주는 데 사용됩니다 .-F
grep
grep
고정 문자열( -F
) 이를 포함하는 문자열만 반환합니다.전체 단어( -w
). 이는 12.34.56.789
고정 문자열 패턴이 일치하지 않음 을 의미합니다 12.34.56.78
.
이 결과로부터 우리는제거하다page1.html
라인에 대해
grep -wF -f <( awk '/page1\.html/ { print $2 }' log ) log | grep -vF 'page1.html'
이제 페이지 방문자가 생성한 모든 로그 항목이 있습니다 ( 페이지 자체 page1.html
는 아님 ).page1.html
특정 프로젝트에 대한 항목을 얻으려면특별한다른 페이지를 선택하고 마지막 페이지 grep -vF 'page1.html'
를 grep -F 'otherpage.html'
.
더 강력한 로그 구문 분석 및 분석 도구가 있다고 확신하지만, 있다고 해도 잘 모르겠습니다(저는 로그 구문 분석을 자주 수행하지 않습니다).
답변2
일반적으로 이는 입력에서 본 내용을 기억하기 위해 연관 배열을 사용하여 awk에서 수행됩니다. 기본 awk 공백 필드 구분 기호를 사용하면 필드 2가 IP 주소이고 필드 8이 URL임을 알 수 있습니다. 예를 들어 다음과 같습니다.
awk '$8=="/page1.html" { ipaddr[$2] = 1; next }
$8=="/somethingelse2.html" { if(ipaddr[$2]==1)print $2 }'
이는 url 필드를 비교하고 첫 번째 url과 일치하면 ipaddr
배열의 IP 주소에 대한 항목을 생성하여 값 1을 보유합니다. 두 번째 URL과 일치하면 해당 항목이 동일한 IP 주소로 설정되어 있는지 확인하고 그렇다면 인쇄합니다. 동일한 IP 주소를 다시 인쇄하지 않으려면 이를 다른 배열에 기록할 수 있습니다.
awk '$8=="/page1.html" { ipaddr[$2] = 1; next }
$8=="/somethingelse2.html" { if(ipaddr[$2]==1 && !done[$2]){print $2; done[$2]=1 } }'
URL에 검색어 부분(예 "/page1.html?id=77"
: )이 있는 경우 비교 대신 일치를 사용할 수 있습니다 $8~/^\/page1.html/
.
역순으로 URL에 액세스할 수 있는 경우 비트마스크 값을 사용하여 이미 본 값(예: 페이지1의 경우 1, 다른 항목2의 경우 2)을 기억한 다음 값 3을 얻을 때까지 기다릴 수 있습니다. 비트 마스크는 or
및 같은 기능을 통해서만 awk에서 사용할 수 있습니다 and
. 그래서 우리는
awk '
BEGIN { v["/page1.html"] = 1
v["/somethingelse2.html"] = 2
}
$8=="/page1.html" || $8=="/somethingelse2.html" {
ipaddr[$2] = or(ipaddr[$2], v[$8])
if(ipaddr[$2]==3){ print $2; ipaddr[$2] = 4 }
}'
v
이는 URL을 비트마스크 값(정수)으로 변환하기 위해 처음에 수행된 BEGIN 블록의 연관 배열에 매핑을 설정합니다 . URL이 일치하면 기억된 값은 적절한 비트마스크 값 또는 -ed를 갖습니다. 이제 3이면 해당 주소를 인쇄하고 다시 인쇄하지 않도록 설정합니다.
답변3
이 작업을 수행하는 동안 other_vhosts_access.log의 형식이 생각보다 다양하다는 것을 발견할 수 있습니다. 예를 들어 좋아하는 열 중 일부를 선택한 awk '{print $2, $8}' other_vhosts_access.log > small.log
다음 더 쉽게 관찰할 수 있도록 small.log에서 작업하는 것이 좋습니다.
문제의 설명은https://httpd.apache.org/docs/2.4/logs.html:
...일반적으로 사용되는 형식 문자열을 결합된 로그 형식이라고 합니다. 다음과 같이 사용할 수 있습니다. LogFormat "%h %l %u %t \"%r\" %>s %b \"%{추천인}i\" \"%{사용자 에이전트}i\"" 조합
이것을 사용하고 있는 것 같습니다. (삭제된) 로그에서 이를 참조 example.com
하고 있는데, 이는 example.com과 같은 사이트에 귀하의 사이트를 가리키는 HREF가 있고 브라우저의 GET 요청에 "Referer: www.example.com" 헤더가 포함되어 있음을 나타냅니다.
/page1에는 /page2에 대한 HREF가 있는 것 같습니다. 일부 브라우저는 page2 요청 시 page1 리퍼러 헤더를 보냅니다. 이에 의존하고 "page2.*page1"에 대해 grep을 선택할 수 있습니다. 또는 허용된 답변에 표시된 대로 소스 IP를 사용하도록 선택할 수 있습니다. 이 경우 잘못된 일치를 유발하는 다른 방해가 되는 열을 제거하고 분석을 위해 단순화된 small.log를 사용할 수 있습니다.