데이터 엔지니어링

Linux awk로 로그 파일 분석하기

들어가며

복잡한 데이터 엔지니어링 환경에서 로그 분석은 단순한 디버깅 도구를 넘어 시스템의 건강 상태를 모니터링하고 성능을 최적화하는 데 필수적인 요소가 되었습니다. 데이터 파이프라인, ETL 프로세스, 실시간 데이터 스트리밍 등 다양한 데이터 처리 작업에서 발생하는 로그는 시스템의 동작을 이해하고 문제를 신속하게 해결하는 데 중요한 정보를 제공합니다. 데이터 엔지니어는 이러한 다양한 형태의 로그 파일을 효과적으로 분석하고 관리할 수 있어야 합니다.

로그 파일은 그 크기가 방대하고 구조가 복잡할 수 있어, 구조를 명확히 정하고 효율적으로 분석하는 것이 중요합니다. 이러한 맥락에서 Linux의 awk 명령어가 유연한 로그 분석에 사용될 수 있습니다. awk는 텍스트 처리에 특화된 프로그래밍 언어로, 복잡한 로그 파일에서 필요한 정보를 추출하고, 데이터를 재구성하며, 간단한 통계를 생성하는 데 탁월한 성능을 보여줍니다. 특히 대규모 로그 파일을 빠르게 처리할 수 있어 실시간 모니터링과 문제 해결에 큰 도움이 됩니다.

본 글에서는 실제 데이터 처리 파이프라인의 로그 분석 사례를 중심으로, awk를 활용한 효율적인 로그 분석 및 관리 방법을 소개하고자 합니다. 프로세스 실행 시간 분석, 에러 패턴 식별, 리소스 사용량 추적 등 시스템 성능 최적화와 문제 해결에 직접적으로 기여할 수 있는 로그 분석 기법에 대해 알아보겠습니다.

데이터 엔지니어링 관점에서 awk를 활용한 로그 분석은 단순한 텍스트 처리 작업이 아닌, 시스템의 안정성과 효율성을 보장하는 핵심 프로세스입니다. 대규모 데이터 처리 작업에서 발생할 수 있는 병목 현상을 식별하고, 에러의 근본 원인을 신속하게 파악하며, 궁극적으로는 데이터 파이프라인의 전반적인 성능을 향상시키는 것이 우리의 목표입니다. 데이터 엔지니어가 어떻게 awk를 활용하여 더 효율적이고 안정적인 데이터 처리 환경을 구축할 수 있는지 함께 살펴보겠습니다.

 

awk에 대하여

awk는 Unix 계열 운영 체제에서 사용되는 텍스트 처리 도구입니다. 다른 명령어들과 다르게 awk의 이름은 개발자들의 이름 첫 글자를 따서 지어졌습니다: Alfred Aho, Peter Weinberger, Brian Kernighan. 그래서 명령어 이름만으로 기능을 추론하기 어렵다는 특징이 있습니다. 1977년에 처음 개발된 이후, awk는 데이터 추출과 보고서 생성을 위한 표준 도구로 자리잡았습니다.

awk의 주요 특징

1. 패턴 매칭: awk는 텍스트에서 특정 패턴을 찾아 처리할 수 있습니다.

2. 필드 처리: 텍스트를 필드(열)로 나누어 각 필드를 개별적으로 처리할 수 있습니다.

3. 프로그래밍 기능: 변수, 함수, 조건문 등을 사용할 수 있어 복잡한 처리도 가능합니다.

4. 내장 함수: 문자열 조작, 수학 연산 등을 위한 다양한 내장 함수를 제공합니다.

awk의 기본 구조

awk 명령어의 기본 구조는 다음과 같습니다:

awk 'pattern { action }' filename
  • pattern: 처리할 라인을 선택하는 조건입니다.
  • action: 선택된 라인에 대해 수행할 동작입니다.
  • filename: 처리할 파일의 이름입니다.

awk pattern

pattern은 awk가 처리할 입력 라인을 선택하는 조건입니다. pattern이 참(true)으로 평가되는 라인에 대해서만 action이 수행됩니다.

주요 pattern 유형:

  • /정규표현식/: 정규표현식과 일치하는 라인 선택
  • 관계표현식: 예를 들어, $1 > 100은 첫 번째 필드 값이 100보다 큰 라인 선택
  • BEGIN: 입력 처리 전에 실행될 action 지정
  • END: 모든 입력 처리 후 실행될 action 지정

