나의 잡다한 노트 및 메모

정형화된 로그 스키마 예시 본문

DevOps

정형화된 로그 스키마 예시

peanutwalnut 2025. 5. 31. 16:32
{
  "timestamp": "2025-05-31T18:42:15.123Z",
  "level": "ERROR",
  "service": "order-service",
  "environment": "production",
  "instance_id": "order-service-3fd8b6c4",
  "host": "app-node-12.mofl.internal",
  "trace_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "span_id": "a7d1c2e3",
  "request_id": "9f1c3b2e-4d5f-6a7b-8c9d-0e1f2a3b4c5d",
  "user_id": "alice",
  "http": {
    "method": "POST",
    "path": "/api/v1/orders",
    "status_code": 504,
    "remote_ip": "203.0.113.45",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)…"
  },
  "db": {
    "query": "INSERT INTO orders (user_id, total_amount) VALUES ($1, $2)",
    "duration_ms": 1250,
    "rows_returned": 0
  },
  "error": {
    "type": "TimeoutError",
    "message": "결제 서비스 응답 지연으로 타임아웃 발생",
    "stack_trace": "com.mofl.payment.TimeoutException: ... (간략화)"
  },
  "message": "결제 처리 중 타임아웃 발생",
  "duration_ms": 15000,
  "tags": {
    "feature_flag": "new-checkout-flow-v2",
    "region": "asia-seoul-1"
  }
}

주요 필드(스키마) 설명

아래 항목들은 대부분의 마이크로서비스/분산 시스템 환경에서 최소한으로 갖추면 좋거나, 확장이 용이한 구조입니다. 실제로는 조직·서비스 규모, 모니터링/트레이싱 시스템(Jaeger, Zipkin, Datadog APM 등)과 연동 방식을 고려해, 필요에 맞게 필드를 추가하거나 제거할 수 있습니다.

  1. timestamp
    • 형식: ISO 8601 (예: 2025-05-31T18:42:15.123Z)
    • 설명: 로그가 발생한 시점을 UTC 기준으로 표기합니다.
    • 이유: 분산 시스템에서 여러 호스트 간 타임라인 정렬이 필요하기 때문에, 반드시 밀리초 단위까지 포함한 ISO 8601 형식을 사용하는 것이 좋습니다.
  2. level
    • 형식: 문자열 (예: DEBUG / INFO / WARN / ERROR / FATAL)
    • 설명: 로그 심각도(Severity).
    • 이유: 필드별 색인(Indexing)을 통해 “level = ERROR” 같은 필터링 및 집계가 가능합니다.
    • Tip: 프로덕션에서는 INFO 이하 메시지는 로그 수집기에서 샘플링하거나, 낮은 빈도로 보관하고, WARN / ERROR 이상의 로그는 장기 보관하도록 정책을 세우면 좋습니다.
  3. service
    • 형식: 문자열 (예: order-service, payment-service, user-service 등)
    • 설명: 로그를 남긴 애플리케이션(또는 마이크로서비스)의 이름.
    • 이유: 여러 서비스가 하나의 로그 저장소(예: Elasticsearch)로 전송될 때, Kibana나 Grafana 대시보드에서 특정 서비스만 빠르게 조회할 수 있도록 해줍니다.
  4. environment
    • 형식: 문자열 (예: development / staging / production)
    • 설명: 로그가 생성된 환경.
    • 이유: 프로덕션/스테이징/개발 환경을 구분해서 모니터링·경고 임계치를 다르게 관리할 수 있습니다.
  5. instance_id (또는 pod, container, VM ID 등)
    • 형식: 문자열 (예: order-service-3fd8b6c4, user-api-pod-5a2f 등)
    • 설명: 해당 애플리케이션 인스턴스의 고유 ID.
    • 이유: 로깅 파이프라인에서 “동일 서비스 내 여러 복제본” 중 어느 인스턴스에서 찍힌 로그인지 구분할 수 있어, 문제 발생 시 특정 인스턴스의 메트릭·로그를 집중 분석할 수 있습니다.
  6. host
    • 형식: 문자열 (예: app-node-12.mofl.internal, vm-23.seoul.cloud)
    • 설명: 물리적/가상 머신 호스트 이름 또는 IP.
    • 이유: Kubernetes 환경이라면 pod_name이나 node_name으로 대체될 수 있지만, VM 또는 베어메탈 환경에서는 호스트 이름을 기록하여 운영팀이 어느 노드에서 문제가 발생했는지 추적할 수 있어야 합니다.
  7. trace_id, span_id
    • 형식: 문자열 (UUID 또는 16진수)
    • 설명: 분산 추적(Distributed Tracing)에서 요청의 전체 경로를 추적하기 위한 고유 식별자(trace_id)와, 해당 로그가 속한 스팬(span_id).
    • 이유: 마이크로서비스 호출 간 요청이동(call chain)을 추적하여, 각각의 서비스에서 얼마나 시간이 소요됐는지, 어디서 병목이 발생했는지 정확하게 파악할 수 있습니다.
  8. request_id
    • 형식: 문자열 (예: UUID)
    • 설명: 클라이언트가 보낸 단일 HTTP/GRPC 요청에 대한 고유 ID.
    • 이유: trace_id/ span_id와 달리, 요청자(클라이언트) 입장에서 하나의 트랜잭션을 구분하는 용도로 사용합니다. 외부 요청·내부 작업(job·batch) 등 여러 케이스를 구분할 때 유용합니다.
  9. user_id (또는 actor_id)
    • 형식: 문자열 (예: alice, user-1234, 혹은 익명 사용자는 anonymous)
    • 설명: 로그와 연관된 사용자의 고유 식별자.
    • 이유: 보안 감사나 사용자별 트랜잭션 분석, 이상 행위 감지 등에 활용할 수 있습니다.
  10. message
    • 형식: 문자열 (예: "결제 처리 중 타임아웃 발생")
    • 설명: 사람이 읽기 쉬운 주요 이벤트 요약 메시지.
    • 이유: Kibana/Grafana 탐색 시 “핵심 메시지”를 한눈에 볼 수 있도록 도와줍니다.
    • Tip: 너무 장황하게 남기지 말고, “무슨 일이 발생했는지”를 한 문장으로 요약하는 것이 좋습니다.
  11. duration_ms (또는 latency_ms)
    • 형식: 숫자 (밀리초 단위)
    • 설명: 해당 로그 이벤트(트랜잭션) 전체 처리에 걸린 시간.
    • 이유: “느린 요청”을 필터링하거나, 평균 응답 시간, p95/p99 latency 지표 산출 시 유용합니다.

'DevOps' 카테고리의 다른 글

API Gateway란  (0) 2025.05.31
request_id, trace_id, span_id 에 대한 구분  (0) 2025.05.31
운영 서비스 이관 전략 중 일부 설명  (0) 2025.03.30
Locale 이란?  (0) 2025.02.12
직렬화와 역직렬화  (2) 2024.12.25