Views: 0
목차
왜 cat 대신 다른 도구를 써야 할까
cat은 파일 전체를 한 번에 표준출력으로 밀어내기 때문에 수십 MB 이상 로그에서 비효율적이다. 스크롤·검색·필터링 기능도 없어 사람이 눈으로 따라가기가 어렵다. 반면 less는 대용량 파일을 즉시 열어 페이지 단위로 탐색하고, tail -f는 새로 써지는 줄만 실시간으로 붙여 보여주며, journalctl은 systemd 기반 서비스 로그를 구조적으로 필터링한다. 상황에 맞게 이 셋을 조합하면 탐색 속도와 정확도가 크게 올라간다.
less로 대용량 로그를 빠르게 훑는 법
less는 “읽기 전용 뷰어”다. 기본 동작을 손에 익히면 cat보다 훨씬 빠르다.
필수 옵션과 단축키
- 줄 넘김 없이 가로 스크롤 허용:
less -S /var/log/nginx/access.log - ANSI 색상 보존(파이프에서 색상 유지):
... | less -R - 파일 끝으로 즉시 이동:
G - 파일 처음으로 이동:
g - 페이지 위/아래:
Space,b - 줄 단위 이동:
j,k - 앞으로 검색:
/에러패턴→ 다음/이전 결과n/N - 뒤로 검색:
?에러패턴 - 현재 뷰 필터(매우 유용):
&정규식(해제는&만 입력)
색상 하이라이트와 조합
grep의 색상을 살려서 less에 넘기면 시인성이 확 올라간다.
grep --color=always -E "ERROR|WARN" app.log | less -R
JSON 로그라면 키워드만 뽑아 하이라이트한다.
jq -r '.level + " " + .msg' app.json.log | grep --color=always -E "ERROR|WARN|Timeout" | less -R
압축 로그 한 번에 보기
로테이션된 gz 로그까지 이어서 본다.
zgrep -h --color=always "ERROR" /var/log/app.log /var/log/app.log.1.gz | less -R
단순 열람은 zless가 편하다.
zless /var/log/nginx/access.log.1.gz
tail -f로 실시간 추적을 제대로 하는 법
실시간 추적은 tail -f가 기본이지만, 로테이션을 고려해 -F를 쓰는 습관이 중요하다.
-f와 -F의 차이
tail -f: 파일 디스크립터를 붙잡고 따라간다. 로테이션(rename) 후 새 파일은 못 따라감.tail -F: 파일명이 같은 새 로그로 교체돼도 자동 추적한다. 실무 기본값으로 추천.
즉시 전줄부터 따라가기
서비스 재시작 직후의 힌트를 놓치지 않으려면 최근 N줄과 함께 추적한다.
tail -n 200 -F /var/log/app.log
라인 버퍼링으로 실시간 필터
grep·awk는 버퍼링 때문에 늦게 출력될 수 있다. 실시간은 라인 버퍼링 옵션을 쓴다.
tail -F app.log | grep --line-buffered -E "ERROR|WARN|Timeout"
tail -F access.log | awk -W interactive '$9 ~ /5[0-9][0-9]/ {print $0}'
특정 프로세스만 추적
PID가 있는 경우:
tail -F app.log | grep --line-buffered "pid=12345"
여러 파일 동시 추적
마이크로서비스를 묶어 본다.
tail -F /var/log/app/*.log | ts '[%Y-%m-%d %H:%M:%S]' # moreutils의 ts 사용 시
journalctl로 systemd 서비스 로그를 정밀 필터링
systemd 환경에서는 journalctl이 sshd, nginx, custom 서비스의 표준 로그 뭉치를 한 번에 다룬다.
서비스 단위로 필터
journalctl -u nginx --since "30 min ago"
journalctl -u sshd -f # 실시간 추적
journalctl -u myapp.service -n 200 # 최근 200줄
시간·부팅·중요도 기준
journalctl --since "2025-10-23 10:00" --until "2025-10-23 11:00"
journalctl -b -1 # 이전 부팅 시퀀스
journalctl -p warning..emerg # 경고 이상만
빠른 문자열 검색과 정규식
journalctl -u myapp --grep="Timeout|failed to connect" -f
JSON·필드 기반 출력
머신 가공용으로는 JSON 출력이 적합하다.
journalctl -u myapp -o json | jq -r '[.ts,.PRIORITY,.MESSAGE] | @tsv'
컬러를 보려면 페이저 해제:
journalctl -u myapp --no-pager -o short-iso-precise
상황별 실전 패턴 모음
SSH 공격 급증 감지
최근 15분간 실패 10회 이상 IP 상위 10개 추출:
journalctl -u sshd --since "15 min ago" \
| grep "Failed password" \
| awk '{for(i=1;i<=NF;i++) if ($i ~ /([0-9]{1,3}\.){3}[0-9]{1,3}/) print $i}' \
| sort | uniq -c | sort -nr | head
Nginx 5xx 폭증 원인 파악
상위 URL과 IP를 빠르게 집계한다.
awk '$9 ~ /^5/ {print $7}' /var/log/nginx/access.log \
| sort | uniq -c | sort -nr | head
awk '$9 ~ /^5/ {print $1}' /var/log/nginx/access.log \
| sort | uniq -c | sort -nr | head
실시간으로 보면:
tail -F /var/log/nginx/access.log | awk -W interactive '$9 ~ /^5/'
애플리케이션 에러 스택 탐색
스택 트레이스는 여러 줄로 이어지는 경우가 많다. “Anchor → 컨텍스트 확장” 방식이 효율적이다.
grep -n "NullPointerException" app.log | head
# 번호 확인 후
nl -ba app.log | sed -n '1200,1300p' | less
배포 직후만 골라보기
특정 시각 이후만 추적하면 잡음이 줄어든다.
journalctl -u myapp --since "2025-10-23 14:05"
색상 하이라이트로 빠른 패턴 인식
grep --color=always -E "ERROR|WARN|Timeout|Refused" app.log | less -R
로테이션·압축·보존 정책과의 궁합
- logrotate가 동작하면 파일이 rename되고 새 파일이 열린다. 실시간 추적은
tail -F를 사용한다. - 과거 이슈 회고는 gz까지 범위를 넓혀
zgrep·zless로 본다. - 보존 주기가 짧다면 문제 발생 시점의 로그를 즉시 백업해 증거를 확보한다.
성능을 해치지 않는 사용 습관
- 거대한 파일을 통으로 grep하지 말고 시간으로 좁혀라(journalctl의
--since,--until). - 정규식은 필요한 그룹만 최소화하고, 파이프는 두세 단계 내로 단순하게 유지한다.
- 반복 조회하는 패턴은 함수로 alias 정의해 휴먼 에러를 줄인다.
alias jerr='journalctl -p err..emerg --no-pager -o short-iso'
alias japp='journalctl -u myapp --no-pager -o short-iso'
팀 작업을 위한 출력 형식 표준화
- 운영 채널 공유를 위해 ISO 타임스탬프 출력(
-o short-iso-precise)을 통일한다. - JSON 로그는 jq 템플릿을 정해 핵심 필드만 뽑는다.
- 이슈 티켓에는 “증상 → 관련 로그 스냅샷 → 시간 범위 → 재현 절차” 순으로 기록한다.
흔한 실수와 빠른 교정 팁
- cat으로 수백 MB를 터미널에 뿌려 터미널이 멎는 문제: less로 열고 필요 시
/패턴검색. - tail -f가 로테이션 후 끊기는 문제: -F로 교체.
- journalctl 결과가 너무 많아 스크롤이 힘든 문제:
-u,-p,--since로 필터부터 적용. - 색상 사라짐:
--color=always | less -R조합 사용. - 실제 클라이언트 IP가 보이지 않음: 리버스 프록시 환경에서는 로그 포맷과 real IP 설정을 점검.
실무용 치트시트
# 최근 10분 nginx 5xx만 색상 하이라이트
awk -v T="$(date -d '-10 min' +'%d/%b/%Y:%H:%M')" '$4 ~ T && $9 ~ /^5/' /var/log/nginx/access.log \
| grep --color=always -E "HTTP/| 5[0-9]{2} " | less -R -S
# sshd 경고 이상만, ISO 타임스탬프
journalctl -u sshd -p warning..emerg --since "1 hour ago" -o short-iso --no-pager
# 앱 로그 에러를 실시간으로, 라인 버퍼링
tail -F /var/log/app/app.log | grep --line-buffered -E "ERROR|Exception"
# gz 포함 특정 에러 키워드 종합 조회
zgrep -h --color=always -E "OutOfMemory|Timeout" /var/log/app/app.log* | less -R
마무리
로그 읽기의 핵심은 “목표를 좁히고, 필요한 줄만 빨리 보는 것”이다. less로 대용량을 빠르게 탐색하고, tail -F로 현재 진행형 이슈를 붙잡으며, journalctl로 서비스·시간·중요도 축을 정교하게 필터링하면 추적 속도가 눈에 띄게 향상된다. 위의 패턴을 그대로 손에 익히면 배포 문제, 성능 저하, 보안 이벤트까지 터미널 하나로 신속하게 진단할 수 있다.