이미지 로딩 중...

로그 필터링 및 카운팅 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 18. · 4 Views

로그 필터링 및 카운팅 완벽 가이드

실무에서 매일 쌓이는 수많은 로그 파일을 효과적으로 분석하는 방법을 배워봅니다. Bash 명령어를 활용하여 에러 로그 추출, 레벨별 분류, 통계 수집까지 한 번에 정복할 수 있습니다.


목차

  1. 에러 로그만 추출하기
  2. 로그 레벨별 분류
  3. wc로 로그 개수 세기
  4. uniq로 중복 제거
  5. sort로 정렬하기
  6. 기본 통계 스크립트 작성

1. 에러 로그만 추출하기

시작하며

여러분이 서버를 운영하다가 갑자기 사용자들로부터 "페이지가 안 열려요!"라는 문의를 받은 상황을 상상해보세요. 로그 파일을 열어보니 수만 줄의 로그가 쏟아져 나오고, 정작 어디서 문제가 생겼는지 찾기가 너무 어렵습니다.

이런 문제는 실제로 개발자들이 가장 자주 겪는 상황입니다. 로그 파일에는 정상 작동 기록(INFO), 경고(WARN), 에러(ERROR) 등이 모두 섞여 있어서 정작 중요한 에러 정보를 찾기가 쉽지 않습니다.

수천, 수만 줄을 일일이 눈으로 확인하는 것은 시간 낭비이자 실수를 유발할 수 있습니다. 바로 이럴 때 필요한 것이 grep 명령어를 이용한 로그 필터링입니다.

마치 거대한 책에서 특정 단어만 하이라이트해서 보는 것처럼, 수많은 로그 중에서 ERROR만 골라내어 빠르게 문제를 찾을 수 있습니다.

개요

간단히 말해서, 이 기술은 로그 파일에서 필요한 정보만 골라내는 필터링 작업입니다. 마치 커피를 내릴 때 필터를 사용하는 것처럼, 불필요한 정보는 걸러내고 핵심만 남기는 것이죠.

실무에서는 하루에도 수십 기가바이트의 로그가 생성됩니다. 이 모든 로그를 다 읽는 것은 불가능합니다.

예를 들어, 전자상거래 사이트에서 결제 실패가 발생했을 때, ERROR 로그만 추출하면 몇 초 만에 원인을 파악할 수 있습니다. 기존에는 텍스트 에디터로 파일을 열어 Ctrl+F로 찾았다면, 이제는 명령어 한 줄로 원하는 로그만 즉시 추출할 수 있습니다.

특히 파일이 너무 커서 에디터로 열 수 없는 경우에도 문제없이 작동합니다. grep 명령어의 핵심 특징은 첫째, 패턴 매칭을 통한 정확한 검색, 둘째, 대용량 파일도 빠르게 처리, 셋째, 다양한 옵션으로 세밀한 제어가 가능하다는 점입니다.

이러한 특징들이 로그 분석 작업의 효율성을 수십 배 높여줍니다.

코드 예제

# 기본적인 에러 로그 추출
grep "ERROR" application.log

# 대소문자 구분 없이 에러 찾기
grep -i "error" application.log

# 에러가 포함된 줄의 앞뒤 3줄도 함께 보기 (컨텍스트 파악)
grep -C 3 "ERROR" application.log

# 에러 로그를 새 파일로 저장
grep "ERROR" application.log > errors.log

# 여러 패턴 동시 검색 (ERROR 또는 FATAL)
grep -E "ERROR|FATAL" application.log

# 줄 번호와 함께 출력하여 원본 위치 확인
grep -n "ERROR" application.log

설명

이것이 하는 일: grep 명령어는 파일 내용을 한 줄씩 읽으면서 지정한 패턴(문자열)이 포함된 줄만 골라내어 화면에 출력합니다. 마치 도서관에서 특정 키워드가 들어간 책만 찾아내는 사서처럼 동작합니다.

첫 번째로, 가장 기본적인 grep "ERROR" application.log는 application.log 파일을 열어서 "ERROR"라는 문자열이 포함된 모든 줄을 찾아냅니다. 이때 대소문자를 정확히 구분하므로 "error"나 "Error"는 찾지 못합니다.

만약 대소문자 구분 없이 찾고 싶다면 -i 옵션을 추가하면 됩니다. 그 다음으로, -C 3 옵션을 사용하면 에러가 발생한 줄뿐만 아니라 그 앞 3줄과 뒤 3줄도 함께 보여줍니다.

이것이 중요한 이유는 에러만 보면 원인을 알기 어려운 경우가 많기 때문입니다. 예를 들어 "NullPointerException" 에러가 있다면, 그 앞 줄에서 어떤 변수가 null인지 확인할 수 있습니다.

