스크립트에서 journalctl로 journald 조회
자동화된 인시던트 분류를 위해 유닛, 우선순위 및 시간별로 systemd 저널 항목을 필터링합니다.
스크립트에서 journalctl로 journald 조회은(는) CoddyKit의 무료 DevOps Bootcamp 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 DevOps Bootcamp 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. DevOps Bootcamp 강의에는 총 4개의 강의가 포함되어 있습니다.
사고 분류에 journald를 사용하는 이유
systemd를 실행하는 최신 Linux 시스템은 모든 로그 출력을 저널이라는 systemd-journald가 관리하는 구조화된 바이너리 로그 저장소에 중앙 집중화합니다. /var/log의 일반 텍스트 파일과 달리 모든 저널 항목에는 유닛 이름, 우선순위 수준, PID, UID, 타임스탬프 등의 풍부한 메타데이터가 포함됩니다.
자동화된 사고 분류 스크립트에서는 이 메타데이터를 사용하여 다음을 수행할 수 있습니다.
grep체인 없이 로그를 하나의 서비스로 필터링합니다.- 쿼리 범위를 정확한 시간 구간으로 제한합니다(최근 15분, 배포 이후 등).
- 중요 또는 오류 메시지만 출력하고 불필요한 내용을 무시합니다.
- 구조화된 출력을 경고 파이프라인에 직접 전달합니다.
이 모든 기능을 제공하는 도구가 journalctl입니다. 이 강의에서는 Bash 스크립트 안에서 이 도구를 프로그래밍 방식으로 사용하는 방법을 배웁니다.
journalctl 기본 호출
가장 단순한 형태의 journalctl은 전체 저널을 출력합니다. 스크립트에서는 거의 항상 이를 원하지 않으므로 최소한 하나의 필터를 추가해야 합니다. 다음은 함께 연결하여 사용하는 가장 일반적인 플래그입니다.
-u <unit>— systemd 유닛으로 필터링(예:nginx.service)-p <priority>— syslog 우선순위로 필터링(0=emerg … 7=debug)--since/--until— 시간 구간-n <N>— 마지막 N개 행--no-pager— 대화형 페이지 표시를 비활성화합니다(스크립트에서 필수).-o <format>— 출력 형식(short,json,cat등)
대화형이 아닌 스크립트에서는 항상 --no-pager를 전달하여 journalctl이 less를 호출하려다 멈추지 않도록 해야 합니다.
#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20Systemd 유닛으로 필터링하기
-u 플래그에는 유효한 유닛 이름을 사용할 수 있습니다. 여러 번 지정하여 유닛을 결합할 수도 있는데, 하나의 애플리케이션이 여러 서비스에 걸쳐 있을 때 유용합니다(예: API와 해당 데이터베이스 사이드카).
유닛 이름은 <name>.service, <name>.socket, <name>.timer 등의 패턴을 따릅니다. 와일드카드도 지원됩니다. -u 'myapp*'는 myapp-api.service, myapp-worker.service 등을 일치시킵니다.
사고 분류 스크립트에서는 일반적으로 유닛 이름을 인수로 받으므로 필터가 동적으로 결정됩니다.
#!/usr/bin/env bash
# Usage: ./unit_logs.sh nginx.service
UNIT="${1:?Usage: $0 <unit>}"
echo "=== Journal for ${UNIT} (last 50 lines) ==="
journalctl --no-pager -u "${UNIT}" -n 50
# Combine two related units
echo "=== Combined: api + worker ==="
journalctl --no-pager -u myapp-api.service -u myapp-worker.service -n 30우선순위 수준과 -p 플래그
-p 플래그는 표준 syslog 우선순위 수준에 매핑됩니다:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
단일 수준(-p err)을 지정하면 해당 수준만 확인할 수 있고, 범위(-p emerg..err)를 지정하면 emergency부터 errors까지 모두 수집할 수 있습니다. 이는 자동화된 알림에서 가장 일반적으로 선택하는 방식입니다.
이름으로 된 별칭(err, warning, crit)은 숫자 값과 함께 사용할 수 있습니다.
#!/usr/bin/env bash
# Extract only error-level and above entries for sshd
journalctl --no-pager \
-u sshd.service \
-p emerg..err \
--since "1 hour ago"
# Exit non-zero if any errors were found (useful in CI health checks)
ERROR_COUNT=$(journalctl --no-pager -u sshd.service -p emerg..err \
--since "1 hour ago" --output=cat | wc -l)
if [[ "${ERROR_COUNT}" -gt 0 ]]; then
echo "[ALERT] ${ERROR_COUNT} error(s) detected in sshd" >&2
exit 1
fi--since 및 --until을 사용한 시간 범위 필터링
시간 필터는 장애 발생 시간대 쿼리의 핵심입니다. journalctl은 사람이 읽기 쉬운 다양한 형식의 타임스탬프를 허용합니다:
- 상대 시간:
"10 minutes ago","2 hours ago","yesterday" - 절대 시간:
"2026-06-11 14:00:00" - 특수 키워드:
today,yesterday,-1h(축약형)
배포 스크립트에서는 배포 직전의 타임스탬프를 저장한 다음, 해당 시점부터 저널을 조회하여 릴리스로 인해 발생한 회귀를 감지하는 방식이 일반적입니다.
#!/usr/bin/env bash
# Record deploy start time, then check logs afterwards
DEPLOY_START=$(date +"%Y-%m-%d %H:%M:%S")
echo "Deploying at ${DEPLOY_START}..."
# ... your deploy steps here ...
sleep 2 # simulate deploy
echo "=== Journal since deploy start ==="
journalctl --no-pager \
-u myapp.service \
--since "${DEPLOY_START}" \
-p emerg..warningJSON 형식의 구조화된 출력
기계가 읽을 수 있는 파이프라인에서는 -o json(줄마다 하나의 JSON 객체, NDJSON) 또는 -o json-pretty(서식 지정)를 전달합니다. 각 객체에는 모든 저널 필드가 포함됩니다:
MESSAGE— 로그 텍스트PRIORITY— 숫자로 표시된 우선순위(0–7)_SYSTEMD_UNIT— 원본 단위__REALTIME_TIMESTAMP— 에포크 이후의 마이크로초_PID,_UID,_HOSTNAME— 프로세스 메타데이터
이 NDJSON 스트림을 jq로 파이프하여 필드를 추출, 필터링하거나 형식을 다시 지정한 뒤 PagerDuty, Slack 웹훅 또는 SIEM 수집기와 같은 후속 알림 시스템으로 보낼 수 있습니다.
#!/usr/bin/env bash
# Extract error messages as a clean list for a Slack notification
MESSAGES=$(journalctl --no-pager \
-u nginx.service \
-p emerg..err \
--since "30 minutes ago" \
-o json \
| jq -r '.MESSAGE' \
| sort -u)
if [[ -n "${MESSAGES}" ]]; then
echo "Errors detected:"
echo "${MESSAGES}"
fi저널을 실시간으로 추적하기
-f 플래그를 사용하면 journalctl이 저널의 끝부분을 실시간으로 추적합니다. 이는 로그 파일에서 tail -f를 사용하는 것과 비슷합니다. 단위 및 우선순위 필터와 함께 사용하면 대상이 명확한 실시간 모니터가 됩니다.
스크립트로 구성된 파이프라인에서는 커서 기반 폴링이 더 유용한 방식입니다. 현재 저널 커서를 저장한 다음, 폴링할 때마다 --after-cursor=<cursor>를 전달하여 마지막 확인 이후의 새 항목만 읽습니다. 이렇게 하면 이전 줄을 다시 처리하지 않아도 됩니다.
--show-cursor -n 0으로 최신 커서를 가져온 다음 출력에서 -- cursor: 줄을 분석합니다.
#!/usr/bin/env bash
# Cursor-based polling: read only new journal entries each run
CURSOR_FILE="/tmp/triage_cursor"
if [[ -f "${CURSOR_FILE}" ]]; then
CURSOR=$(cat "${CURSOR_FILE}")
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--after-cursor="${CURSOR}" \
-o json)
else
# First run: look back 5 minutes
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--since "5 minutes ago" \
-o json)
fi
# Save updated cursor for next poll
journalctl --no-pager -n 0 --show-cursor 2>&1 \
| grep '^-- cursor:' \
| sed 's/-- cursor: //' \
> "${CURSOR_FILE}"
echo "${NEW_ENTRIES}" | jq -r '.MESSAGE // empty'-b를 사용한 부팅 세션 범위 쿼리
-b 플래그는 쿼리 범위를 특정 부팅 세션으로 제한합니다. 충돌 또는 예기치 않은 재부팅 이후 현재 부팅이 아닌 이전 부팅의 로그를 가져올 때 필수적입니다.
-b 0— 현재 부팅(기본값)-b -1— 이전 부팅-b -2— 두 번 전 부팅--list-boots— 타임스탬프와 함께 기록된 모든 부팅 세션 표시
사후 분석 스크립트에서는 시스템이 충돌했거나 서비스가 시작 시 실패한 이유를 진단하기 위해 이전 부팅(-b -1)의 중요한 로그를 덤프하는 경우가 많습니다.
#!/usr/bin/env bash
# Post-mortem: collect critical logs from the previous boot
echo "=== Previous boot sessions ==="
journalctl --list-boots
echo ""
echo "=== Critical entries from previous boot ==="
journalctl --no-pager \
-b -1 \
-p emerg..crit \
-o short-isojournalctl 내부 grep과 기본 일치 기능 비교
모든 플래그 뒤에 원시 grep 패턴을 전달할 수 있지만, journalctl은 FIELD=value 구문을 사용한 기본 필드 일치도 지원합니다. 기본 일치는 구조화된 메타데이터를 대상으로 평가되므로 grep으로 텍스트를 후처리하는 것보다 훨씬 빠릅니다.
자주 사용하는 일치 조건은 다음과 같습니다:
_PID=1234— 특정 프로세스의 로그_COMM=python3— 이름이python3인 모든 프로세스의 로그SYSLOG_IDENTIFIER=myapp— 사용자 지정 식별자가 붙은 로그
여러 FIELD=value 인수는 AND 조건으로 결합되고, 인수 사이에 +를 넣으면 OR 조건이 됩니다. 구조화된 메타데이터만으로 부족할 때는 -g <regex>를 사용하여 전체 텍스트를 grep하십시오.
#!/usr/bin/env bash
# Native field match: errors from the postgres process only
journalctl --no-pager \
_COMM=postgres \
-p emerg..err \
--since "1 hour ago"
# Full-text grep for a specific error string
journalctl --no-pager \
-u postgresql.service \
--since "1 hour ago" \
-g "FATAL|PANIC" \
--output=cat재사용 가능한 분류 함수 만들기
개별 플래그를 익힌 후 이를 재사용 가능한 Bash 함수로 조합하면 분류 스크립트를 깔끔하고 일관되게 유지할 수 있습니다. 잘 설계된 함수는 다음을 수행해야 합니다:
- 단위, 우선순위 범위 및 시간 범위를 매개변수로 받습니다
- 인수가 생략되면 안전하고 잡음이 적은 값으로 기본 설정합니다
- errors가 발견되면 0이 아닌 종료 코드를 반환합니다(CI 파이프라인과 통합)
- 감사 추적을 위해 발견 결과를 표준 출력과 타임스탬프가 포함된 로그 파일 양쪽에 기록합니다
#!/usr/bin/env bash
# triage.sh — reusable journal triage function
triage_unit() {
local unit="${1:?unit required}"
local priority="${2:-emerg..err}"
local since="${3:-1 hour ago}"
local logfile="/tmp/triage_${unit//[^a-zA-Z0-9]/_}_$(date +%s).log"
echo "[$(date -Iseconds)] Triaging ${unit} | prio=${priority} | since='${since}'" | tee "${logfile}"
journalctl --no-pager \
-u "${unit}" \
-p "${priority}" \
--since "${since}" \
-o short-iso \
| tee -a "${logfile}"
local count
count=$(wc -l < "${logfile}")
# Subtract 1 for the header line
(( count-- ))
if [[ "${count}" -gt 0 ]]; then
echo "[ALERT] ${count} line(s) logged to ${logfile}" >&2
return 1
fi
return 0
}
# Example: triage nginx errors in the last 30 minutes
triage_unit nginx.service "emerg..err" "30 minutes ago"자동화된 장애 분류 스크립트
다음 전체 스크립트는 모든 개념을 실용적인 자동화 분류 도구로 통합합니다. 구성 가능한 조회 기간 동안 중요한 서비스 목록을 읽고 각 서비스의 저널을 조회하며, 발견 결과를 집계하고, errors가 하나라도 감지되면 실패 코드를 반환합니다. 따라서 cron 작업이나 CI 상태 확인 단계에 적합합니다.
#!/usr/bin/env bash
# incident_triage.sh — automated multi-service journal triage
set -euo pipefail
LOOKBACK="${1:-15 minutes ago}"
PRIORITY="emerg..err"
SERVICES=(nginx.service postgresql.service myapp-api.service myapp-worker.service)
REPORT="/tmp/incident_report_$(date +%Y%m%d_%H%M%S).txt"
FAILED=0
{
echo "Incident Triage Report"
echo "Generated : $(date -Iseconds)"
echo "Lookback : ${LOOKBACK}"
echo "Priority : ${PRIORITY}"
echo "-----------------------------------"
} > "${REPORT}"
for svc in "${SERVICES[@]}"; do
ENTRIES=$(journalctl --no-pager \
-u "${svc}" \
-p "${PRIORITY}" \
--since "${LOOKBACK}" \
--output=cat 2>/dev/null || true)
COUNT=$(echo "${ENTRIES}" | grep -c . || true)
if [[ "${COUNT}" -gt 0 ]]; then
echo "[FAIL] ${svc}: ${COUNT} error(s)" | tee -a "${REPORT}"
echo "${ENTRIES}" >> "${REPORT}"
echo "-----------------------------------" >> "${REPORT}"
FAILED=1
else
echo "[OK] ${svc}"
fi
done
echo ""
echo "Full report: ${REPORT}"
exit "${FAILED}"지식 확인: 우선순위 범위 필터링
서비스가 error 수준 이상(즉, error, critical, alert 또는 emergency)의 메시지를 기록한 경우에만 당직 엔지니어에게 알림을 보내는 스크립트를 작성하고 있습니다. 정확히 해당 범위를 수집하는 journalctl 플래그 조합은 무엇입니까?
레슨 요약: 스크립트에서 journalctl 사용하기
이 레슨에서는 자동화된 장애 분류를 위해 systemd 저널을 프로그래밍 방식으로 조회하는 방법을 배웠습니다:
- 항상 스크립트에서
--no-pager를 전달하십시오. 대화형 대기로 인해 작업이 차단되는 것을 방지할 수 있습니다. - 단위 필터링(
-u)은 쿼리 범위를 하나 이상의 서비스로 제한합니다. 글롭과 여러-u플래그를 지원합니다. - 우선순위 필터링(
-p emerg..err)은 필요한 심각도 수준만 수집합니다. 숫자가 낮을수록 더 심각하다는 점을 기억하십시오. - 시간 범위(
--since/--until)는 사람이 읽기 쉬운 타임스탬프를 사용하여 로그 출력을 배포 시간대 또는 조회 기간으로 제한합니다. - 부팅 범위 지정(
-b -1)을 사용하면 사후 분석 스크립트에서 이전 충돌 세션의 로그를 읽을 수 있습니다. - JSON 출력(
-o json)과jq를 사용하면 알림 또는 SIEM 시스템으로 전달되는 구조화된 파이프라인을 구성할 수 있습니다. - 커서 기반 폴링에서
--after-cursor를 사용하면 반복 실행 시 이전 항목을 다시 처리하지 않습니다. - 기본 필드 일치(
_COMM=,SYSLOG_IDENTIFIER=)는grep으로 파이프하는 것보다 빠릅니다.
이러한 플래그를 재사용 가능한 Bash 함수 안에서 조합하면 cron, CI 파이프라인 및 당직 알림 작업 흐름에 깔끔하게 통합되는 운영 수준의 분류 도구를 만들 수 있습니다.
자주 묻는 질문
“스크립트에서 journalctl로 journald 조회” 강의는 무료인가요?
네 — “스크립트에서 journalctl로 journald 조회” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 DevOps Bootcamp 강의 전체를 잠금 해제할 수 있습니다. DevOps Bootcamp 강의에는 총 4개의 강의가 포함되어 있습니다.
“스크립트에서 journalctl로 journald 조회”에서 뭘 배우나요?
자동화된 인시던트 분류를 위해 유닛, 우선순위 및 시간별로 systemd 저널 항목을 필터링합니다. 브라우저에서 직접 실행하는 실습 코드로 DevOps Bootcamp을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
DevOps Bootcamp을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 DevOps Bootcamp은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“스크립트에서 journalctl로 journald 조회” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 DevOps Bootcamp 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 DevOps Bootcamp 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 대규모 웹 및 애플리케이션 로그 분석
- 실시간 로그 추적 및 스트리밍 알림
- 스크립트에서 journalctl로 journald 조회
- 로그 스트림에서 지표 및 히스토그램 계산