pattern 예시:

awk '/error/' file.log   # 'error'를 포함한 라인 선택 
awk '$5 == 404' access.log   # HTTP 상태 코드가 404인 라인 선택 
awk 'BEGIN { print "Start of report" }'   # 처리 시작 전 메시지 출력

awk action

Action은 선택된 라인에 대해 수행할 작업을 정의합니다. 중괄호 {} 안에 하나 이상의 명령문으로 구성됩니다.

주요 action 요소:

  • print, printf: 결과 출력
  • 변수 할당: 데이터 저장 및 조작
  • 조건문 (if, else): 조건에 따른 처리
  • 반복문 (for, while): 반복 작업 수행
  • 내장 함수 사용: 문자열 처리, 수학 연산 등

Action 예시:

awk '{ print $1, $3 }' file.txt   # 첫 번째와 세 번째 필드 출력

awk '{ sum += $1 } END { print sum }' data.txt   # 첫 번째 필드의 합계 계산 

awk '{ if($3 > 1000) print $0 }' sales.txt   # 세 번째 필드가 1000 초과인 라인 전체 출력

pattern과 action을 조합하면 복잡한 데이터 처리 작업을 간결하게 표현할 수 있습니다. 예를 들어:

awk '$4 ~ /^4[0-9]{2}/ { errors++ } END { print "Total HTTP 4xx errors:", errors }' access.log

이 명령은 HTTP 4xx 에러의 총 개수를 계산합니다. 네 번째 필드($4)가 4로 시작하는 3자리 숫자와 일치하는 경우 errors 변수를 증가시키고, 처리가 끝난 후 총 에러 수를 출력합니다. pattern과 action의 다양한 조합을 통해 awk는 복잡한 로그 분석 작업을 효율적으로 수행할 수 있습니다.

여러 awk 관련 옵션은 이곳에서 확인할 수 있습니다.

awk의 활용

awk는 다음과 같은 상황에서 특히 유용합니다:

  • 로그 파일 분석
  • 데이터 추출 및 보고서 생성
  • 간단한 데이터베이스 작업
  • 시스템 관리 작업

데이터 엔지니어링 분야에서 awk는 대량의 텍스트 데이터를 빠르게 처리하고 분석하는 데 사용됩니다. 특히 로그 파일 분석, 데이터 정제, 간단한 통계 작업 등에 널리 활용됩니다. 다음 섹션에서는 실제 로그 파일 분석에 awk를 어떻게 적용할 수 있는지 구체적인 예제를 통해 살펴보겠습니다.

 

awk로 로그 파일 분석하기

데이터 처리 프로세스에서 주기적인 로그 분석은 모니터링과 성능 최적화에 필수적입니다. 여기서는 linux 환경에서 awk를 사용하여 매시간 로그를 분석하는 스크립트를 소개하겠습니다.

핵심 로직

analyze_logs() {
    local current_time=$(date -u +"%Y-%m-%dT%H:%M:%S")
    local one_hour_ago=$(date -u -d '1 hour ago' + "%Y-%m-%dT%H:%M:%S")
    local log_file=$(ls -t "$LOG_DIR"/result_*.txt | head -n1)

    echo "Analyzing log file: $log_file for the last hour"

    awk -v start_time="$one_hour_ago" '
    function time_diff(t1, t2) {
        gsub(/[-T:]/, " ", t1)
        gsub(/[-T:]/, " ", t2)
        return mktime(t1) - mktime(t2)
    }
    BEGIN {
        FS = "\""
        print "Analysis Time: " strftime("%Y-%m-%dT%H:%M:%S", systime())
        print "Analysis from: " start_time
        print "Keyword Statistics:"
    }
    /timestamp/ {
        timestamp = $4
        gsub(/Z$/, "", timestamp)
        if (time_diff(timestamp, start_time) >= 0) {
            keyword = $16
            status = $12
            total[keyword]++
            if (status == "Success") success[keyword]++
            else if (status == "Failed") failed[keyword]++
        }
    }
    END {
        for (kw in total) {
            print " " kw ":"
            print " Total:", total[kw]
            print " Success:", success[kw] ? success[kw] : 0
            print " Failed:", failed[kw] ? failed[kw] : 0
        }
        print "------------------------"
    }
    ' <(tac "$log_file") >> "$result_file"

    echo "Analysis completed at $current_time"
    echo "Result:"
    cat "$RESULT_FILE"
}

  • 프로세스 결과가 저장되는 디렉토링에서 최신 텍스트 파일을 선택합니다.
  • awk 를 이용하여 키워드 별 실행 횟수, 성공 횟수, 실패 횟수를 집계합니다.
  • tac 을 이용하여 로그 파일을 역순으로 읽습니다.
  • 매 시간 집계 결과를 텍스트 파일로 저장하고, rotation을 사용합니다.
  • awk는 자체적으로 입력 파일의 각 줄을 처리하는 기능을 가지고 있어, 반복문을 실행하지 않아도 됩니다.