마지막으로, > errors.log를 사용하면 화면에 출력하는 대신 결과를 파일로 저장합니다. 이렇게 하면 추출한 에러 로그를 동료에게 공유하거나, 나중에 다시 분석할 수 있습니다.

-E 옵션과 파이프(|)를 사용하면 여러 패턴을 동시에 검색할 수 있어서, ERROR와 FATAL을 한 번에 찾을 수 있습니다. 여러분이 이 코드를 사용하면 몇 기가바이트짜리 로그 파일에서도 몇 초 만에 원하는 에러를 찾아낼 수 있습니다.

파일을 직접 열 필요도 없고, 메모리 부족 걱정도 없으며, 검색 속도도 매우 빠릅니다.

실전 팁

💡 -i 옵션은 대소문자를 구분하지 않으므로, ERROR, Error, error 모두 찾습니다. 로그 형식이 통일되지 않은 경우 반드시 사용하세요.

💡 -v 옵션을 사용하면 반대로 특정 패턴이 없는 줄만 출력합니다. 예: grep -v "DEBUG" app.log로 디버그 로그를 제외한 모든 로그를 볼 수 있습니다.

💡 여러 파일을 한 번에 검색하려면 grep "ERROR" *.log처럼 와일드카드를 사용하세요. 모든 .log 파일에서 에러를 찾아줍니다.

💡 --color=auto 옵션을 추가하면 검색된 단어가 색깔로 강조되어 눈에 훨씬 잘 띕니다.

💡 로그가 실시간으로 생성되는 경우 tail -f application.log | grep "ERROR" 형태로 사용하면 새로운 에러가 발생할 때마다 즉시 확인할 수 있습니다.


2. 로그 레벨별 분류

시작하며

여러분이 운영하는 웹 서비스에서 성능이 느려진다는 보고를 받았습니다. 로그를 확인해보니 INFO, WARN, ERROR가 뒤섞여 있어서 어떤 문제가 가장 심각한지, 얼마나 자주 발생하는지 파악하기 어렵습니다.

이런 상황은 로그를 단순히 보는 것만으로는 해결할 수 없습니다. 로그 레벨(심각도)별로 분류해서 봐야 전체적인 시스템 상태를 파악할 수 있습니다.

ERROR가 100건인데 INFO가 10,000건이라면, 실제로는 1%의 에러율이지만 로그를 쭉 보면 에러가 많아 보일 수 있습니다. 바로 이럴 때 필요한 것이 로그 레벨별 분류 기술입니다.

각 레벨별로 로그를 분리해서 저장하거나, 레벨별 개수를 세어보면 시스템의 건강 상태를 한눈에 파악할 수 있습니다.

개요

간단히 말해서, 이 기술은 로그를 심각도(DEBUG, INFO, WARN, ERROR, FATAL)별로 나누어 관리하는 방법입니다. 마치 병원에서 환자를 경증, 중증, 응급으로 분류하는 것과 같은 원리입니다.

실무에서는 로그 레벨별 분류가 필수적입니다. 모니터링 시스템에서 ERROR 개수가 급증하면 알람을 보내거나, WARN 로그를 분석하여 미래의 에러를 예방할 수 있습니다.

예를 들어, 메모리 부족 경고(WARN)가 계속 나온다면, ERROR로 발전하기 전에 서버 증설을 준비할 수 있습니다. 기존에는 로그 파일 하나에 모든 레벨이 섞여 있어서 분석이 어려웠다면, 이제는 레벨별로 분리하여 각각 다른 전략으로 관리할 수 있습니다.

DEBUG는 개발 환경에서만 보고, ERROR는 즉시 알림을 받는 식으로 말이죠. 이 기술의 핵심 특징은 첫째, grep과 리다이렉션을 활용한 자동 분류, 둘째, 레벨별 파일 관리로 디스크 공간 절약, 셋째, 각 레벨에 맞는 보관 기간 설정이 가능하다는 점입니다.

이러한 특징들이 로그 관리를 체계적으로 만들어줍니다.

코드 예제

# 각 로그 레벨별로 파일 분리
grep "DEBUG" application.log > debug.log
grep "INFO" application.log > info.log
grep "WARN" application.log > warn.log
grep "ERROR" application.log > error.log

# 한 번에 모든 레벨 분류 (효율적인 방법)
awk '/DEBUG/ {print > "debug.log"} /INFO/ {print > "info.log"} /WARN/ {print > "warn.log"} /ERROR/ {print > "error.log"}' application.log

# 레벨별 개수만 빠르게 확인
echo "DEBUG: $(grep -c "DEBUG" application.log)"
echo "INFO: $(grep -c "INFO" application.log)"
echo "WARN: $(grep -c "WARN" application.log)"
echo "ERROR: $(grep -c "ERROR" application.log)"

# 특정 시간대의 로그만 레벨별 분류
grep "2025-11-18 14:" application.log | awk '/ERROR/ {print > "14h_error.log"} /WARN/ {print > "14h_warn.log"}'

