비활성화된 줄을 포함하지 않는 로그 파일에서 쿼리 추출

비활성화된 줄을 포함하지 않는 로그 파일에서 쿼리 추출

다음과 유사한 로그 파일이 있습니다.

query1 startQuery
query1 do something
query1 do something else
query2 startQuery
query1 do something banned
query2 do something
query3 startQuery
query2 endQuery 1000
query3 something else to do
query1 endQuery 2003
query3 do something
query4 startQuery
query4 endQuery 100
query3 endQuery 1434

내가 찾은 가장 오래 실행되는 쿼리는 다음과 같습니다.

> grep "endQuery" logfile | awk '{print $3 " " $1}' | sort -nr | head -n 3
2003 query1
1434 query3
1000 query2

하지만 일부 작업은 시간이 오래 걸리는 것으로 알려져 있어 가장 오래 실행되는 쿼리를 찾고 싶습니다.원하지 않는다다음 작업을 포함합니다. 예를 들어, 로그 줄에 "banned"라는 단어가 포함되지 않은 가장 오래 실행되는 쿼리를 찾고 싶습니다.

이 예에서는 다음과 같이 출력됩니다.

1434 query3
1000 query2
100 query4

실제로 이러한 로그 파일은 크기가 크고 많은 수의 쿼리를 포함합니다.

답변1

grep먼저, 호출이 필요하지 않다는 점에 유의하세요. awk호출에 원활하게 통합됩니다.

<logfile awk '/endQuery/ {print $3 " " $1}'

awk 단계에서 금지된 쿼리를 필터링할 수 있습니다. 진행 중인 쿼리를 배열에 저장하고, 금지된 경우 제거하고, 금지되지 않은 쿼리만 인쇄합니다.

<logfile awk '
    $2 == "startQuery" {q[$1]=1}        # store the names of active queries
    q[$1] && /banned/ {delete q[$1]}    # delete banned queries
    $2 == "endQuery" {
        if (q[$1]) print $3, $1;        # only report non-banned queries
        delete q[$1];
    }
' | sort -nr | head -n 3

답변2

나는 다음을 공식화했습니다.

diff <(grep "endQuery" logfile | awk '{print $1}') \
     <(grep "banned"   logfile | awk '{print $1}') | \
  grep "<" | awk '{print $2}' | xargs -I{0} grep "{0} endQuery" logfile | \
    awk '{print $3 " " $1}' | sort -nr | head -n3
1434 query3
1000 query2
100 query4

그러나 로그 파일에 대한 3개의 grep이 필요하므로 대용량 로그 파일의 경우 비용이 많이 들 수 있습니다.

관련 정보