awk 필드 구분자 커스터마이징

awk의 기본 설정은 공백(space, tab)과 줄바꿈을 필드 구분자로 사용합니다. 하지만, 로그의 형식은 사용자가 직접 지정하는 경우가 많습니다. 저희의 로그 파일은 아래와 같이 JSON 구조를 가지고 있어 필드 구분자를 수정해야 했습니다.

{"timestamp": "2024-09-11T07:56:11.998645Z", "KST": "2024-09-11T16:56:11.998645", "status": "Success", "keyword": "example", "url": "https://example.com"}

저희의 로그 파일에서 각 필드는 따옴표(")로 둘러싸여 있습니다. 이를 효과적으로 처리하기 위해 다음과 같이 필드 구분자를 설정했습니다:

BEGIN {
    FS = "\""
}

커스텀 필드 구분자를 설정한 후, 다음과 같이 필요한 정보를 간단하게 추출할 수 있습니다.

{ 
    timestamp = $4 
    status = $12 
    keyword = $16
}

로그 분석 결과는 아래와 같이 저장됩니다.

awk 로그 분석 결과

awk 사용의 이점

  1. 효율성: awk는 한 번의 파일 읽기로 모든 처리를 수행합니다. 이는 여러 번 파일을 읽는 방식보다 훨씬 효율적입니다.
  2. 시간 계산의 정확성: awkmktime 함수를 사용하여 정확한 시간 차이를 계산합니다. 이는 문자열 비교보다 더 신뢰할 수 있습니다.
  3. 코드 간결성: 복잡한 bash 로직이 awk의 간결한 코드로 대체되어 가독성이 향상되고 유지보수가 쉬워집니다.
  4. 유연성: awk 스크립트는 쉽게 수정할 수 있어, 로그 형식이 변경되거나 추가 분석이 필요한 경우 빠르게 대응할 수 있습니다.
  5. 내장 함수 활용: awk의 내장 함수(예: strftime, mktime)를 사용하여 시간 처리를 쉽게 할 수 있습니다.

이러한 awk의 특성은 데이터 엔지니어가 복잡한 로그 분석 작업을 효율적으로 수행하는 데 큰 도움이 됩니다.

service를 이용한 스케줄링

이 쉘 스크립트를 service로 등록하여 지속적으로 실행되도록 설정했습니다. service 파일은 아래와 같이 작성할 수 있습니다.

[Unit] 
Description=Log Analysis Service 
After=network.target 

[Service] 
ExecStart=/home/dev/example/result_analysis.sh 
Restart=always 
User=dev 
Group=dev 
Environment=PATH=/usr/bin:/usr/local/bin 
WorkingDirectory=/home/dev/example 

[Install] 
WantedBy=multi-user.target

이를 통해 로그 분석 스크립트가 지속적으로 실행되면서 매시간 로그를 분석하게 됩니다.

결론

awk를 활용한 로그 분석은 데이터 엔지니어링 분야에서 효율적이고 강력한 도구입니다. 대량의 로그 데이터를 빠르게 처리하고, 필요한 정보를 정확하게 추출할 수 있어 시스템 모니터링과 성능 최적화에 큰 도움이 됩니다. 특히 커스텀 필드 구분자 설정과 내장 함수를 활용하면, 다양한 형식의 로그에 유연하게 대응할 수 있습니다.

데이터 엔지니어링 프로세스에서 awk를 효과적으로 활용하면 로그 분석 작업의 효율성을 크게 높일 수 있습니다. 이는 결과적으로 시스템 성능 향상과 문제 해결 시간 단축으로 이어져, 전반적인 데이터 처리 환경을 개선하는 데 기여할 수 있습니다.

Share this post

About the author

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다