설명

이것이 하는 일: 로그 레벨별 분류는 하나의 로그 파일을 읽어서 각 줄의 로그 레벨을 확인하고, 해당하는 레벨의 파일에 저장하는 작업입니다. 마치 우편물을 받아서 중요도에 따라 다른 서랍에 넣는 것과 같습니다.

첫 번째로, 기본적인 방법은 grep을 여러 번 실행하는 것입니다. grep "DEBUG" application.log > debug.log는 파일 전체를 읽어서 DEBUG가 포함된 줄만 debug.log에 저장합니다.

하지만 이 방법은 파일을 4번 읽어야 하므로 큰 파일에서는 비효율적입니다. 10GB 파일이라면 40GB를 읽는 셈이죠.

그 다음으로, awk를 사용하면 파일을 딱 한 번만 읽으면서 모든 레벨을 분류할 수 있습니다. awk는 각 줄을 읽을 때마다 패턴을 확인하고, 일치하면 해당 파일에 즉시 씁니다.

이 방식은 훨씬 빠르고 메모리도 적게 사용합니다. 실무에서는 이 방법을 추천합니다.

세 번째로, grep -c 옵션은 매칭되는 줄의 개수만 세어서 숫자로 출력합니다. 이를 활용하면 "DEBUG: 1523건, INFO: 8934건, WARN: 234건, ERROR: 12건" 같은 통계를 만들 수 있습니다.

echo와 $()를 조합하면 보기 좋은 형태로 출력할 수 있습니다. 마지막 예제처럼 grep과 awk를 파이프로 연결하면, 특정 시간대(예: 14시)의 로그만 추출한 후 레벨별로 분류할 수도 있습니다.

이런 식으로 조건을 계속 추가하면 매우 세밀한 분석이 가능합니다. 여러분이 이 코드를 사용하면 수십 개의 로그 파일을 체계적으로 관리할 수 있습니다.

ERROR 로그는 7일간 보관하고, INFO 로그는 1일만 보관하는 식으로 디스크 공간도 효율적으로 사용할 수 있습니다.

실전 팁

💡 awk를 사용할 때 파일명에 날짜를 포함하면 좋습니다. 예: debug_20251118.log 형식으로 저장하면 나중에 날짜별 분석이 쉽습니다.

💡 로그가 너무 많다면 ERROR와 WARN만 별도 파일로 저장하고, DEBUG와 INFO는 원본에만 남겨두는 것도 좋은 전략입니다.

💡 grep -c로 개수를 셀 때 결과를 CSV 파일로 저장하면 엑셀에서 차트를 그릴 수 있습니다. echo "DEBUG,$(grep -c DEBUG app.log)" >> stats.csv

💡 cron으로 매일 자정에 레벨별 분류 스크립트를 실행하면 자동으로 정리된 로그를 받아볼 수 있습니다.

💡 분류된 로그 파일에 다시 grep을 사용하면 더 정밀한 검색이 가능합니다. 예: grep "NullPointerException" error.log


3. wc로 로그 개수 세기

시작하며

여러분이 배포한 새 버전에서 에러가 발생한다는 보고를 받았습니다. 긴급하게 로그를 확인해보니 ERROR 로그가 보이긴 하는데, 이게 심각한 수준인지 아니면 가끔 발생하는 정도인지 판단하기 어렵습니다.

몇 건이나 발생했는지 알아야 롤백할지 말지 결정할 수 있습니다. 이런 문제는 로그를 눈으로만 보면 해결할 수 없습니다.

"많다", "적다"는 주관적인 판단이고, 실제로 몇 건인지 정확한 숫자가 필요합니다. 100건의 요청 중 1건의 에러는 1%지만, 10건의 요청 중 1건은 10%로 심각한 문제입니다.

바로 이럴 때 필요한 것이 wc(word count) 명령어입니다. 로그 줄 수를 세거나, 특정 패턴이 몇 번 나타나는지 정확히 카운팅하여 데이터 기반 의사결정을 할 수 있게 해줍니다.

개요

간단히 말해서, wc는 파일의 줄 수, 단어 수, 바이트 수를 세는 도구입니다. 로그 분석에서는 주로 줄 수(-l 옵션)를 사용하여 로그 개수를 파악합니다.

실무에서는 로그 개수가 매우 중요한 지표입니다. SLA(서비스 수준 협약)에서 "에러율 1% 이하 유지"라고 정의했다면, 전체 요청 수와 에러 수를 세어서 비율을 계산해야 합니다.

예를 들어, API 서버에서 하루 100만 건의 요청이 들어오는데 에러가 1만 건이면 1%로 SLA를 지키지 못한 것입니다. 기존에는 로그를 스크롤하면서 대충 "많다" "적다"로 판단했다면, 이제는 정확한 숫자로 판단할 수 있습니다.

