> For the complete documentation index, see [llms.txt](https://leehyokyun.gitbook.io/openbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://leehyokyun.gitbook.io/openbook/6-4..md).

# 6-4. 모니터링과 디버깅

모니터링 & 디버깅에 대하여

### 계측 목적별 데이터 수집

* 관측 대상 및 데이터 소스 정의 분산 환경에서 시스템을 안정적으로 운영하기 위해 관측 대상으로 무엇을 지정하고 어떠한 데이터 소스를 수집할 것인가에 대한 기준을 정의한다.
  * Tracing: 분산 트랜잭션의 요청 흐름 및 서비스 간 호출을 추적하여 어느 지점에서 병목이 일어나는지 파악한다.
  * Metric: 분산 트랜잭션 자체의 숫자 지표를 수집하여 전반적인 시스템의 현재 상태를 측정한다.
  * Log: 시스템 내부의 이벤트를 기록하여 구체적인 에러 메시지를 확인하고 디버깅하는 데 활용한다.

### 목적별 수집 및 시각화 도구의 역할

* Tracing 도구: Sleuth는 분산 트랜잭션 요청 시 TraceId 및 각 도메인별 SpanId를 생성하고 관리하며, MSA 간 호출 시 HTTP Header를 통해 이를 자동 전파하여 요청 단위의 고유 ID를 관리한다. Zipkin은 이러한 TraceId를 저장하고 조회할 수 있는 수집 및 UI 도구 역할을 수행한다.
* Metric 도구: MicroMeter는 분산 트랜잭션 시 시스템의 전체적인 상태 정보(CPU, TPS, API latency, 메모리 등)를 계측하는 센서 역할을 담당한다. Prometheus는 이렇게 계측한 Metric 정보를 Pull 방식(Scrap)으로 가져와 별도의 서버 시계열 DB에 저장한다. Grafana는 최종적으로 Scrap된 데이터 정보를 시각화하여 보여주는 UI 도구로 기능한다.
* Log 도구: ELK(Elasticsearch, Logstash, Kibana) 스택 등을 활용하여 로그 데이터를 수집, 인덱싱하고 시각화하여 조회한다.

### Actuator와 MicroMeter

* Spring Boot Actuator는 애플리케이션의 가동 상태, 모니터링 지표, 설정 정보 등을 HTTP 엔드포인트나 JMX를 통해 외부로 노출하여 관리할 수 있게 돕는 라이브러리이다. 다만 엔드포인트를 무분별하게 노출하면 민감한 설정 정보나 힙 덤프 등이 외부에 유출될 수 있으므로, 실운영 환경에서는 `/actuator/health`와 같이 필수적인 엔드포인트만 노출하고 나머지는 차단하거나 접근 권한을 철저히 제한하는 보안 설정이 필수적이다.
* MicroMeter는 애플리케이션의 핵심 메트릭(CPU, 메모리, 처리량 등)을 수집하여 프로메테우스와 같은 외부에 전달할 때, 다양한 모니터링 시스템의 규격에 맞게 데이터를 변환해 주는 추상화 레이어(인터페이스) 역할을 수행한다. 개발자는 모니터링 시스템이 변경되더라도 코드를 수정할 필요 없이 마이크로미터의 표준 인터페이스를 통해 일관된 방식으로 메트릭을 계측할 수 있다.

### Prometheus와 Grafana의 연동 메커니즘

* 프로메테우스의 데이터 수집 방식 (Pull 구조) 프로메테우스는 대상 애플리케이션이 수집한 메트릭 데이터를 직접 전송받는 Push 방식이 아니라, 프로메테우스 서버가 주기적으로 애플리케이션의 엔드포인트(예: `/actuator/prometheus`)에 접근하여 데이터를 긁어오는 Pull 방식을 채택한다. 타겟 서버에 과도한 Push 트래픽 부담을 주지 않고 프로메테우스 서버가 자신의 주기에 맞게 데이터를 안정적으로 Scrap하여 시계열 데이터베이스(TSDB)에 저장 관리한다.
* 그라파나의 시각화 원리 그라파나는 자체적으로 데이터를 저장하는 저장소가 아니라 시각화 전용 UI 도구이다. 프로메테우스를 데이터 소스(Data Source)로 등록한 후, 프로메테우스의 전용 쿼리 언어인 PromQL을 사용하여 시계열 데이터를 조회하고 이를 실시간 대시보드의 차트와 그래프 형태로 변환하여 모니터링 화면을 구성한다.

### 로깅 전략과 주의점 (MDC, 인덱싱)

* 대량 로그 적재 시 병목 원인과 해결 방안 로그를 파일에 쓰거나 네트워크를 통해 전송하는 작업은 I/O 비용이 매우 높은 작업이다. 대량의 트래픽이 몰리는 상황에서 모든 로그를 동기(Sync) 방식으로 처리하면 로깅 작업으로 인해 애플리케이션의 주 스레드가 블로킹되어 심각한 성능 저하와 병목 현상이 발생한다. 이를 해결하기 위해 AsyncAppender 등을 활용한 비동기 로깅 구조를 채택하여, 로그 메시지를 내부 버퍼 큐에 빠르게 밀어 넣고 별도의 워커 스레드가 이를 처리하도록 구성하여 메인 비즈니스 로직의 지연을 방지한다.
* MDC는 멀티스레드 환경에서 각 스레드별로 고유한 컨텍스트 정보를 유지하고 관리할 수 있도록 돕는 컴포넌트이며 내부적으로 ThreadLocal을 기반으로 동작한다. 분산 환경에서 클라이언트의 요청이 들어올 때 고유한 트레이스 ID를 MDC에 저장해 두면, 해당 요청을 처리하는 모든 로그 라인에 트레이스 ID가 자동으로 출력되어 수많은 로그 속에서 특정 요청의 흐름만 정확히 추적할 수 있다.&#x20;
  * 다만 스레드 풀을 사용하는 환경에서는 작업이 끝난 후 MDC의 컨텍스트 정보를 명확히 제거(`MDC.clear()`)하지 않으면, 해당 스레드가 다른 요청에 재사용될 때 이전 요청의 잔재 데이터가 오염되어 잘못된 로그가 찍히는 심각한 버그가 발생하므로 반드시 clear 처리를 수반해야 한다.

### Cardinality Explosion : 로그 수집 대상의 구체화

* 중앙 집중형 로그 수집 시스템(Elasticsearch 등)으로 로그를 전송할 때, 무분별한 텍스트 전체 인덱싱은 엄청난 디스크 용량 소모와 성능 저하를 야기한다. 특히 HTTP 요청 경로를 로그나 메트릭으로 수집할 때 `/order/123`, `/order/456`과 같이 동적 파라미터가 포함된 URL 구조를 그대로 수집하면 인덱싱 카디널리티(Cardinality)가 무한정 늘어나 시스템이 마비될 수 있다. 따라서 경로를 지정할 때는 정규화(Normalization) 작업을 통해 `/order/{id}`와 같은 형태로 병합(Merged)된 공통 Path로 등록하여 수집하고 관리하는 전략이 요구된다. "누가 요청했냐"는 Trace와 Log의 영역으로 풀고, "몇 개 요청했냐"는 Metric의 영역으로 분리하여 목적에 맞게 계측 및 수집 도구를 별도로 사용하는 것이 올바른 방법이다.

### OpenTelemetry

* OpenTelemetry는 메트릭 수집만을 의미하는 단순한 개념이나 방법론이 아니다. CNCF(Cloud Native Computing Foundation) 산하의 오픈 소스 통합 가시성(Observability) 프레임워크이자, 특정 상용 벤더 기술에 대한 의존성을 완전히 제거하고 메트릭, 로그, 트레이스를 일관된 방식으로 계측하기 위한 글로벌 표준 방안이다. 기존의 OpenTracing(추적 표준) 기술과 OpenCensus(수집 표준)의 개념을 완벽하게 통합하여 클라우드 네이티브 계측의 단일 표준으로 자리 잡았다.

#### Collector

* 애플리케이션 내부에 포함된 Otel SDK 또는 에이전트(Agent)가 수집한 데이터는 글로벌 통용 프로토콜인 OTLP(OpenTelemetry Protocol) 규격을 타고 중앙의 OpenTelemetry Collector로 전송된다. Collector는 아키텍처 상에서 핵심적인 역할을 담당하며 내부 파이프라인은 다음과 같은 구조적 컴포넌트로 연결된다.

#### Receiver / Processor / Exporter

* Receiver: 외부(애플리케이션 에이전트 등)에서 OTLP 프로토콜 등으로 송신한 다양한 포맷의 span, metric, log 데이터를 수신하는 입구 역할을 수행한다.
* Processor: 수신된 데이터를 최종 내보내기 전에 중간에서 가공, 필터링, 배치(Batch) 처리, 민감 정보 마스킹, 데이터 변환 등을 수행하며 필요한 경우 여러 프로세서를 계층(Processor 1, Processor 2, Processor N)으로 두어 연속적으로 처리한다.
* Exporter: 가공이 완료된 모니터링 데이터를 최종 저장소나 분석 도구로 전송하는 출구 역할을 수행한다. Exporter 설정을 통해 한 번에 여러 외부 시스템으로 데이터를 복제 발송(fan-out)할 수 있으며, 데이터 규격에 맞춰 Jaeger, Prometheus, Zipkin 등 전용 백엔드 도구의 포맷으로 최종 변환하여 유연하게 전송한다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://leehyokyun.gitbook.io/openbook/6-4..md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
