우분투 실전 명령어 | grep+awk로 Nginx 에러 빈도 빠르게 집계

언제 쓰는가
운영 중인 서버에서 장애 징후를 빠르게 잡아야 할 때, 전체 로그를 눈으로 읽는 건 너무 느립니다.
이럴 때 grepawk를 조합하면 "최근 1시간 에러 몇 건", "어떤 에러 코드가 많은지"를 바로 확인할 수 있습니다.
Nginx, 애플리케이션 로그처럼 줄 단위 텍스트 로그를 다룰 때 특히 유용합니다.

바로 쓰는 명령어

# 1) 최근 2000줄에서 error 키워드 개수
sudo tail -n 2000 /var/log/nginx/error.log | grep -i "error" | wc -l

# 2) 오늘 로그만 뽑아 에러 레벨별 집계
# 
sudo grep "$(date '+%Y/%m/%d')" /var/log/nginx/error.log \
| awk -F'[][]' '/\[(error|warn|crit)\]/{cnt[$4]++} END{for (k in cnt) printf "%s %d\n", k, cnt[k]}' \
| sort

# 3) 자주 나오는 에러 메시지 TOP 10
sudo tail -n 5000 /var/log/nginx/error.log \
| grep -i "error" \
| sed -E 's/^[^:]+: \*?[0-9]+ //g' \
| sort | uniq -c | sort -nr | head -10

핵심 옵션/패턴

  • tail -n 2000: 파일 전체를 읽지 않고 최근 구간만 빠르게 확인합니다.
  • grep -i: 대소문자 섞인 패턴도 한 번에 잡습니다.
  • awk -F'[][]': 대괄호 기준으로 필드를 나눠 [error] 같은 레벨을 안정적으로 추출합니다.
  • sort | uniq -c | sort -nr: 빈도 집계의 기본 패턴입니다.

자주 하는 실수

  • sudo 없이 시스템 로그를 읽으려다 권한 오류가 납니다.
  • cat 전체로그 | grep ...처럼 큰 파일을 전부 읽어 서버에 불필요한 부하를 줍니다.
  • 날짜 포맷이 로그 포맷과 다르면(예: 2026/02/18 vs 18/Feb/2026) 필터가 0건으로 나옵니다.
  • awk 필드 번호를 로그 포맷 확인 없이 고정해 잘못된 집계를 만듭니다.

검증 방법

# 실제 에러 샘플 5줄 직접 확인
sudo tail -n 200 /var/log/nginx/error.log | grep -i "error" | head -5

# 집계 결과와 원본 라인 수 비교
raw_count=$(sudo tail -n 2000 /var/log/nginx/error.log | grep -i "error" | wc -l)
echo "raw error count: $raw_count"

# 로그 파일 갱신 상태 확인
sudo ls -lh /var/log/nginx/error.log
sudo stat /var/log/nginx/error.log | grep -E "Modify|Size"

실행 결과 예시

$ sudo tail -n 2000 /var/log/nginx/error.log | grep -i "error" | wc -l
37

$ sudo grep "2026/02/18" /var/log/nginx/error.log | awk -F'[][]' '/\[(error|warn|crit)\]/{cnt[$4]++} END{for (k in cnt) printf "%s %d\n", k, cnt[k]}' | sort
crit 2
error 29
warn 11

$ sudo tail -n 5000 /var/log/nginx/error.log | grep -i "error" | sed -E 's/^[^:]+: \*?[0-9]+ //g' | sort | uniq -c | sort -nr | head -5
  12 connect() failed (111: Connection refused) while connecting to upstream
   8 upstream timed out (110: Connection timed out) while reading response header
   5 no live upstreams while connecting to upstream
   4 open() "/var/www/html/favicon.ico" failed (2: No such file or directory)
   3 client intended to send too large body

운영 팁

  • 장애 대응 중에는 watch -n 5 '...집계명령...'로 변화량을 보면 훨씬 빠르게 판단할 수 있습니다.
  • 로그 로테이션 직후에는 파일 경로가 바뀔 수 있으니 /var/log/nginx/error.log.1도 같이 확인하세요.

출처

  • Nginx Documentation
  • GNU Coreutils Manual
  • GNU Awk User's Guide
  • grep Manual