어제는 50건, 오늘은 500건이면 10배 증가한 것이므로 뭔가 문제가 생긴 것입니다. wc의 핵심 특징은 첫째, 매우 빠른 카운팅 속도(기가바이트 파일도 몇 초), 둘째, grep 등 다른 명령어와 조합 가능, 셋째, 간단한 문법으로 누구나 쉽게 사용 가능하다는 점입니다.

이러한 특징들이 로그 통계의 기초를 만들어줍니다.

코드 예제

# 전체 로그 줄 수 세기
wc -l application.log

# 에러 로그만 개수 세기
grep "ERROR" application.log | wc -l

# 여러 파일의 총 줄 수
wc -l *.log

# 특정 시간대의 에러 개수
grep "2025-11-18 14:" application.log | grep "ERROR" | wc -l

# 에러율 계산 (전체 대비 에러 비율)
total=$(wc -l < application.log)
errors=$(grep "ERROR" application.log | wc -l)
echo "에러율: $(echo "scale=2; $errors * 100 / $total" | bc)%"

# 시간대별 로그 개수 비교
echo "13시: $(grep "2025-11-18 13:" application.log | wc -l)건"
echo "14시: $(grep "2025-11-18 14:" application.log | wc -l)건"
echo "15시: $(grep "2025-11-18 15:" application.log | wc -l)건"

설명

이것이 하는 일: wc 명령어는 파일이나 입력 데이터의 줄 수, 단어 수, 문자 수를 세는 간단하지만 강력한 도구입니다. -l 옵션을 사용하면 줄 수만 세므로 로그 분석에 최적화됩니다.

첫 번째로, wc -l application.log는 파일 전체를 읽어서 줄바꿈 문자(\n)가 몇 개인지 세어서 출력합니다. 결과는 "15234 application.log" 같은 형식으로 나오는데, 앞의 숫자가 줄 수입니다.

이것이 곧 전체 로그 개수를 의미합니다. 그 다음으로, grep과 파이프(|)로 연결하면 조건에 맞는 로그만 셀 수 있습니다.

grep "ERROR" application.log | wc -l은 먼저 grep이 ERROR를 포함한 줄만 추출하고, 그 결과를 wc가 받아서 개수를 셉니다. 이렇게 하면 에러 로그가 정확히 몇 건인지 알 수 있습니다.

세 번째로, 변수를 활용하면 복잡한 계산도 가능합니다. total=$(wc -l < application.log) 부분은 전체 줄 수를 total 변수에 저장하고, errors=$(grep "ERROR" application.log | wc -l) 부분은 에러 개수를 errors 변수에 저장합니다.

그 후 bc(계산기 프로그램)를 사용하여 에러율을 퍼센트로 계산합니다. 마지막으로, 여러 조건을 동시에 확인하면 트렌드를 파악할 수 있습니다.

시간대별 로그 개수를 비교하면 "14시에 갑자기 트래픽이 10배 증가했구나" 같은 인사이트를 얻을 수 있습니다. 이를 통해 특정 시간대에 문제가 집중되는지 확인할 수 있습니다.

여러분이 이 코드를 사용하면 감이 아닌 정확한 숫자로 시스템을 모니터링할 수 있습니다. 대시보드에 "현재 에러율: 0.8%"라고 표시하거나, "어제 대비 에러 200% 증가" 같은 알림을 만들 수 있습니다.

실전 팁

💡 wc -l < file.log 형식을 사용하면 파일명 없이 숫자만 출력되어 스크립트에서 사용하기 편합니다.

💡 여러 파일의 개수를 합산하려면 cat *.log | wc -l 처럼 cat으로 합친 후 세면 됩니다.

💡 실시간 로그를 모니터링하려면 watch -n 5 "grep ERROR app.log | wc -l" 명령어로 5초마다 자동으로 업데이트되게 할 수 있습니다.

💡 bc 대신 awk로도 계산 가능합니다: awk "BEGIN {printf \"%.2f%%\", ($errors/$total)*100}"

💡 로그 개수를 시계열 데이터로 저장하면 나중에 그래프를 그릴 수 있습니다: echo "$(date +%H:%M),$(grep ERROR app.log | wc -l)" >> error_count.csv


4. uniq로 중복 제거

시작하며

여러분이 에러 로그를 분석하는데, 같은 에러 메시지가 수천 번 반복되어 있습니다. "NullPointerException at line 42"가 3000번 나오면 로그가 너무 길어서 다른 에러를 찾기가 어렵습니다.

같은 에러는 한 번만 보고, 몇 번 발생했는지만 알 수 있다면 훨씬 효율적일 것입니다. 이런 상황은 로그 분석에서 매우 흔합니다.

