문제 상황#

Grafana 대시보드 “애플리케이션 모니터링(Spring Boot)“에서:

  • 애플리케이션 드롭다운에 gateway만 표시됨
  • auth-guard, order-core, seat, queue 등 다른 서비스가 보이지 않음
  • http_server_requests_seconds_count{namespace="dev-webs"} 쿼리 시 gateway만 결과 반환

원인 분석#

1. 메트릭 수집 경로가 2가지로 분리되어 있었음#

경로메트릭 이름라벨대상
PodMonitor → Prometheus 직접 스크레이핑http_server_requests_seconds_*status, uri, namespacegateway만
OTel Agent → OTel Collector → Remote Writehttp_server_request_duration_seconds_*http_response_status_code, http_route모든 서비스

2. gateway만 Micrometer 메트릭이 있었던 이유#

  • gateway: Spring Cloud Gateway로 micrometer-registry-prometheus 의존성 포함
  • 다른 서비스: OTel Java Agent만 사용, Micrometer 의존성 없음

3. OTel 메트릭에 namespace 라벨 누락#

OTel Collector의 transform processor에서 namespace 라벨을 설정하려 했으나:

transform:
  metric_statements:
    - context: datapoint
      statements:
        - set(attributes["namespace"], resource.attributes["service.namespace"])

문제: OTel Java Agent가 service.namespace resource attribute를 설정하지 않고 있었음

해결#

1. Deployment에 OTEL_RESOURCE_ATTRIBUTES 추가#

java-service/templates/deployment.yaml:

{{- if .Values.otel.enabled }}
- name: JAVA_TOOL_OPTIONS
  value: "-javaagent:/otel/opentelemetry-javaagent.jar"
- name: OTEL_SERVICE_NAME
  value: {{ include "java-service.fullname" . }}
- name: OTEL_RESOURCE_ATTRIBUTES          # 추가
  value: "service.namespace={{ .Release.Namespace }}"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
  value: {{ .Values.otel.collectorEndpoint | quote }}
{{- end }}

ai-service/templates/deployment.yaml에도 동일하게 추가

2. 대시보드를 OTel 메트릭으로 변경#

메트릭 이름 변경:

Micrometer (기존)OTel (변경)
http_server_requests_seconds_counthttp_server_request_duration_seconds_count
http_server_requests_seconds_buckethttp_server_request_duration_seconds_bucket
http_server_requests_seconds_sumhttp_server_request_duration_seconds_sum

라벨 이름 변경:

Micrometer (기존)OTel (변경)
statushttp_response_status_code
urihttp_route

3. 템플릿 변수 쿼리 변경#

# 기존
label_values(http_server_requests_seconds_count{namespace="$namespace"}, app)

# 변경
label_values(http_server_request_duration_seconds_count{namespace="$namespace"}, app)

4. 필터 regex 수정 (느린 엔드포인트 TOP 10)#

context-path가 포함된 경로도 필터링되도록 수정:

# 기존: /auth/actuator/health/** 같은 경로가 필터링 안 됨
http_route!~"/actuator.*|/swagger.*|..."

# 변경: 경로 중간에 있는 패턴도 매칭
http_route!~".*actuator.*|.*swagger.*|.*health.*|..."

수정된 파일 목록#

  1. common-charts/apps/java-service/templates/deployment.yaml

    • OTEL_RESOURCE_ATTRIBUTES 환경변수 추가
  2. common-charts/apps/ai-service/templates/deployment.yaml

    • OTEL_RESOURCE_ATTRIBUTES 환경변수 추가
  3. common-charts/infra/monitoring/prometheus-stack/files/grafana-dashboards/dev-team-observability/application-monitoring-springboot.json

    • OTel 메트릭으로 변경
  4. common-charts/infra/monitoring/prometheus-stack/files/grafana-dashboards/infra-team-observability/k6/k6-overview.json

    • OTel 메트릭으로 변경
    • RDS/Redis 템플릿 변수 제거
    • PostgreSQL 쿼리 라벨 수정 (datname → 제거)

메트릭 흐름도#

┌─────────────────┐
│  Java Service   │
│  (OTel Agent)   │
└────────┬────────┘
         │ OTLP (gRPC :4317)
         │ service.namespace=dev-webs
         ▼
┌─────────────────┐
│  OTel Collector │
│   (transform)   │
│                 │
│ namespace ←     │
│ service.namespace
└────────┬────────┘
         │ Remote Write
         ▼
┌─────────────────┐
│   Prometheus    │
│                 │
│ http_server_    │
│ request_duration│
│ _seconds_count  │
│ {namespace=     │
│  "dev-webs"}    │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│    Grafana      │
│   Dashboard     │
└─────────────────┘

적용 순서#

  1. java-service, ai-service 변경 배포

    • dev-webs, dev-ai 앱 ArgoCD Sync
    • Pod 재시작으로 OTEL_RESOURCE_ATTRIBUTES 적용
  2. prometheus-stack 배포

    • 대시보드 ConfigMap 업데이트
  3. 확인

    • Prometheus에서 http_server_request_duration_seconds_count{namespace="dev-webs"} 쿼리
    • 모든 서비스(gateway, auth-guard, order-core, seat, queue)가 보이면 성공

참고: OTel vs Micrometer 선택 이유#

항목OTelMicrometer
표준CNCF 표준, 벤더 중립Spring 생태계
의존성OTel Agent만 (runtime)micrometer-registry-prometheus 필요
설정환경변수로 설정application.yml
메트릭 이름OpenTelemetry Semantic ConventionsSpring Boot 네이밍

결론: 모든 서비스에 OTel Agent가 이미 붙어있으므로 OTel 메트릭으로 통일