고급 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
    

저널 필터를 좁히는 도구로 사용하십시오. 먼저 부트, 시간 창, 유닛 및 우선순위를 선택한 다음 결과를 보관하거나 구문 분석해야 할 때만 출력 형식을 변경하십시오.