특히 반복문 안에서 에러가 발생하거나, 여러 사용자가 동일한 문제를 겪으면 같은 에러가 수백, 수천 번 기록됩니다. 이 모든 걸 다 보는 것은 시간 낭비입니다.

바로 이럴 때 필요한 것이 uniq 명령어입니다. 중복된 줄을 제거하거나, 각 줄이 몇 번 나타났는지 카운트하여 로그를 요약해줍니다.

3000줄이 1줄로 줄어들면서도 핵심 정보는 잃지 않습니다.

개요

간단히 말해서, uniq는 연속된 중복 줄을 하나로 합쳐주는 도구입니다. 마치 "이하 동문"이라고 쓰는 것처럼, 반복되는 내용을 생략하여 간결하게 만들어줍니다.

실무에서는 중복 제거가 필수적입니다. 모니터링 알림을 설정할 때, 같은 에러로 1000개의 이메일을 받으면 정작 중요한 다른 알림을 놓칠 수 있습니다.

예를 들어, 데이터베이스 연결 실패가 계속 발생한다면, 첫 번째 알림만 받고 "이 에러가 523번 발생했습니다"라는 요약을 받는 것이 훨씬 유용합니다. 기존에는 중복된 로그를 일일이 스크롤하면서 확인했다면, 이제는 고유한 에러 종류만 빠르게 파악할 수 있습니다.

100가지 에러가 각각 10번씩 발생했는지, 1가지 에러가 1000번 발생했는지 즉시 구분됩니다. uniq의 핵심 특징은 첫째, -c 옵션으로 각 줄의 발생 횟수 카운트, 둘째, sort와 조합하여 가장 빈번한 에러 찾기, 셋째, 메모리 효율적인 스트림 처리 방식입니다.

이러한 특징들이 로그 요약을 자동화합니다.

코드 예제

# 기본 중복 제거 (연속된 중복만 제거됨)
sort application.log | uniq

# 중복 횟수와 함께 출력
sort application.log | uniq -c

# 가장 많이 발생한 에러 찾기 (상위 10개)
grep "ERROR" application.log | sort | uniq -c | sort -rn | head -10

# 에러 메시지만 추출하여 중복 제거
grep "ERROR" application.log | awk -F': ' '{print $2}' | sort | uniq -c | sort -rn

# 특정 패턴의 고유한 값 찾기 (예: IP 주소)
grep "Failed login" auth.log | awk '{print $5}' | sort | uniq -c | sort -rn

# 중복이 아닌 것만 출력 (한 번만 나타난 줄)
sort application.log | uniq -u

설명

이것이 하는 일: uniq 명령어는 입력에서 연속으로 중복된 줄을 찾아서 하나로 합쳐줍니다. 중요한 점은 "연속된" 중복만 제거한다는 것입니다.

따라서 먼저 sort로 정렬해야 모든 중복을 제거할 수 있습니다. 첫 번째로, sort application.log | uniq 명령어는 먼저 로그를 알파벳 순서로 정렬한 후, 연속된 동일한 줄을 하나로 만듭니다.

예를 들어 "ERROR: 123"이 10번 나오면, sort 후에는 10개가 연속으로 나열되고, uniq가 이를 1개로 줄입니다. 정렬하지 않으면 중간에 다른 줄이 끼어 있어서 중복 제거가 제대로 안 됩니다.

그 다음으로, -c 옵션을 추가하면 각 줄이 몇 번 나타났는지 숫자를 앞에 붙여줍니다. 결과는 "10 ERROR: 123" 같은 형식으로 나옵니다.

이를 다시 sort -rn으로 정렬하면 가장 많이 발생한 에러가 맨 위로 올라옵니다. -r은 역순(큰 것부터), -n은 숫자로 정렬하라는 의미입니다.

세 번째로, awk와 조합하면 더 정교한 분석이 가능합니다. awk -F': ' '{print $2}'는 콜론(:)을 구분자로 사용하여 두 번째 필드만 추출합니다.

"ERROR: NullPointerException"에서 "NullPointerException"만 뽑아내는 식입니다. 이렇게 하면 에러 메시지만으로 통계를 낼 수 있습니다.

마지막으로, -u 옵션은 반대로 중복되지 않은 줄만 출력합니다. 즉, 딱 한 번만 나타난 줄을 찾습니다.

이는 "특이한 에러"를 찾을 때 유용합니다. 1000번 발생한 흔한 에러보다, 딱 한 번 발생한 희귀한 에러가 진짜 문제의 원인일 수 있습니다.

여러분이 이 코드를 사용하면 수만 줄의 로그를 수십 줄로 요약할 수 있습니다. "가장 많이 발생한 에러 TOP 10"을 보면 어디에 집중해야 할지 즉시 알 수 있고, 리소스를 효율적으로 사용할 수 있습니다.

실전 팁

