리눅스 journalctl 명령어 사용법 - systemd 로그 조회와 필터
이 명령어를 언제 쓰는가
서비스가 failed 상태인데 systemctl status가 보여주는 로그 10줄로는 원인을 알 수 없을 때, 새벽에 서버가 재부팅된 이유를 찾을 때, OOM Killer가 어떤 프로세스를 죽였는지 확인할 때 쓴다.
systemd를 쓰는 배포판에서는 커널 메시지, 서비스 표준출력, sshd 인증 기록이 모두 저널이라는 한 곳에 바이너리로 쌓인다. /var/log의 텍스트 파일만 뒤지다가 "로그가 없다"고 결론 내리는 경우가 많은데, 사실은 저널에 다 있다.
기본 형식
journalctl [필터 옵션...] [출력 옵션...]
- 인자 없이 실행하면 가장 오래된 로그부터 전부 페이저로 띄운다. 실무에서 그대로 쓰는 일은 거의 없고, 항상 대상(-u)과 시간(--since)으로 좁혀서 쓴다.
- 다른 사람의 로그와 시스템 로그를 보려면 root 권한 또는
systemd-journal·adm그룹 소속이 필요하다. - 여러 필터를 함께 쓰면 AND로 결합된다. 같은 종류를 여러 번 쓰면 OR이다.
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
-u 유닛 | 특정 서비스의 로그만 | journalctl -u nginx |
-f | 실시간으로 따라가기(tail -f) | journalctl -u myapp -f |
-n 줄수 | 마지막 N줄만(기본 10) | journalctl -u myapp -n 100 |
--since / --until | 시간 범위. 사람이 읽는 표현을 받는다 | --since "2026-08-25 09:00" --until "10:00" |
-p 레벨 | 우선순위 이상만. err, warning, crit 등 | journalctl -p err -b |
-b | 이번 부팅 이후. -b -1은 직전 부팅 | journalctl -b -1 -p err |
-k | 커널 메시지만(dmesg 대응) | journalctl -k -b |
-t 태그 | syslog 식별자로 필터 | journalctl -t sudo |
_PID=, _UID= | 필드 기반 정밀 필터 | journalctl _UID=1001 |
-o 형식 | 출력 형식. short-iso, json, cat 등 | journalctl -u myapp -o short-iso |
--no-pager | 페이저 없이 그대로 출력(스크립트·파이프용) | journalctl -u myapp -n 50 --no-pager |
--disk-usage | 저널이 차지한 디스크 용량 | journalctl --disk-usage |
--vacuum-time / --vacuum-size | 오래된 저널 정리 | sudo journalctl --vacuum-time=7d |
실전 예제
1. 죽은 서비스의 마지막 로그를 본다. 장애 대응에서 가장 먼저 치는 형태다.
$ sudo journalctl -u myapp -n 50 --no-pager
Aug 25 11:20:03 web01 systemd[1]: Started My Application.
Aug 25 11:20:03 web01 myapp[4812]: FATAL: config file /etc/myapp/app.yml not found
Aug 25 11:20:03 web01 systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Aug 25 11:20:03 web01 systemd[1]: myapp.service: Failed with result 'exit-code'.
2. 장애 시간대만 잘라서 본다. 알림이 09:40에 왔다면 앞뒤로 여유를 두고 자른다.
sudo journalctl --since "2026-08-25 09:30" --until "2026-08-25 09:50" -p warning --no-pager
sudo journalctl -u nginx --since "1 hour ago"
sudo journalctl --since yesterday --until today -p err
3. 서버가 갑자기 재부팅된 원인을 찾는다. 직전 부팅의 마지막 로그에 정전·커널 패닉·OOM의 흔적이 남는다.
journalctl --list-boots
sudo journalctl -b -1 -n 100 --no-pager
sudo journalctl -k -b -1 | grep -i -E 'oom|killed process|panic'
메모리 부족으로 프로세스가 죽었다면 커널 로그에 Out of memory: Killed process 4812 (java) 형태로 남는다.
4. 배포 직후 로그를 실시간으로 지켜본다.
sudo systemctl restart myapp && sudo journalctl -u myapp -f
여러 서비스를 함께 보려면 -u를 반복한다. OR로 묶인다.
sudo journalctl -u nginx -u myapp -f -o short-iso
5. SSH 로그인 실패를 추적한다. 무차별 대입 시도가 있는지 확인할 때 쓴다.
sudo journalctl -u ssh --since today | grep 'Failed password'
유닛 이름이 배포판마다 다르다. Ubuntu/Debian은 ssh, RHEL/CentOS 계열은 sshd다.
6. 저널이 디스크를 잡아먹을 때 정리한다. 디스크 풀 장애 대응에서 자주 쓴다.
$ journalctl --disk-usage
Archived and active journals take up 3.8G in the file system.
$ sudo journalctl --vacuum-time=7d
$ sudo journalctl --vacuum-size=500M
영구 설정은 /etc/systemd/journald.conf의 SystemMaxUse=1G를 지정한 뒤 sudo systemctl restart systemd-journald로 반영한다.
함정과 주의점
- 재부팅하면 로그가 사라지는 서버가 있다.
/var/log/journal디렉터리가 없으면 저널은/run/log/journal(메모리)에만 쌓이고 재부팅 시 전부 날아간다. Debian 계열 기본값이 이럴 수 있다.journalctl --list-boots에 이번 부팅만 나온다면 이 상태다. 영구 저장으로 바꾸려면 다음과 같이 한다.sudo mkdir -p /var/log/journal sudo systemd-tmpfiles --create --prefix /var/log/journal sudo systemctl restart systemd-journald grep을 붙일 때--no-pager를 빼면 출력이 잘리거나 멈춘 것처럼 보인다. 파이프로 넘기면 대개 페이저가 자동으로 빠지지만, 색상·터미널 설정에 따라 이상하게 동작하는 경우가 있다. 스크립트에서는 항상--no-pager를 명시한다. 문자열 검색은 grep 대신-g 패턴(정규식 검색)을 쓸 수도 있다.- 시간 필터는 서버의 타임존을 따른다. UTC로 도는 서버에서
--since "09:00"은 한국 시간 18시다. 애매하면-o short-iso로 타임존이 함께 찍히는 형식을 쓰거나--utc를 붙여 기준을 통일한다.timedatectl로 서버 타임존을 먼저 확인하는 습관이 좋다. - 일반 사용자에게는 자기 로그만 보인다. sudo 없이 실행해서 아무것도 안 나오면 권한 문제다. 계정을
systemd-journal그룹(Debian 계열은adm도 가능)에 넣으면 sudo 없이 시스템 로그를 읽을 수 있다. - 애플리케이션이 파일로 직접 로그를 쓰면 저널에 없다. 저널에 남는 것은 표준출력·표준오류로 나온 내용이다. 애플리케이션이 자체 로그 파일을 쓴다면 그 경로를 따로 봐야 한다. 반대로 컨테이너·systemd 환경에서는 표준출력으로 내보내는 편이 관리가 쉽다.
함께 보면 좋은 명령어
systemctl status— 상태와 최근 로그를 한 화면에서 보는 진입점.dmesg -T— 커널 링버퍼를 직접 본다. 저널이 없는 환경에서도 동작한다.tail -f— 파일로 남는 애플리케이션 로그를 볼 때.timedatectl— 시간 필터가 어긋날 때 타임존을 확인한다.
필터 필드 이름과 시간 표현의 전체 목록은 journalctl 공식 문서에 정리되어 있다.