LLM 시스템의 관찰 가능성: 프로덕션 환경의 지표, 추적, 로그 및 테스트
LLM 추론 및 LLM 애플리케이션을 위한 종단간 가시성 전략
LLM 시스템은 전통적인 API 모니터링으로는 파악할 수 없는 방식으로 실패합니다. 큐가 조용히 가득 차고, GPU 메모리는 CPU가 바쁘게 보이기 훨씬 전에 포화 상태에 도달하며, 지연 시간은 애플리케이션 계층이 아닌 배치 처리 계층에서 급격히 증가합니다.
이 가이드는 LLM 추론 및 LLM 애플리케이션에 대한 관측성 전략의 엔드투엔드 접근 방식을 다룹니다. 무엇을 측정해야 하는지, Prometheus와 OpenTelemetry, Grafana를 사용하여 어떻게 계측(instrument)해야 하는지, 그리고 텔레메트리 파이프라인을 대규모로 배포하는 방법을 설명합니다.
풀 어시스턴트 스택(Full assistant stacks)은 원시 추론 위에 검색, 도구 호출, 라우팅을 추가합니다. AI 어시스턴트 아키텍처는 이러한 계층들 사이에서 관측성이 어디에 위치하는지 설명합니다.

TL;DR (요약)
LLM 시스템은 고전적인 “HTTP 지연 시간 + 오류율” 모니터링으로는 설명할 수 없는 방식으로 성능이 저하됩니다. 프로덕션급 **LLM 시스템 관측성**은 신속하고 방어 가능한 방식으로 다음 질문에 답해야 합니다:
- 사용자 경험이 저하되고 있는지 (미미한 지연 시간, 첫 토큰 도달 시간(TTFT), 토큰 간 지연 시간, 오류 및 중단).
- 시간이 어디에 소비되는지 (큐잉 대 배치 대 모델 실행; 검색/도구/안전 필터 대 추론).
- 무엇이 먼저 포화되는지 (GPU 사용률 및 메모리 압력, KV 캐시/큐 압력, CPU 토큰화).
- 비용 및 용량이 어떻게 변동하는지 (요청당 토큰, GPU당 초당 토큰 수, 캐시 히트율, 낭비된 생성).
- 텔레메트리가 안전하게 저장 가능한지 (프롬프트에는 PII가 포함될 수 있음; 로그/속성으로 민감한 정보 누출 방지).
가장 탄력적인 설계는 다중 신호 파이프라인입니다:
- 지표(Metrics): 빠른 감지 및 용량 계획용 (Prometheus + PromQL; Thanos/Cortex/Mimir/VictoriaMetrics를 통한 선택적 장기 저장소).
- 추적(Traces): 요청 수준의 인과 관계 파악용 (OTLP를 사용하는 OpenTelemetry; Tempo/Jaeger/Zipkin/Elastic APM과 같은 백엔드).
- 로그(Logs): 추적과 상관관계가 있는 컨텍스트 제공용 (Loki/Elastic/OpenSearch), 낮은 카디널리티 메타데이터를 위해 설계됨.
- 프로파일링(Profiling): CPU/메모리 핫스팟 및 미미한 지연 시간 분석용 (Grafana Pyroscope).
- 합성 및 부하 테스트(Synthetic + load tests): 사용자보다 먼저 회귀 현상을 감지하기 위해 (Grafana k6; 블랙박스 스타일 프로빙).
- 서비스 수준 목표(SLOs): 사용자 결과를 측정하고 실행 가능한 알림을 유도하기 위해 (오류 예산; 소모율 스타일).
LLM 시스템 관측성을 차별화하는 요소
범주 참고: 대상 LLM 프레임워크는 지정되지 않았습니다. 이 기사의 예시는 일반적인 서버/프레임워크(Triton, vLLM, TGI, LangChain/LangSmith)를 다루며, 동등한 지표와 스팬으로 대체하여 다른 스택에도 적용 가능합니다.
LLM은 기존 웹 서비스와 다른 운영 동작을 도입합니다:
- 요청당 가변적인 작업량: 토큰 수(입력/출력)는 크게 변동하므로 “초당 요청 수”는 안정적으로 보일 수 있지만 토큰 처리량은 붕괴될 수 있습니다. TGI와 vLLM은 이러한 모니터링 스타일을 지원하기 위해 토큰 및 토큰 지연 시간 관련 텔레메트리를 명시적으로 내보냅니다.
- 큐잉 + 연속 배치: 처리량은 배치/큐 규율에 의존하며, 큐 크기와 배치 크기가 일급 지표가 됩니다(TGI는 둘 다 노출).
- 스트리밍 UX: 사용자는 전체 응답 시간만큼이나 TTFT와 토큰 간 지연 시간을 중요하게 여깁니다. OpenTelemetry는 심지어 GenAI 시맨틱 관례 하에서 서버 TTFT/토큰당 시간 지표를 표준화했습니다.
- GPU 압력이 실패 모드를 지배: GPU 사용률과 GPU 메모리(사용된 메모리 포함)는 신뢰성의 핵심입니다. NVIDIA의 DCGM 익스포터는 Prometheus
/metrics엔드포인트에서 GPU 텔레메트리를 노출하기 위해 특별히 존재합니다. - 다단계 파이프라인: 검색, 도구 호출, 안전 필터 및 후처리는 엔드투엔드 지연 시간이 여러 스팬/큐의 조합임을 의미하여 분산 추적과 신중한 지표 설계가 필수적입니다.
인기 있는 추론 서버의 구체적인 예시는 이를 부각시킵니다:
- NVIDIA Triton Inference Server는
/metrics(일반적으로:8002/metrics)를 통해 평문으로 지표를 노출하고, 지표를 활성화/비활성화하고 지표 포트를 선택하기 위한 플래그를 제공합니다. - vLLM은
vllm:접두사를 가진 광범위한 Prometheus/metrics엔드포인트를 노출합니다. 문서에는 생성 토큰에 대한 카운터 및 첫 토큰 도달 시간과 같은 히스토그램이 포함되어 있습니다. - Hugging Face TGI는 큐 크기, 배치 크기, 엔드투엔드 요청 지속 시간, 생성된 토큰 및 큐 지속 시간을 포함하는
/metrics엔드포인트를 문서화합니다.
핵심 관측성 작업 및 필요한 LLM 텔레메트리
LLM 시스템 관측성은 작업 → 신호 → 도구를 매핑하고, 첫날부터 카디널리티와 샘플링을 제한할 때 가장 쉽게 구현됩니다.
지표: 온라인 서비스 시스템의 경우, Prometheus의 자체 계측 가이드는 쿼리 수, 오류 및 지연 시간을 핵심 지표로 강조합니다. LLM은 이를 TTFT, 토큰별 처리량/지연 시간, 큐 길이, 배치 크기 및 GPU 사용률로 확장합니다.
추적: 추적은 검색/도구/안전/추론 단계에 걸쳐 지연 시간과 실패를 귀속시키는 방법입니다. OpenTelemetry는 추적을 벤더 중립적인 방식으로 수집기나 백엔드로 텔레메트리를 방출하고 보내는 방법으로 프레임웍합니다.
로그: 로그는 사람이 읽을 수 있는 컨텍스트와 “왜”를 제공하지만, 무한한 값을 인덱싱하지 않으면서만 대규모로 사용 가능합니다(예: Loki는 레이블만 인덱싱하고 압축된 로그 청크를 개체 저장소에 저장).
프로파일링: 연속 프로파일링은 낮은 오버헤드 샘플링으로 프로덕션 CPU/메모리 동작을 캡처합니다. Grafana Pyroscope는 이를 위해 명시적으로 위치합니다.
합성 테스트 및 부하 테스트: Grafana k6은 오픈 소스 부하 테스트 도구이며, Grafana는 합성 모니터링이 k6으로 구동되며 단순 프로토콜 확인을 넘어선다고 명시합니다.
SLO: Google의 SRE 가이드는 SLO를 SLI로 측정된 서비스 수준의 대상 값/범위로 정의하며, SLO에 대한 알림을 위한 가이드(정확도/재현율/감지 시간 트레이드오프)를 제공합니다.
주요 LLM 지표 청사진
| 카테고리 | 예시 지표 이름 (실제 예시) | 타입 | 중요성 | 예시 출처 |
|---|---|---|---|---|
| 엔드투엔드 지연 시간 | tgi_request_duration |
히스토그램 | 미미한 지연 시간은 사용자 경험입니다 | TGI가 명시적으로 내보냄 |
| 첫 토큰 도달 시간 | vllm:time_to_first_token_seconds ; gen_ai.server.time_to_first_token |
히스토그램 | 스트리밍/지연된 첫 토큰은 종종 포화의 첫 신호입니다 | vLLM 및 OTel semconv GenAI |
| 출력 토큰당 시간 | tgi_request_mean_time_per_token_duration ; gen_ai.server.time_per_output_token |
히스토그램 | 토큰 간 지연 시간; 요청이 완료되더라도 “느리게 느껴짐” | TGI 및 OTel semconv GenAI |
| 토큰 사용량/볼륨 | tgi_request_generated_tokens ; gen_ai.client.token.usage |
히스토그램 / 카운터 | 비용 + 용량은 토큰 기반입니다 | TGI 및 OTel semconv GenAI |
| 요청 | tgi_request_count ; vllm:request_success_total |
카운터 | 트래픽 기준선 및 결과 | TGI 및 vLLM |
| 큐 길이 | tgi_queue_size |
게이지 | 큐잉은 지연 시간 폭발을 예측합니다 | TGI |
| 배치 크기 및 배치 한계 | tgi_batch_current_size ; tgi_batch_current_max_tokens |
게이지 | 처리량-지연 시간 트레이드오프 | TGI |
| GPU 사용률/메모리 | DCGM_* (익스포터 제공) |
게이지 | 포화, OOM 위험, 확장 트리거 | DCGM 익스포터가 /metrics에서 GPU 지표를 노출 |
| 추론 서버 텔레메트리 엔드포인트 | :8002/metrics (Triton 문서/아카이브 기본값) |
— | Prometheus용 표준 스크랩 대상 | Triton 문서 |
표준화를 위한 OpenTelemetry GenAI 시맨틱 관례
OpenTelemetry는 GenAI 시맨틱 관례(상태: “개발 중”)를 제공하며, 다음과 같은 GenAI 지표에 대한 표준 명명법을 제공합니다:
gen_ai.client.token.usage및gen_ai.client.operation.durationgen_ai.server.request.duration,gen_ai.server.time_per_output_token, 및gen_ai.server.time_to_first_token
이 표준화는 “OpenTelemetry로 LLM 모델 모니터링” 전략의 포터블한 실용적인 레버입니다: 한 번 방출하고 나중에 동일한 텔레메트리를 OSS 또는 벤더 백엔드로 라우팅합니다.
텔레메트리 파이프라인 설계