💡 uniq를 사용할 때는 반드시 먼저 sort를 실행하세요. 안 그러면 중복 제거가 제대로 안 됩니다.

💡 -c 결과를 파일로 저장해두면 시간별 비교가 가능합니다. 어제는 A 에러가 1위였는데 오늘은 B 에러가 1위라면 뭔가 변화가 있는 것입니다.

💡 head -10 대신 tail -10을 사용하면 가장 적게 발생한 에러를 볼 수 있습니다.

💡 로그 레벨별로 따로 uniq를 실행하면 더 정확합니다: grep ERROR app.log | sort | uniq -c, grep WARN app.log | sort | uniq -c

💡 IP 주소, 사용자 ID 등 특정 필드만 추출해서 uniq하면 "가장 많은 에러를 발생시킨 사용자" 같은 분석도 가능합니다.


5. sort로 정렬하기

시작하며

여러분이 시스템 장애 원인을 찾기 위해 로그를 분석하는데, 로그가 시간 순서대로 뒤죽박죽 섞여 있습니다. 여러 서버에서 수집한 로그를 합쳤더니 2시, 1시, 3시 이런 식으로 뒤섞여서 사건의 순서를 파악하기 어렵습니다.

또한 에러 코드별로 그룹핑해서 보고 싶은데 정렬이 안 되어 있으니 불편합니다. 이런 문제는 데이터가 정렬되지 않아서 발생합니다.

사람의 눈은 정렬된 데이터를 훨씬 빠르게 이해합니다. 시간 순서대로 보면 "A 이벤트 후 B 에러가 발생했구나"를 알 수 있고, 알파벳 순으로 정렬하면 같은 종류의 에러를 한눈에 볼 수 있습니다.

바로 이럴 때 필요한 것이 sort 명령어입니다. 로그를 시간순, 알파벳순, 숫자순 등 원하는 기준으로 정렬하여 분석을 쉽게 만들어줍니다.

특히 uniq, head, tail 등 다른 명령어와 조합할 때 sort는 필수입니다.

개요

간단히 말해서, sort는 텍스트 줄을 정렬하는 도구입니다. 책의 색인을 가나다순으로 정리하듯이, 로그를 원하는 순서대로 배열해줍니다.

실무에서는 정렬이 모든 분석의 기초입니다. uniq로 중복 제거하려면 먼저 정렬이 필요하고, 가장 큰/작은 값을 찾으려면 정렬 후 head/tail을 사용합니다.

예를 들어, API 응답 시간 로그를 정렬하면 가장 느린 요청이 무엇인지 즉시 찾을 수 있습니다. 기존에는 엑셀로 로그를 열어서 정렬 버튼을 눌렀다면, 이제는 명령어 한 줄로 기가바이트 파일도 몇 초 만에 정렬할 수 있습니다.

파일을 열 필요도, GUI를 사용할 필요도 없습니다. sort의 핵심 특징은 첫째, 다양한 정렬 기준(알파벳, 숫자, 역순, 특정 필드), 둘째, 대용량 파일도 처리 가능한 외부 정렬 알고리즘, 셋째, 다른 명령어와의 완벽한 호환성입니다.

이러한 특징들이 로그 분석의 기반을 만들어줍니다.

코드 예제

# 기본 알파벳 정렬
sort application.log

# 역순 정렬 (큰 것부터)
sort -r application.log

# 숫자로 정렬 (문자열이 아닌 숫자로 인식)
sort -n numbers.log

# 특정 필드(열)를 기준으로 정렬 (공백 구분, 3번째 필드)
sort -k3 application.log

# 타임스탬프로 정렬 (시간 순서)
sort -k1,2 application.log  # 1~2번째 필드(날짜+시간)

# 에러 코드별 정렬 후 중복 제거
grep "ERROR" application.log | awk '{print $4}' | sort | uniq -c

# 대소문자 구분 없이 정렬
sort -f application.log

# 여러 파일 합쳐서 정렬
sort app1.log app2.log app3.log > merged_sorted.log

설명

이것이 하는 일: sort 명령어는 파일의 각 줄을 읽어서 지정된 기준에 따라 순서를 재배열합니다. 기본값은 알파벳 순서(ASCII 코드 순서)이며, 옵션으로 다양한 정렬 방식을 선택할 수 있습니다.

첫 번째로, 기본 sort application.log는 각 줄을 문자열로 간주하여 사전식으로 정렬합니다. "a"로 시작하는 줄이 "z"로 시작하는 줄보다 앞에 옵니다.

이는 에러 메시지를 알파벳 순으로 그룹핑할 때 유용합니다. 같은 종류의 에러가 모두 모이니까요.

그 다음으로, -n 옵션은 숫자 정렬을 의미합니다. 기본 문자열 정렬에서는 "10"이 "2"보다 앞에 오지만(1이 2보다 작으므로), 숫자 정렬에서는 "2", "10" 순서가 됩니다.

