고급 Systemd Journald 문제 해결 기술
시간 필터, 부트 선택, 유닛 쿼리, 우선순위 수준 및 내보내기를 사용하여 systemd 저널 로그를 문제 해결합니다.
고급 Systemd Journald 문제 해결 기술
systemd 기반 Linux 호스트를 디버깅할 때는 종종 저널에서 시작합니다. journalctl -xe는 최근 실패를 보여줄 수 있지만, 실제 문제 해결은 일반적으로 부트, 시간 범위, 유닛, 우선순위, 프로세스 또는 실행 파일별로 로그를 좁히는 것을 의미합니다.
아래 예제는 서비스 실패, 부트 문제 및 반복되는 시스템 오류 중에 사용할 수 있는 집중된 보기로 대용량 저널을 변환하는 방법을 보여줍니다.
저널 이해: 구조 및 위치
systemd 저널은 커널, 시스템 서비스 및 애플리케이션의 로그를 집계합니다. 기존 syslog 파일과 달리 저널은 인덱싱된 바이너리 형식으로 로그를 저장하므로 journalctl을 통한 정교한 쿼리가 가능합니다. 로그는 일반적으로 /var/log/journal/과 같은 디렉토리에 저장됩니다.
기억해야 할 주요 개념:
- 구조화된 로깅: 항목에는
journalctl이 필터링에 사용하는 메타데이터 필드(_PID,_COMM,_SYSTEMD_UNIT등)가 포함됩니다. - 휘발성 vs. 영구적: 로그는 메모리에만 저장(휘발성)되거나 디스크에 기록(영구적)될 수 있습니다. 기본 구성은 일반적으로 영구 저장을 선호합니다.
필수 고급 필터링 기술
journalctl의 강점은 수백만 개의 로그 항목을 좁힐 수 있는 능력에 있습니다. 다음은 가장 효과적인 고급 필터입니다.
1. 시간 기반 필터링
시간 범위는 일시적인 문제나 성능 저하를 진단할 때 중요합니다. 절대 형식 또는 상대 앵커를 사용하여 시간을 지정할 수 있습니다.
A. 상대 시간: 상대 시간 지정에는 -S(이후) 및 -U(이전)를 사용합니다.
# 지난 30분 동안의 로그 표시
journalctl --since "30 minutes ago"
# 어제 오전 10시부터 현재까지의 로그 표시
journalctl -S yesterday -U now
# 특정 시간 범위의 로그 표시 (ISO 8601 형식)
journalctl --since "2024-05-01 08:00:00" --until "2024-05-01 08:15:00"
B. 부트 기반 시간: 특정 문제가 있는 부트 시퀀스를 분석하려면 -b 플래그를 사용합니다.
# 현재 부트의 로그만 표시
journalctl -b
# 이전 부트의 로그 표시
journalctl -b -1
# 마지막 이전 부트의 커널 로그 표시
journalctl -b -2 -k
2. Systemd 유닛 및 서비스별 필터링
특정 서비스에 속하는 로그를 분리하려면 -u 또는 --unit 플래그를 사용합니다. 이는 실패한 서비스를 문제 해결할 때 필수적입니다.
# Apache 웹 서버 서비스의 모든 로그 표시
journalctl -u httpd.service
# 서비스가 마지막으로 시작된 이후의 로그 표시
journalctl -u nginx.service --since "start of job -1"
3. 프로세스 ID(PID) 및 실행 파일 이름별 필터링
특정 프로세스가 충돌했지만 어떤 서비스가 소유하고 있는지 즉시 알 수 없는 경우 PID 또는 실행 파일 이름(_COMM)으로 필터링하는 것이 매우 효과적입니다.
# 특정 프로세스 ID(예: PID 4589)와 관련된 로그 표시
journalctl _PID=4589
# 'mysqld'라는 이름의 모든 프로세스에 대한 로그 표시
journalctl _COMM=mysqld
4. 우선순위 수준별 필터링
저널 항목에는 숫자 우선순위(0=긴급, 7=디버그)가 할당됩니다. -p 플래그를 사용하여 심각도별로 필터링하면 오류를 찾을 때 과도한 디버그 출력을 억제하는 데 도움이 됩니다.
| 우선순위 수준 | 키워드 | 숫자 값 |
|---|---|---|
| 긴급 | emerg | 0 |
| 경보 | alert | 1 |
| 치명적 | crit | 2 |
| 오류 | err | 3 |
| 경고 | warning | 4 |
| 알림 | notice | 5 |
| 정보 | info | 6 |
| 디버그 | debug | 7 |
# 시스템에 대한 치명적 오류(수준 2) 이상만 표시
journalctl -p crit
# 디버그 메시지를 제외한 모든 로그 표시
journalctl -p 6
부트 실패 및 커널 메시지 분석
시스템 시작 문제를 해결하려면 사용자 공간 서비스 실패와 커널 또는 하드웨어 초기화 문제를 분리해야 합니다.
커널 메시지 분리(-k 또는 --dmesg)
-k 플래그는 커널 메시지만 표시합니다(dmesg 실행과 동일). 이는 systemd가 서비스를 로드하기 전에 장치 드라이버, 하드웨어 인식 또는 초기 초기화 실패와 관련된 문제를 식별하는 데 중요합니다.
# 현재 부트의 모든 커널 메시지 검토
journalctl -k
# 이전 부트의 커널 로그에서 특정 하드웨어 오류 찾기
journalctl -k -b -1 | grep -i "error"
서비스 종속성 추적
서비스가 시작에 실패하면 상위 종속성이 실패했기 때문일 수 있습니다. 역순 표시(-r)와 유닛 필터링을 결합하여 실패로 이어지는 시퀀스를 확인합니다.
# 유닛의 로그를 역시간순으로 표시
journalctl -u my-app.service -r
고급 출력 형식 지정 및 내보내기
심층 분석 또는 로그 공유를 위해 출력 형식을 수정하는 것이 필수적입니다.
1. JSON으로 보기(-o json)
스크립팅 또는 외부 로그 분석 도구와의 통합을 위해 구조화된 JSON 출력이 선호됩니다.
journalctl -u sshd.service -o json
2. 단일 행으로 보기(-o cat)
타임스탬프나 메타데이터 없이 깨끗하고 원시적인 출력을 얻으려면(다른 도구(예: grep)로 직접 파이프할 때 유용) cat 형식을 사용합니다.
journalctl -u cron.service -o cat
3. 로그 내보내기
로그를 보관하거나 전송하려면 표준 텍스트 파일로 내보냅니다. 특정 메타데이터 필드가 필요한 경우 구조화된 필드를 포함하는 출력 형식을 선택합니다.
# 현재 부트의 모든 로그를 텍스트 파일로 내보내기
journalctl -b > boot_log_$(date +%F).txt
# 하나의 유닛에 대해 선택한 구조화된 필드 내보내기
journalctl -u mariadb.service -o json --output-fields=__REALTIME_TIMESTAMP,PRIORITY,_PID,_COMM,MESSAGE --since today > mariadb_recent.json
저널 관리 모범 사례
특히 로그 볼륨이 많은 시스템에서 디스크 공간 부족을 방지하려면 저널 크기를 관리하는 것이 중요합니다.
- 사용량 확인: 현재 저널 디스크 소비량 확인:
journalctl --disk-usage - 오래된 로그 정리:
vacuum명령을 사용하여 시간 또는 디스크 사용량별로 저널 크기 제한:# 지난 7일 동안의 로그만 유지 sudo journalctl --vacuum-time=7d # 디스크 사용량을 최대 500MB로 줄이기 sudo journalctl --vacuum-size=500M
저널 필터를 좁히는 도구로 사용하십시오. 먼저 부트, 시간 창, 유닛 및 우선순위를 선택한 다음 결과를 보관하거나 구문 분석해야 할 때만 출력 형식을 변경하십시오.