lnav - tail -f는 이제 그만, 로그 분석의 새 세계
tail -f로 로그를 보던 시절은 끝났습니다. lnav(Log Navigator)는 자동 컬러링, 에러 점프, 필터링, SQL 분석까지 지원하는 터미널 기반 로그 분석 도구입니다.
도입
현우: 도현아, 요즘 서버 로그 볼 때 뭐 쓰고 있어?
도현:
tail -f catalina.out쓰고 있는데요… 로그가 너무 빨리 올라가서 눈이 아파요. 에러 찾으려면 한참 스크롤해야 하고요.
현우: 나도 신입 때 그랬어. 로그가 쏟아지는데 눈으로 에러 찾겠다고 화면 뚫어져라 쳐다보고. 오늘 lnav라는 도구 하나 알려줄게. 이거 쓰면
tail -f쓸 이유가 진짜 없어져.
도현: lnav요? 처음 들어보는데요.
현우: Log Navigator의 줄임말인데, 로그 파일을 컬러링해주고, 에러만 콕콕 찍어서 점프할 수 있고, 필터링도 되고, 심지어 SQL로 로그를 분석할 수도 있어. 맥에서 brew로 한 줄이면 설치 끝이야.
설치
현우: 자, 먼저 설치부터 하자. 이거 한 줄이면 돼.
brew install lnav
도현: 설치 끝이에요? 설정 같은 건 없나요?
현우: 없어! 그게 lnav의 장점이야. 설치하자마자 바로 쓸 수 있어. 확인해보려면 이렇게.
lnav --version
기본 실행
현우: 실행 방법도 간단해. 파일 경로만 넣으면 돼.
# 단일 파일
lnav /opt/tomcat/logs/catalina.out
# 여러 파일 동시 보기 (자동 병합 + 시간순 정렬)
lnav /var/log/*.log
# 디렉토리 전체
lnav /opt/tomcat/logs/
# 파이프로 받기
cat logfile.log | lnav
# 압축 파일도 직접 열림
lnav catalina.out.gz
도현: 여러 파일을 동시에 볼 수 있다고요? 그러면 서로 다른 서버 로그도요?
현우: 맞아! 여러 파일을 넣으면 시간순으로 자동 병합해줘. 분산 환경에서 디버깅할 때 진짜 유용해. 그리고 가장 중요한 건, lnav는 파일을 열면 자동으로 tail -f 모드로 동작해. 새 로그가 추가되면 자동으로 따라가.
도현: 아, 그러면
tail -f대신 lnav로 열기만 하면 되는 거군요!
현우: 정확해! 근데 lnav는
tail -f에서 절대 못 하는 것들을 할 수 있어.
화면 구성
도현: 열어보니까 로그가 색깔이 있는데요? ERROR는 빨간색이고 WARN은 노란색이에요!
현우: 그래, lnav가 로그 포맷을 자동 인식해서 레벨별로 컬러링해줘. 별도 설정 없이!
| 영역 | 설명 |
|---|---|
| 상단 바 | 파일명, 라인 수, 현재 위치 |
| 메인 영역 | 로그 내용 (ERROR=빨강, WARN=노랑, INFO=초록 자동 컬러링) |
| 하단 바 | 명령 입력, 필터 상태 |
도현:
tail -f는 그냥 하얀 텍스트 벽이었는데, 이건 한눈에 뭐가 에러인지 보이네요.
이동 - Vi 스타일 키바인딩
현우: lnav는 Vi 스타일 키바인딩을 쓰거든. Vim 쓸 줄 알면 바로 익숙할 거야.
| 키 | 동작 |
|---|---|
j / k |
한 줄 아래/위 |
h / l |
좌/우 스크롤 |
PgDn / PgUp |
페이지 단위 이동 |
g / G |
파일 맨 위 / 맨 아래 |
e / E |
다음 에러 / 이전 에러로 점프 |
w / W |
다음 경고 / 이전 경고로 점프 |
Space |
다음 페이지 |
도현:
e키로 에러만 점프할 수 있다고요?! 수천 줄에서 에러 찾으려고 스크롤하지 않아도 되는 건가요?
현우: 맞아!
e키가 킬러 기능이야. 에러 하나 보고,e누르면 다음 에러로 딱. 또e누르면 그 다음 에러로. 수만 줄 로그에서 에러만 콕콕 찍어 이동하는 거지. 이전 에러로 돌아가고 싶으면 대문자E.
도현: 경고도
w/W로 같은 방식이고요? 이거 하나만으로도tail -f대신 쓸 이유가 되네요.
현우: 그치? 근데 이건 시작에 불과해.
검색
현우: 검색은
/키를 누르면 돼. 정규식도 지원해.
| 키 | 동작 |
|---|---|
/ |
정규식 검색 (아래 방향) |
n / N |
다음 / 이전 검색 결과 |
도현: Vim이랑 똑같네요!
현우: 맞아. 예를 들면 이런 식으로 쓸 수 있어.
/NullPointerException
/ERROR.*biocideProd
/MST_NO.*1007834
현우: 정규식이니까
.*같은 패턴도 당연히 되고. 검색하면 매칭된 부분이 하이라이팅돼서 바로 눈에 들어와.
필터 - 가장 유용한 기능
현우: 자, 이게 lnav의 진짜 핵심이야. 필터 기능.
:키를 눌러서 명령 모드로 들어가.
도현:
:키요? 이것도 Vim이랑 비슷하네요.
현우: 맞아. 여기서 필터 명령어를 쓸 수 있어.
특정 패턴만 보기
:filter-in ERROR
:filter-in biocideProd
현우:
filter-in은 해당 패턴이 포함된 줄만 보여줘. 나머지는 다 숨겨.
특정 패턴 숨기기
:filter-out DEBUG
:filter-out HealthCheck
현우:
filter-out은 반대로 해당 패턴을 제외하고 보여줘. 헬스체크 로그가 너무 많을 때 유용하지.
시간 범위 필터
:hide-lines-before 2026-02-14 10:00:00
:hide-lines-after 2026-02-14 11:00:00
도현: 시간 범위로도 필터링이 돼요?! 장애 발생 시간대만 딱 볼 수 있겠네요!
현우: 그래! 장애 나면 보통 “10시 30분쯤 문제가 생겼다"고 하잖아. 그러면 그 시간대만 딱 잘라서 볼 수 있어.
로그 레벨 필터
:set-min-log-level warning
:set-min-log-level error
현우: 이건 로그 레벨로 필터링하는 거야.
warning으로 설정하면 WARNING 이상만 보이고,error로 설정하면 ERROR 이상만 보여.
필터 관리
| 키/명령 | 동작 |
|---|---|
TAB |
필터 패널 열기/닫기 |
:reset-session |
모든 필터 초기화 |
:disable-filter <패턴> |
특정 필터 비활성화 |
도현:
TAB으로 필터 패널을 열면 현재 적용된 필터를 한눈에 볼 수 있는 건가요?
현우: 맞아. 필터를 여러 개 걸다 보면 뭘 걸었는지 헷갈리거든.
TAB누르면 현재 활성화된 필터 목록이 쭉 나와.
뷰 전환
현우: lnav에는 다양한 뷰 모드가 있어.
| 키 | 뷰 |
|---|---|
P |
PRETTY 뷰 (JSON, XML 자동 포맷팅) |
i |
히스토그램 뷰 (시간대별 에러/경고 분포) |
I |
히스토그램에서 원래로 복귀 |
T |
타임스탬프 토글 (상대시간 <-> 절대시간) |
도현: 히스토그램이요? 로그를 그래프로 보여주는 건가요?
현우:
i키를 눌러봐. 시간대별로 에러가 몇 건, 경고가 몇 건 발생했는지 막대 그래프로 보여줘. 어느 시간대에 문제가 집중됐는지 한눈에 파악할 수 있어. 장애 분석할 때 진짜 유용하지.
도현: 와…
tail -f로는 상상도 못 할 기능이네요.
현우: 그리고
P키도 추천해. API 응답 로그에 JSON이 한 줄로 찍혀 있으면 읽기 힘들잖아?P누르면 자동으로 예쁘게 들여쓰기해서 보여줘.
SQL 모드 - 로그를 DB처럼 분석
현우: 자, 이건 좀 고급 기능인데. lnav에서
;키를 누르면 SQL 모드로 들어가.
도현: SQL이요? 로그 파일을 SQL로 조회한다고요?
현우: 그래! lnav가 로그를 SQLite DB처럼 쿼리할 수 있게 해줘. 테이블 이름은
logline이야.
-- 에러 레벨별 카운트
;SELECT log_level, count(*) FROM logline GROUP BY log_level
-- 시간대별 에러 수
;SELECT timeslice(log_time, '1h'), count(*) FROM logline WHERE log_level = 'error' GROUP BY 1
-- 특정 패턴 포함 라인
;SELECT log_body FROM logline WHERE log_body LIKE '%Exception%'
도현: 시간대별 에러 수를 SQL로 뽑을 수 있다니… 이거 장애 보고서 쓸 때 엄청 편하겠는데요?
현우: 맞아! 예전에 나도 장애 보고서 쓰면서 “10시
11시 에러 몇 건, 11시12시 몇 건” 이런 거 수작업으로 세다가 lnav SQL 알고 나서 삶이 바뀌었어.
실무 활용 시나리오
현우: 실제로 내가 자주 쓰는 패턴 몇 가지 알려줄게.
시나리오 1: Tomcat 로그 실시간 모니터링
lnav /opt/tomcat/logs/catalina.out
현우: 열자마자 자동으로 최신 로그가 보이고,
e키로 에러만 탐색하면 돼.
시나리오 2: 특정 기능 디버깅
lnav catalina.out
# 연 다음:
:filter-in biocideProd
:set-min-log-level warning
현우: 우리 프로젝트에서 살생물제 모듈만 보고 싶을 때 이렇게 해. biocideProd 관련 WARNING 이상만 딱 보여.
시나리오 3: 여러 서버 로그 병합
lnav server1.log server2.log server3.log
현우: 시간순으로 자동 병합돼서, 분산 환경에서 요청이 어떻게 흘러갔는지 추적할 수 있어.
도현: 그러면 WAS 여러 대 쓸 때도 로그를 한 번에 볼 수 있는 거네요!
현우: 맞아. 로드밸런서 뒤에 WAS 3대 있을 때, 어느 서버에서 에러 났는지 한 화면에서 확인 가능해.
tail -f vs lnav 비교
현우: 마지막으로 정리해보면 이런 차이야.
| 기능 | tail -f | lnav |
|---|---|---|
| 실시간 추적 | O | O |
| 에러 컬러링 | X | O (자동) |
| 에러 점프 | X | O (e 키) |
| 검색/필터 | X (grep 파이프 필요) | O (내장) |
| 시간 범위 | X | O |
| 여러 파일 병합 | X | O |
| 위로 스크롤 | X | O |
| SQL 분석 | X | O |
도현: 이렇게 보니까
tail -f를 쓸 이유가 정말 없어지네요.
현우: 맥북프로에서
brew install lnav한 번이면 로그 분석 환경이 완전히 달라져. 처음에e키랑:filter-in이 두 가지만 기억해도 충분해. 나머지는 쓰다 보면 자연스럽게 익숙해지거든.
도현: 네! 오늘부터 바로 써볼게요.
e로 에러 점프,:filter-in으로 필터링,i로 히스토그램. 이 세 가지부터 시작하겠습니다!
현우: 그리고 도움말은
?키, 종료는q키야. 까먹으면?누르면 돼.
핵심 단축키 치트시트
| 키 | 용도 |
|---|---|
? |
도움말 |
q |
종료 |
e / E |
다음/이전 에러 |
w / W |
다음/이전 경고 |
/ |
검색 |
: |
명령 모드 |
; |
SQL 모드 |
TAB |
필터 패널 |
i |
히스토그램 |
P |
Pretty Print |
g / G |
맨 위 / 맨 아래 |