에러 코드나 응답 시간 같은 숫자 데이터를 정렬할 때 반드시 사용해야 합니다. 세 번째로, -k 옵션은 특정 필드(열)를 기준으로 정렬합니다.

로그 형식이 "2025-11-18 14:30:15 ERROR 500 User not found"라면, -k4는 네 번째 필드인 "500"(에러 코드)를 기준으로 정렬합니다. -k1,2는 1~2번째 필드, 즉 날짜와 시간을 기준으로 정렬하여 시간 순서대로 만듭니다.

마지막으로, 여러 파일을 인자로 주면 모든 파일의 내용을 합쳐서 정렬합니다. 5대의 서버에서 수집한 로그를 시간 순서대로 합치려면 `sort -k1,2 server1.log server2.log ...

server5.log`처럼 사용합니다. 이렇게 하면 분산된 로그를 통합 분석할 수 있습니다.

여러분이 이 코드를 사용하면 아무리 복잡한 로그도 원하는 순서로 정리할 수 있습니다. 시간 순서로 보면 사건의 흐름을 추적하고, 빈도 순서로 보면 우선순위를 정하고, 특정 필드로 정렬하면 패턴을 발견할 수 있습니다.

실전 팁

💡 큰 파일을 정렬할 때는 -T /tmp 옵션으로 임시 디렉토리를 지정하면 디스크 공간이 부족한 문제를 피할 수 있습니다.

💡 -u 옵션을 사용하면 정렬과 동시에 중복 제거가 됩니다. sort -usort | uniq와 같은 결과입니다.

💡 여러 기준으로 정렬하려면 -k를 여러 번 사용하세요: sort -k1,1 -k3,3n은 1번 필드로 먼저 정렬하고, 같으면 3번 필드를 숫자로 정렬합니다.

💡 CSV 파일처럼 구분자가 쉼표인 경우 -t, 옵션으로 구분자를 지정할 수 있습니다.

💡 정렬 결과를 원본에 덮어쓰지 마세요. 실수로 데이터가 손실될 수 있으니 항상 > sorted.log 형태로 새 파일에 저장하세요.


6. 기본 통계 스크립트 작성

시작하며

여러분이 매일 아침 출근하면 어제 발생한 로그를 분석해야 합니다. 매번 grep으로 에러 찾고, wc로 개수 세고, sort로 정렬하고, uniq로 요약하는 작업을 반복하다 보니 시간이 너무 오래 걸리고 실수도 자주 발생합니다.

이 과정을 자동화할 수 있다면 몇 분이면 끝날 텐데 말이죠. 이런 반복 작업은 스크립트로 자동화하는 것이 정답입니다.

한 번 스크립트를 작성해두면 언제든지 실행만 하면 되고, 동료와 공유할 수도 있으며, 실수 없이 일관된 결과를 얻을 수 있습니다. 특히 매일 같은 분석을 해야 한다면 스크립트는 필수입니다.

바로 이럴 때 필요한 것이 Bash 스크립트입니다. 지금까지 배운 grep, wc, sort, uniq 명령어들을 하나의 스크립트로 묶어서, 단 한 줄의 명령어로 전체 로그 분석을 완료할 수 있습니다.

개요

간단히 말해서, Bash 스크립트는 여러 명령어를 하나의 파일에 담아서 순서대로 자동 실행하는 프로그램입니다. 마치 요리 레시피처럼 순서를 정해두면 컴퓨터가 알아서 실행해줍니다.

실무에서는 스크립트가 생산성의 핵심입니다. 10분 걸리는 작업을 10초로 줄일 수 있고, 사람이 실수할 부분을 제거하며, 누구나 같은 방식으로 분석할 수 있게 표준화됩니다.

예를 들어, 매일 아침 9시에 자동으로 로그 분석 리포트를 이메일로 받을 수 있습니다. 기존에는 명령어를 하나씩 입력하며 결과를 기록했다면, 이제는 스크립트 하나로 모든 통계를 자동 생성할 수 있습니다.

게다가 변수와 함수를 사용하면 다양한 상황에 재사용 가능합니다. 스크립트의 핵심 특징은 첫째, 복잡한 분석 로직을 재사용 가능하게 저장, 둘째, 조건문과 반복문으로 지능적 처리, 셋째, cron과 결합하여 스케줄링 가능하다는 점입니다.

이러한 특징들이 로그 분석을 완전 자동화합니다.

코드 예제

#!/bin/bash
# 로그 통계 분석 스크립트

LOG_FILE="application.log"
REPORT_FILE="daily_report_$(date +%Y%m%d).txt"

echo "===== 로그 분석 리포트 =====" > $REPORT_FILE
echo "분석 일시: $(date)" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# 전체 로그 개수
total=$(wc -l < $LOG_FILE)
echo "전체 로그: $total 건" >> $REPORT_FILE