풀(Pull) 대 푸시(Push)
Prometheus는 풀 우선입니다. 프로세스는 지원되는 노출 형식으로 지표를 노출하고, Prometheus는 구성된 스크랩 작업에 따라 이를 스크랩합니다.
푸시는 예외를 위한 것입니다. Prometheus의 “Pushgateway 사용 시기” 가이드는 Pushgateway를 제한적인 경우에만(일반적인 푸시 대체재가 아님) 명시적으로 권장하며, Pushgateway README는 이를 통해 Prometheus를 “푸시 기반 모니터링 시스템”으로 변환할 수 없다고 강조합니다.
LLM 특화 실용 패턴:
- 추론 서버/익스포터(Triton/vLLM/TGI 지표 엔드포인트; DCGM 익스포터; 노드 지표)에 대해 풀 사용.
- 추적/로그/OTel 지표에 대해 OTLP 푸시 사용 (OpenTelemetry Protocol은 소스, 수집기 및 백엔드 간의 전송/인코딩/배달을 정의).
- 단일 Prometheus를 넘어서 확장할 때 리모트 씰(Write) 사용 (Prometheus는 리모트 씰 튜닝 가이드를 제공; Mimir/Thanos/Cortex는 장기 및/또는 HA 저장소 옵션을 제공).
에이전트 대 사이드카 대 게이트웨이 수집기
OpenTelemetry는 에이전트 배포 패턴을 문서화합니다. 여기서는 텔레메트리가 애플리케이션과 함께 또는 동일한 호스트(사이드카/DaemonSet)에서 실행되는 수집기로 전송된 후 내보내집니다.
Kubernetes의 경우, OpenTelemetry Operator를 통해 주석 기반 주입을 사용하여 사이드카 주입이 지원됩니다.
LLM 스택을 위한 실용적인 경험 법칙:
- 호스트 수준 보강 및 많은 포드 간 공유 파이프라인에 대해 DaemonSet 에이전트 사용.
- 엄격한 워크로드별 격리 또는 전용 로컬 필터링이 필요할 때 사이드카 사용 (프롬프트에 민감한 데이터가 포함될 수 있는 경우 일반적).
- 중앙 집중식 테일 샘플링, 배치, 재시도 및 내보내기 팬아웃을 위해 게이트웨이 수집기 사용.
샘플링 및 카디널리티 제어
OpenTelemetry는 테일 샘플링이 추적에서 파생된 기준을 사용하여 샘플링 결정을 허용한다고 명확히 합니다(머리 샘플링만으로는 불가능).
Prometheus의 계측 가이드는 레이블 과용을 경고하고, 카디널리티를 낮게 유지하라는 경험 법칙을 제공하며, 잠재적 카디널리티가 ~100을 초과할 경우 지표를 재설계하도록 조언합니다.
조기에 금지해야 할 LLM 특화 “카디널리티 함정”:
- 프롬프트 텍스트, 응답 텍스트, 대화 ID, 요청 ID를 레이블/속성으로 사용.
- 도구 인자 블롭을 스팬 속성으로 사용.
- 무한한 “user_id” 레이블.
유한 차원을 선호: model, model_family, endpoint, region, status_code, deployment, tenant(유한한 경우에만).
LLM 관측성 도구 비교
관측성 작업에 매핑된 도구
| 도구 | 지표 | 추적 | 로그 | 프로파일링 | 합성 테스트 | SLO / 알림 | LLM 관련성 |
|---|---|---|---|---|---|---|---|
| Prometheus | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | ✅ | 계측 가이드 + 알림 모델; 풀 기반 스크래핑 |
| Grafana | ✅ (시각화) | ✅ (시각화) | ✅ (시각화) | ✅ | ✅ | ✅ | 대시보드는 데이터 소스 위의 패널; 광범위한 데이터 소스 지원 |
| OpenTelemetry | ✅ | ✅ | ✅ | ✅ (프로파일 발전 중) | ◻️ | ◻️ | OTLP 스펙 + GenAI 시맨틱 관례; 벤더 중립 계측 |
| Jaeger | ◻️ | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | OTLP(gRPC/HTTP)를 받고 일반적인 추적 백엔드임 |
| Grafana Tempo | ◻️ | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | 대규모 추적; metrics-generator를 통해 스팬에서 지표 생성 가능 |
| Grafana Loki | ◻️ | ◻️ | ✅ | ◻️ | ◻️ | ◻️ | 레이블만 인덱싱; 압축된 청크 저장; 확장 시 로그 비용 감소 |
| Elastic Stack (ELK) | ✅ | ✅ | ✅ | ◻️ | ◻️ | ✅ | Elastic Stack는 Elasticsearch + Kibana 기반을 나열; Elastic APM은 OTel 통합 지원 |
| DCGM 익스포터 | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | ◻️ | /metrics 스크랩 엔드포인트를 노출하는 GPU 지표 익스포터 |
| Mimir / Thanos / Cortex | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | ◻️ | 장기/HA Prometheus 호환 지표 저장소 |
| Datadog | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | OTel 추적/지표/로그를 받음; 민감한 데이터 스캔 기능 포함 |
| New Relic | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | OTLP 엔드포인트 구성 및 지원되는 OTLP/HTTP 관행 문서화 |
| Honeycomb | ✅ | ✅ | ✅ | ◻️ | ◻️ | ✅ | gRPC/HTTP를 통한 OTLP 수신 지원; OTel 우선 수집 |
| LangSmith | ◻️ | ✅ | ◻️ | ◻️ | ◻️ | ◻️ | LLM 애플리케이션을 위한 OpenTelemetry 기반 추적 지원 |
시각화를 위한 Grafana 대 대안
- Grafana 대시보드는 데이터 소스(Loki 및 Mimir 포함)를 쿼리하여 차트와 시각화를 생성하는 패널로 구성됩니다.
- Kibana는 Elastic Stack 내 UI 레이어로 대시보드/시각화를 제공합니다.
- OpenSearch Dashboards는 OpenSearch를 위한 데이터 시각화 도구를 제공합니다.
- InfluxData의 문서는 Chronograf를 Influx 생태계 내 시각화 컴포넌트로 위치시킵니다.
지표 백엔드를 위한 Prometheus 대 대안
- Prometheus 로컬 저장소 기본값: 유지 기간 플래그가 설정되지 않으면 유지 기간은 15일로 기본 설정됩니다(유지 기간/비용을 조기에 계획).
- Grafana Mimir은 Prometheus 및 OpenTelemetry 지표용 수평 확장, HA, 다중 테넌트 장기 저장소로 설명됩니다.
- Thanos는 장기 저장소 기능을 갖춘 고가용성 Prometheus 설정으로 설명됩니다.
- Cortex는 Prometheus 및 OpenTelemetry 지표용 수평 확장, HA, 다중 테넌트 장기 저장소 솔루션으로 자신을 설명합니다.
- VictoriaMetrics Cloud는 장기 저장소를 위한 Prometheus 리모트 씰 통합을 문서화합니다.
- Amazon Managed Service for Prometheus는 수집/쿼리 필요에 따라 확장되고 PromQL 및 리모트 씰을 지원하는 관리형 서비스를 설명합니다.
실용적인 구현 쿡북
오늘 구현해야 할 지표 이름 및 타입
OpenTelemetry GenAI 시맨틱 관례(상태: 개발 중)는 즉시 표준화할 수 있는 지표 이름을 정의합니다:
gen_ai.client.token.usagegen_ai.client.operation.durationgen_ai.server.request.durationgen_ai.server.time_per_output_tokengen_ai.server.time_to_first_token
지금 바로 스크랩할 수 있는 서버 측 예시:
- vLLM의 Prometheus 엔드포인트에는 카운터(예: 총 생성 토큰) 및 히스토그램(TTFT)이 포함되며,
model_name레이블 전략을 문서화합니다. - TGI는 큐 크기, 요청 지속 시간, 생성된 토큰 및 토큰당 평균 시간을 포함하는 지표를 문서화합니다.
- Triton은
/metrics노출 및 지표 토글을 문서화합니다.
LLM 지연 시간 및 처리량 대시보드를 위한 PromQL 예시
# 애플리케이션 히스토그램의 p95 엔드투엔드 지연 시간
histogram_quantile(
0.95,
sum(rate(llm_request_latency_seconds_bucket[5m])) by (le, model)
)
# 오류율 퍼센티지 (5xx)
100 *
(
sum(rate(llm_requests_total{status_code=~"5.."}[5m]))
/
sum(rate(llm_requests_total[5m]))
)
# 모든 모델에 대한 초당 토큰 수 (출력)
sum(rate(llm_tokens_total{direction="out"}[5m]))
# TGI 큐 크기 (게이지)
max(tgi_queue_size) by (instance)
# vLLM TTFT p95
histogram_quantile(
0.95,
sum(rate(vllm:time_to_first_token_seconds_bucket[5m])) by (le, model_name)
)
Prometheus의 히스토그램 가이드는 히스토그램 분위수가 서버 측에서 버킷을 사용하여 histogram_quantile()로 계산됨을 설명합니다.
LLM 시스템을 위한 OpenTelemetry 계측 참고 사항
- OTLP는 OpenTelemetry Protocol로, 소스, 수집기 및 백엔드 간에 텔레메트리가 어떻게 인코딩/전송되는지 지정합니다.
- OpenTelemetry SDK 구성은
OTEL_EXPORTER_OTLP_ENDPOINT(및 프로토콜 옵션)와 같은 환경 변수를 문서화하여 텔레메트리를 내보냅니다. - OpenTelemetry Python contrib는 자동 및 수동 계측을 위한 FastAPI 계측 지원을 문서화합니다.
- GenAI 시맨틱 관례에는
OTEL_SEMCONV_STABILITY_OPT_IN을 통한 GenAI 관례 마이그레이션용 옵인 안정성 메커니즘이 포함됩니다.
짧은 Python 예시: 지표 + 추적 + 로그
아래 스니펫은 다음을 시연합니다:
- “Prometheus로 LLM 추론 모니터링”을 위한 Prometheus 지표 노출(
/metrics) - OTLP(벤더 중립)를 통해 내보낸 OpenTelemetry 추적
- 추적 컨텍스트와 상관관계가 있는 구조화된 로그, 프라이버시 안전 기본값 포함(원시 프롬프트 로깅 금지)
import logging
import time
from fastapi import FastAPI, Request
from pydantic import BaseModel
# Prometheus (풀 기반 지표)
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
from starlette.responses import Response
# OpenTelemetry (OTLP 추적)
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
app = FastAPI(title="LLM Inference API", version="1.0.0")
FastAPIInstrumentor.instrument_app(app)
# --- 로깅 (프라이버시 안전 기본값) ---
logger = logging.getLogger("llm")
logging.basicConfig(level=logging.INFO, format="%(message)s")
def trace_id_hex() -> str:
span = trace.get_current_span()
ctx = span.get_span_context()
return format(ctx.trace_id, "032x") if ctx.is_valid else ""
# --- Prometheus 지표 ---
LLM_REQUESTS = Counter(
"llm_requests_total",
"LLM requests total",
["route", "status_code", "model"],
)
LLM_LATENCY = Histogram(
"llm_request_latency_seconds",
"End-to-end LLM request latency (seconds)",
["route", "model"],
buckets=(0.1, 0.2, 0.35, 0.5, 0.75, 1, 1.5, 2, 3, 5, 8, 13),
)
# --- OpenTelemetry 트레이서 제공자 ---
resource = Resource.create({"service.name": "llm-inference-api"})
trace.set_tracer_provider(TracerProvider(resource=resource))
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(OTLPSpanExporter()) # OTEL_EXPORTER_OTLP_* 환경 변수를 통해 구성
)
tracer = trace.get_tracer(__name__)
class GenerateRequest(BaseModel):
prompt: str
model: str = "unspecified"
max_tokens: int = 256
class GenerateResponse(BaseModel):
model: str
output: str
latency_ms: int
@app.post("/v1/generate", response_model=GenerateResponse)
async def generate(req: GenerateRequest, request: Request):
route = "/v1/generate"
start = time.perf_counter()
with tracer.start_as_current_span("llm.generate") as span:
# 전체 프롬프트 로깅 피함; 안전한 메타데이터 방출
span.set_attribute("gen_ai.request.model", req.model)
span.set_attribute("gen_ai.request.max_tokens", req.max_tokens)
# 실제 LLM 호출로 대체 (Triton/vLLM/TGI 클라이언트)
time.sleep(0.15)
output = "Hello from the model."
latency_s = time.perf_counter() - start
LLM_LATENCY.labels(route=route, model=req.model).observe(latency_s)
LLM_REQUESTS.labels(route=route, status_code="200", model=req.model).inc()
logger.info(
{
"msg": "llm_request_complete",
"trace_id": trace_id_hex(),
"model": req.model,
"latency_ms": int(latency_s * 1000),
# 정책이 허용하지 않는 한 원시 프롬프트/출력을 포함하지 마십시오.
}
)
return GenerateResponse(model=req.model, output=output, latency_ms=int(latency_s * 1000))
@app.get("/metrics")
def metrics():
return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)
배포, 확장, 보안 및 문제 해결

