콘텐츠로 이동
Study Note서버 관리 일반

6. 로그 — 무슨 일이 있었나

로그는 grep 하는 것이 아니라 필터로 좁히는 것이다 — journal은 텍스트 파일이 아니다

이 장에서 처음 나오는 말5개
journal
systemd가 모든 로그를 구조화된 바이너리 형식으로 모아 두는 저장소. 필드(유닛·PID·우선순위·부팅 ID)로 질의할 수 있다는 것이 텍스트 로그와의 결정적 차이다.
facility / priority
syslog가 물려준 로그의 두 축. facility는 출처(auth·cron·kern·daemon), priority는 심각도(0 emerg ~ 7 debug)다. journalctl -p err의 err가 priority 3이다.
부팅 IDboot ID
부팅할 때마다 새로 생기는 식별자. journalctl -b는 이번 부팅, -b -1은 직전 부팅 — 크래시 원인을 찾을 때 쓰는 바로 그 옵션이다.
rsyslog
journal과 별개로 /var/log 아래에 텍스트 로그 파일을 만드는 전통적 로그 데몬. Ubuntu 서버에 기본 설치돼 있어 같은 내용이 두 곳에 남는다.
logrotate
로그 파일이 무한정 커지지 않게 주기적으로 잘라서 압축·보관·삭제하는 도구. /var/log의 .1·.2.gz 파일들이 그 결과다.
터미널 창
journalctl -u nginx # 이 유닛의 로그만
journalctl -u nginx -f # 실시간 따라가기 (tail -f)
journalctl -u nginx -n 100 # 마지막 100줄
journalctl -b # 이번 부팅 전체
journalctl -b -1 -e # 직전 부팅의 끝 ← 갑작스러운 재부팅 조사
journalctl -p err -b # 오류 이상만
journalctl --since "1 hour ago"
journalctl --since "2026-08-10 09:00" --until "2026-08-10 10:00"
journalctl -k # 커널 로그만 (= dmesg)
journalctl -xe # 최근 + 설명 추가 (실패 직후 관용구)

옵션은 자유롭게 겹친다. 실전에서 쓰는 형태는 대개 조합이다. 옵션만 빨리 찾으려면 systemctl · journalctl 명령 참조를 쓴다.

터미널 창
journalctl -u myapp -p warning --since today --no-pager | tail -50
sudo journalctl -u ssh --since "2026-08-01" | grep "Accepted"
자주 쓰는 옵션뜻
-f / -e실시간 따라가기 / 끝으로 이동해서 열기
-r최신순으로 뒤집기
--no-pager페이저 없이 그대로 출력 (스크립트·파이프용)
-o short-iso타임스탬프를 ISO 형식으로 (-o json · -o cat도 있다)
-p erremerg alert crit err warning notice info debug
--user사용자 세션 유닛의 로그

유닛 이름을 모를 때 — 필드로 찾기

섹션 제목: “유닛 이름을 모를 때 — 필드로 찾기”

journal은 모든 줄에 메타데이터가 붙어 있다. 이것이 텍스트 로그와 다른 지점이다.

터미널 창
journalctl _COMM=sshd # 프로세스 이름으로
journalctl _PID=1234 # PID로
journalctl _UID=1000 # 사용자로
journalctl /usr/sbin/cron # 실행 파일 경로로
journalctl -F _SYSTEMD_UNIT # 로그를 남긴 유닛 목록 전체
journalctl -o verbose -n 1 # 한 줄에 어떤 필드가 붙어 있는지 구경
  • 디렉터리/var/log/
    • syslog 시스템 전반 (rsyslog가 만든다)
    • auth.log 인증·sudo·SSH — 11장의 핵심 파일
    • kern.log 커널 메시지
    • dpkg.log 패키지 설치/제거 하나하나
    • 디렉터리apt/
      • history.log 누가 언제 무슨 apt 명령을 실행했나
      • term.log 그때의 화면 출력 전체
    • 디렉터리unattended-upgrades/ 자동 보안 업데이트 결과
      • …
    • 디렉터리journal/ journal 본체 (바이너리)
      • …
    • 디렉터리nginx/ · mysql/ … 애플리케이션이 직접 쓰는 로그
      • …
    • wtmp · btmp · lastlog 로그인 이력 (바이너리 — 11장)
터미널 창
sudo tail -f /var/log/syslog
sudo grep -i error /var/log/syslog | tail -30
sudo zgrep -i "failed" /var/log/auth.log.*.gz # 로테이션된 압축본까지
sudo less +F /var/log/nginx/error.log # tail -f처럼 보다가 Ctrl-C로 탐색 모드

압축된 옛 로그는 zgrep·zcat·zless 로 푼다 — 이걸 모르면 며칠 전 사건을 놓친다.

하드웨어 오류·OOM·드라이버·디스크 I/O 에러가 여기 남는다.

터미널 창
sudo dmesg -T # 사람이 읽는 시각으로 (-T 없으면 부팅 후 초)
sudo dmesg -T -l err,warn # 심각한 것만
sudo dmesg -T -w # 실시간
sudo dmesg -T | grep -i -E "error|fail|oom|i/o"
터미널 창
journalctl --disk-usage # 저널이 차지한 용량
sudo journalctl --vacuum-time=14d # 14일치만 남기고 삭제
sudo journalctl --vacuum-size=500M # 500MB까지 줄인다
sudo du -sh /var/log/* | sort -rh | head # 텍스트 로그 쪽 범인 찾기

Ubuntu 24.04는 저널이 영구 저장(/var/log/journal)인데 크기 상한이 기본으로 설정돼 있지 않다 — 오래된 서버에서 저널이 수 GB로 자라 있는 일이 흔하다. 상한을 못 박아 둔다.

/etc/systemd/journald.conf.d/size.conf

[Journal]
SystemMaxUse=1G
MaxRetentionSec=1month
터미널 창
sudo systemctl restart systemd-journald
터미널 창
cat /etc/logrotate.conf
ls /etc/logrotate.d/ # 패키지마다 규칙 하나씩
sudo logrotate -d /etc/logrotate.d/nginx # 시뮬레이션 (-d = dry run) ← 먼저 이걸로
sudo logrotate -f /etc/logrotate.d/nginx # 강제 실행

직접 쓰는 규칙은 이 정도면 충분하다.

/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
알고 싶은 것명령
서비스가 왜 안 뜨나journalctl -u <유닛> -b --no-pager | tail -50
갑자기 재부팅된 이유journalctl -b -1 -e · journalctl -k -b -1 | grep -i -E "oom|panic"
이 시간대에 무슨 일이journalctl --since "09:50" --until "10:10"
누가 로그인했나/var/log/auth.log · journalctl -u ssh (11장)
누가 패키지를 깔았나/var/log/apt/history.log · /var/log/dpkg.log
하드웨어·디스크 오류sudo dmesg -T -l err
자동 업데이트가 뭘 했나/var/log/unattended-upgrades/
  • journal은 바이너리다 — grep 대신 -u · -b · -p · --since 필터로 좁힌다
  • -b -1(직전 부팅)이 갑작스러운 재부팅 조사의 핵심 옵션이다
  • 유닛을 모르면 _COMM= · _PID= 같은 필드 필터로 찾는다
  • 텍스트 로그는 syslog · auth.log · apt/history.log가 실무의 3대장
  • dmesg는 root 권한이 필요하고 링 버퍼라 밀려 사라진다 — 과거는 journalctl -k
  • 저널 상한(SystemMaxUse)은 기본값이 없다 — 직접 걸어 둔다
  • 로테이션 후 로그가 멈추면 copytruncate 또는 postrotate reload