# 로그 레벨별 개수
echo "" >> $REPORT_FILE
echo "레벨별 통계:" >> $REPORT_FILE
echo "  DEBUG: $(grep -c "DEBUG" $LOG_FILE) 건" >> $REPORT_FILE
echo "  INFO: $(grep -c "INFO" $LOG_FILE) 건" >> $REPORT_FILE
echo "  WARN: $(grep -c "WARN" $LOG_FILE) 건" >> $REPORT_FILE
echo "  ERROR: $(grep -c "ERROR" $LOG_FILE) 건" >> $REPORT_FILE

# 에러율 계산
errors=$(grep -c "ERROR" $LOG_FILE)
error_rate=$(echo "scale=2; $errors * 100 / $total" | bc)
echo "" >> $REPORT_FILE
echo "에러율: $error_rate%" >> $REPORT_FILE

# 가장 많이 발생한 에러 TOP 5
echo "" >> $REPORT_FILE
echo "빈발 에러 TOP 5:" >> $REPORT_FILE
grep "ERROR" $LOG_FILE | awk -F': ' '{print $2}' | sort | uniq -c | sort -rn | head -5 >> $REPORT_FILE

# 시간대별 트래픽
echo "" >> $REPORT_FILE
echo "시간대별 로그:" >> $REPORT_FILE
for hour in {00..23}; do
    count=$(grep "2025-11-18 $hour:" $LOG_FILE | wc -l)
    if [ $count -gt 0 ]; then
        echo "  ${hour}시: $count 건" >> $REPORT_FILE
    fi
done

echo "" >> $REPORT_FILE
echo "===== 분석 완료 =====" >> $REPORT_FILE
cat $REPORT_FILE

설명

이것이 하는 일: 이 스크립트는 로그 파일을 읽어서 다양한 통계를 계산하고, 그 결과를 읽기 쉬운 리포트 형태로 저장합니다. 매일 같은 형식의 분석 결과를 자동으로 만들어주는 일종의 로봇입니다.

첫 번째로, #!/bin/bash는 이 파일이 Bash 스크립트임을 선언하는 셰뱅(shebang)입니다. 그 다음 변수를 정의합니다.

LOG_FILE은 분석할 로그 파일 이름이고, REPORT_FILE은 결과를 저장할 파일인데 날짜를 포함하여 매일 다른 이름으로 저장됩니다. $(date +%Y%m%d)는 오늘 날짜를 20251118 형식으로 만듭니다.

그 다음으로, echo와 >> 리다이렉션으로 리포트 파일에 내용을 계속 추가합니다. 첫 번째 echo는 > 하나로 파일을 새로 만들고, 그 다음부터는 >>로 내용을 덧붙입니다.

wc -l < $LOG_FILE로 전체 로그 개수를 세고, grep -c로 각 레벨의 개수를 셉니다. 세 번째로, bc를 사용하여 에러율을 계산합니다.

scale=2는 소수점 2자리까지 표시하라는 의미입니다. 그 다음 grep, awk, sort, uniq, head를 파이프로 연결하여 가장 빈번한 에러 TOP 5를 추출합니다.

이는 앞에서 배운 모든 기술의 조합입니다. 마지막으로, for 반복문을 사용하여 00시부터 23시까지 각 시간대의 로그 개수를 셉니다.

{00..23}은 00, 01, 02, ..., 23을 순서대로 생성합니다. if 조건문으로 0건인 시간대는 출력하지 않아서 리포트가 간결해집니다.

모든 분석이 끝나면 cat $REPORT_FILE로 리포트를 화면에 출력합니다. 여러분이 이 스크립트를 사용하면 단 한 줄의 명령어(./log_analysis.sh)로 수십 줄의 명령어를 실행한 것과 같은 효과를 얻습니다.

cron에 등록하면 매일 자동으로 실행되어 아침에 출근하면 리포트가 준비되어 있습니다.

실전 팁

💡 스크립트를 실행 가능하게 만들려면 chmod +x log_analysis.sh 명령어를 먼저 실행하세요.

💡 에러 처리를 추가하면 더 안정적입니다: if [ ! -f $LOG_FILE ]; then echo "로그 파일이 없습니다"; exit 1; fi

💡 매일 자동 실행하려면 crontab에 등록하세요: 0 9 * * * /path/to/log_analysis.sh (매일 오전 9시)

💡 리포트를 이메일로 보내려면 mail -s "로그 리포트" admin@example.com < $REPORT_FILE 명령어를 스크립트 끝에 추가하세요.

💡 여러 로그 파일을 분석하려면 for 반복문 안에서 각 파일을 처리하면 됩니다: for log in *.log; do ... done


#Bash#grep#wc#sort#uniq#awk#Bash,Linux,로그분석

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.