배포 옵션
| 배포 옵션 | 가장 적합한 경우 | 트레이드오프 |
|---|---|---|
| Kubernetes + kube-prometheus-stack (Helm) | 표준화된 클러스터 모니터링 번들 (Prometheus Operator, 대시보드, 규칙) | CRD/오퍼레이터 라이프사이클 관리 |
| Kubernetes + OpenTelemetry Collector (DaemonSet/sidecar) | 표준화된 OTLP 파이프라인; 로컬 민감 필터링 | 샘플링/한계 튜닝 필요 |
| Docker Compose | 단일 호스트에서 빠른 프로토타이핑 | HA 아님; 저장소 수동 |
| systemd / VM 설치 | 베어메탈 GPU 플릿 및 전통적인 운영 | 수동 발견 및 구성 |
| 관리형 서비스 (Grafana Cloud / Datadog / New Relic / AMP) | 빠른 가치 실현; 관리형 확장 | 비용 및 거버넌스; 벤더 잠금 트레이드오프 |
확장 및 유지 기간: 실용적인 제약
- Prometheus 로컬 저장소: 명시적인 크기/시간 플래그 없이 유지 기간은 15일로 기본 설정됩니다.
- Prometheus 리모트 씰: Prometheus는 “상식적인 기본값”을 넘어 확장하기 위한 리모트 씰 튜닝을 문서화합니다.
- Grafana Tempo: 대규모 추적 백엔드로 위치되며, metrics-generator를 사용하여 스팬에서 지표를 생성할 수 있습니다(Prometheus 데이터 소스로의 리모트 씰).
- Loki 저장소: Loki의 문서는 레이블만 인덱싱하고 압축된 청크 저장(개체 저장소)을 강조하며, 레이블 전략이 확장과 비용의 핵심임을 명시합니다.
보안 및 프라이버시: 프롬프트에는 PII가 포함될 수 있음
OpenTelemetry의 보안 가이드는 텔레메트리 수집이 우연히 민감한/개인 정보를 캡처할 수 있음을 강조하며, 이를 적절하게 처리하는 것은 사용자의 책임입니다.
Prometheus의 보안 모델은 Prometheus 엔드포인트가 모니터링되는 시스템에 대한 정보를 제공하므로 공개적으로 접근 가능한 네트워크(인터넷 등)에 노출되어서는 안 된다고 경고합니다.
“LLM 시스템 관측성”을 안전하게 유지하는 운영 프라이버시 제어:
- 기본값으로 원시 프롬프트/응답을 로그하지 않음; 대신 토큰 수, 모델 이름, 지연 시간 및 추적 ID를 로그합니다.
- 수집기/파이프라인에서 민감한 속성을 삭제/드롭 (수집기 수준 필터링은 생태계 전반에서 일반적인 접근 방식).
- 로그/추적에 대한 RBAC 및 유지 기간 정책을 강제; 적절한 경우 민감 데이터 스캐너 고려 (예: 벤더는 텔레메트리를 위한 스캐너를 문서화).
문제 해결 체크리스트
LLM 지연 시간 Grafana 대시보드가 잘못 보인다면 다음 순서로 디버깅하십시오:
- 수집 건강 상태
- Prometheus: 스크랩 성공 및 구성 시맨틱 검증 (Prometheus 구성은 스크랩 작업/인스턴스를 정의).
- OTLP: 익스포터 엔드포인트 구성 확인 (SDK는
OTEL_EXPORTER_OTLP_ENDPOINT및 프로토콜 설정 사용).
- 스키마 불일치
- 대시보드는
model을 기대하지만, 서버는model_name을 방출 (vLLM은model_name레이블을 명시적으로 문서화).
- 대시보드는
- 카디널리티 폭발
- 누군가가 요청 ID/프롬프트 해시로 레이블링; Prometheus는 레이블 세트가 RAM/CPU/디스크/네트워크 비용을 증가시킨다고 경고하고 카디널리티 가이드를 제공.
- 히스토그램 오용
_bucket시리즈에서rate()및le를 사용하여 분위수를 계산하는지 확인; Prometheus는 히스토그램 분위수 계산 트레이드오프를 설명.
- 추적 샘플링 간격
- 머리 샘플링을 너무 공격적으로 수행하면 희귀한 느린/오류 추적이 사라짐; 테일 샘플링은 전체 추적 기준에 따라 “중요한” 추적을 유지.
- Tempo 스팬-지표 문제
- Tempo metrics-generator 및 스팬-지표를 사용하는 경우 활성화 및 튜닝됨을 확인 (Tempo는 metrics-generator 및 스팬-지표 프로세서를 문서화; 생성기 문제에 대한 문제 해결 존재).
- GPU 지표 누락
- DCGM 익스포터가 배포되고
/metrics에 도달 가능한지 확인 (DCGM 익스포터는 HTTP를 통해 Prometheus용 GPU 지표를 노출).
- DCGM 익스포터가 배포되고
유용한 링크
- AI 어시스턴트의 폴링 에이전트: 11가지 구현 패턴 — 관측성 체크리스트 섹션은 프로덕션 폴링 시스템에 계측해야 할 정확한 백그라운드 에이전트 지표, 로그 필드 및 관리자 뷰를 다룹니다
- 관측성: 모니터링, 지표, Prometheus 및 Grafana 가이드
- A2A vs MCP: AI 에이전트가 실제로 두 프로토콜 모두 필요한가? —那里的 관측성 및 보안 섹션은 두 프로토콜을 결합하는 다중 에이전트 시스템에서 무엇을 추적해야 하는지 다룹니다
- 다중 에이전트 오케스트레이션 패턴 — 관측성 섹션은 각 패턴에 특화된 분산 추적 요구 사항을 다룹니다: 스웜을 위한 블랙보드 리플레이, 에이전트별 비용 귀속, 메시를 위한 수렴 모니터링
- 2026년 Google A2A 프로토콜: 채택, 과장 및 현실 — 보안 및 일반적 실수 섹션은 A2A 경계를 넘어 에이전트를 배포할 때 필요한 관측성을 정확히 다룹니다
- A2A 프로토콜이란 무엇인가? 에이전트 카드 및 작업 설명 — 관측성 섹션은 크로스 에이전트 작업 추적이 무엇을 캡처해야 하는지 설명합니다: 작업 상태 변경, 위임 체인, 아티팩트 및 에이전트 간 메시지
- Prometheus 모니터링: 설정 및 모범 사례
- LLM 성능: 벤치마크, 병목 현상 및 최적화
- LLM 호스팅: 로컬, 셀프 호스트 및 클라우드 인프라 비교
- RAG 단계별 튜토리얼
- Prometheus 구성 문서
- Prometheus 노출 형식
- Prometheus 계측 모범 사례
- Prometheus 지표 명명
- Prometheus 히스토그램 및 요약
- Prometheus 알림 규칙
- Prometheus 알림 개요
- Alertmanager 구성
- Grafana 대시보드 JSON 모델
- Grafana 프로비저닝
- NVIDIA Triton Inference Server 지표
- TorchServe 지표 API
- NVIDIA DCGM 익스포터
- kube-prometheus-stack Helm 차트
- Prometheus Operator 시작 가이드
- OpenTelemetry Prometheus 익스포터 스펙
- OTLP 수신용 Prometheus 가이드
- OpenTelemetry로 LangSmith 추적