본문으로 건너뛰기

Jaeger & Google Cloud Trace 통합 가이드

OpenTelemetry 분산 추적 데이터를 Jaeger UI와 Google Cloud Trace에서 활용하는 방법을 설명합니다.

📋 목차

  1. 개요
  2. Google Cloud Trace 사용법
  3. Jaeger UI 사용법
  4. 환경별 접근 방법
  5. 트레이스 분석 가이드
  6. 성능 모니터링
  7. 문제 해결

1. 개요

1.1 두 시스템의 역할

시스템주요 용도장점환경별 활성화
Google Cloud Trace실시간 모니터링, 알림관리형 서비스, 자동 스케일링모든 환경
Jaeger UI상세 분석, 디버깅풍부한 UI, 트레이스 시각화Stage, Prod만

1.2 데이터 흐름


2. Google Cloud Trace 사용법

2.1 Cloud Trace 콘솔 접근

환경별 직접 링크

# Dev 환경
https://console.cloud.google.com/traces/list?project=dta-cloud-de-dev

# Stage 환경
https://console.cloud.google.com/traces/list?project=dta-cloud-de-stage

# Prod 환경
https://console.cloud.google.com/traces/list?project=dta-cloud-de-prod

접근 권한 확인

# 현재 사용자 권한 확인
gcloud auth list

# Cloud Trace 권한 확인
gcloud projects get-iam-policy dta-cloud-de-dev \
--flatten="bindings[].members" \
--filter="bindings.members:$(gcloud auth list --filter=status:ACTIVE --format='value(account)')"

2.2 기본 트레이스 조회

최근 트레이스 확인

  1. Time Range: 최근 1시간 선택
  2. Filter:
    • service_name = "dta-wide-api"
    • http.status_code >= 400 (오류만)
    • duration >= 1000ms (느린 요청만)

고급 필터 예시

# 특정 엔드포인트의 오류 트레이스
service_name="dta-wide-api" AND http.route="/api/sleep-logs" AND http.status_code>=400

# 느린 데이터베이스 쿼리
service_name="dta-wide-api" AND span_name CONTAINS "pg." AND duration>=2000ms

# 특정 사용자 세션 (해시화된 ID)
user_id_hash="a1b2c3d4e5f6g7h8"

2.3 트레이스 상세 분석

트레이스 타임라인 읽기

Root Span: POST /api/sleep-logs (Total: 1,234ms)
├── Auth Middleware (45ms)
├── Validation (23ms)
├── Business Logic (156ms)
│ ├── Database Query (89ms)
│ └── Cache Lookup (12ms)
├── External ML Service (967ms) ⚠️ 병목!
└── Response Serialization (34ms)

성능 이상 패턴 식별

  • 지연시간 급증: 특정 시간대 응답시간 증가
  • 오류율 상승: HTTP 5xx 상태 코드 증가
  • 의존성 실패: 외부 서비스 호출 실패

2.4 Cloud Monitoring 대시보드

대시보드 접근

# Terraform output에서 대시보드 URL 확인
cd infrastructure/terragrunt/dev/distributed-tracing
terragrunt output dashboard_url

주요 메트릭

  • Request Rate: 분당 요청 수
  • Latency Percentiles: P50, P95, P99 응답시간
  • Error Rate: 오류 발생률
  • Service Dependencies: 서비스 간 호출 관계

3. Jaeger UI 사용법

3.1 Jaeger UI 접근 (Stage/Prod만)

접속 URL 확인

# Stage 환경 Jaeger URL
cd infrastructure/terragrunt/stage/distributed-tracing
terragrunt output jaeger_ui_url

# 예시 출력: https://jaeger-stage.europe-west3.run.app

브라우저 접속

# Stage 환경 Jaeger UI
https://jaeger-stage.europe-west3.run.app

# Prod 환경 Jaeger UI
https://jaeger-prod.europe-west3.run.app

3.2 Jaeger UI 주요 기능

3.2.1 트레이스 검색

기본 검색:

  • Service: dta-wide-api
  • Operation: POST /api/sleep-logs
  • Tags: http.status_code=500
  • Lookback: 1h (지난 1시간)

고급 태그 검색:

# 특정 사용자 세션
user_id_hash="a1b2c3d4e5f6g7h8"

# 느린 데이터베이스 쿼리
db.operation="SELECT" AND duration>2s

# 오류가 발생한 외부 서비스 호출
error=true AND service_name="external-ml-service"

# 특정 시간대 트레이스
start_time>2025-01-22T09:00:00 AND start_time\<2025-01-22T10:00:00

3.2.2 트레이스 상세 분석

트레이스 타임라인:

  • Gantt Chart: 시간 흐름에 따른 스팬 실행
  • Span Details: 개별 스팬의 속성 및 로그
  • Process Info: 서비스별 메타데이터

스팬 속성 분석:

{
"operation": "POST /api/sleep-logs",
"duration": "1.234s",
"status": "OK",
"tags": {
"http.method": "POST",
"http.route": "/api/sleep-logs",
"http.status_code": 200,
"user.id_hash": "a1b2c3d4e5f6g7h8",
"service.component": "sleep-service"
}
}

3.2.3 서비스 의존성 맵

System Architecture 탭:

  • Service Graph: 서비스 간 호출 관계 시각화
  • Operation Dependencies: 작업별 의존성
  • Performance Metrics: 서비스별 성능 지표

Dependencies 분석:

dta-wide-api (Entry Point)
├── dta-wide-mcp (94% success, 123ms avg)
├── postgresql (99.2% success, 45ms avg)
├── redis (99.8% success, 8ms avg)
└── external-ml-service (89% success, 967ms avg) ⚠️

3.3 Jaeger 고급 분석

3.3.1 성능 히트맵

Latency Distribution:

  • P50: 250ms
  • P95: 1.2s
  • P99: 2.8s
  • Max: 15s

3.3.2 에러 분석

Error Traces 필터링:

# 오류 트레이스만 표시
error=true

# 특정 에러 타입
error.type="TimeoutError"

# HTTP 오류 상태 코드
http.status_code>=400

4. 환경별 접근 방법

4.1 Dev 환경 (Cloud Trace만)

# Cloud Trace 콘솔
echo "https://console.cloud.google.com/traces/list?project=dta-cloud-de-dev"

# BigQuery 트레이스 쿼리
bq query --use_legacy_sql=false '
SELECT
service_name,
operation_name,
COUNT(*) as span_count,
AVG(duration_ms) as avg_duration_ms
FROM `dta-cloud-de-dev.traces.otel_traces`
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
GROUP BY service_name, operation_name
ORDER BY span_count DESC'

4.2 Stage 환경 (Cloud Trace + Jaeger)

# Jaeger UI 접속
echo "Jaeger UI: $(cd infrastructure/terragrunt/stage/distributed-tracing && terragrunt output jaeger_ui_url)"

# Cloud Trace 콘솔
echo "Cloud Trace: https://console.cloud.google.com/traces/list?project=dta-cloud-de-stage"

# 대시보드 URL
echo "Dashboard: $(cd infrastructure/terragrunt/stage/distributed-tracing && terragrunt output dashboard_url)"

4.3 Prod 환경 (완전한 모니터링)

# 모든 모니터링 URL 출력
cd infrastructure/terragrunt/prod/distributed-tracing

echo "🔍 Jaeger UI: $(terragrunt output jaeger_ui_url)"
echo "📊 Cloud Trace: https://console.cloud.google.com/traces/list?project=dta-cloud-de-prod"
echo "📈 Dashboard: $(terragrunt output dashboard_url)"
echo "🗃️ BigQuery: https://console.cloud.google.com/bigquery?project=dta-cloud-de-prod"

5. 트레이스 분석 가이드

5.1 일반적인 분석 패턴

5.1.1 성능 병목 식별

1단계: 느린 트레이스 찾기

# Jaeger에서 검색
Service: dta-wide-api
Min Duration: 2s
Lookback: 1h

2단계: 병목 스팬 분석

  • 가장 긴 실행 시간을 가진 스팬 확인
  • 병렬 실행 가능한 작업 식별
  • 외부 의존성 성능 확인

3단계: 최적화 방향 결정

// 예시: 병렬 처리 최적화
async function optimizedSleepAnalysis(data: any) {
// Before: 순차 실행 (총 500ms)
const validation = await validateData(data); // 100ms
const analysis = await analyzePattern(validation); // 300ms
const report = await generateReport(analysis); // 100ms

// After: 병렬 실행 (총 300ms)
const [validation, preloadedData] = await Promise.all([
validateData(data), // 100ms
preloadAnalysisData() // 50ms
]);

const [analysis, reportTemplate] = await Promise.all([
analyzePattern(validation), // 300ms (병목)
loadReportTemplate() // 50ms
]);

return generateReport(analysis, reportTemplate); // 50ms
}

5.1.2 오류 근본 원인 분석

1단계: 오류 트레이스 수집

# Jaeger 검색
Tags: error=true
Service: dta-wide-api
Lookback: 24h

2단계: 오류 패턴 분석

  • 시간대별 오류 분포: 특정 시간대 집중 여부
  • 서비스별 오류율: 어느 서비스에서 오류 발생
  • 오류 전파 경로: 상위 서비스에서 하위 서비스로의 오류 전파

3단계: 오류 컨텍스트 분석

{
"error_trace_example": {
"root_cause": "external-ml-service timeout",
"error_propagation": [
"external-ml-service (timeout after 30s)",
"dta-wide-api (circuit breaker opened)",
"client (503 Service Unavailable)"
],
"resolution": "Increase timeout to 45s, add retry logic"
}
}

5.2 DTA 플랫폼 특화 분석

5.2.1 사용자 세션 추적

사용자별 트레이스 분석:

# 특정 사용자의 전체 세션 추적
user_id_hash="a1b2c3d4e5f6g7h8"

# 사용자 여정 분석
1. Login → 2. Profile Update → 3. Sleep Log Creation → 4. Analysis Request

5.2.2 의료 데이터 처리 모니터링

규제 준수 추적:

# GDPR 데이터 접근 추적
Tags: gdpr.data_access=true AND audit.required=true

# 의료 데이터 처리 성능
Tags: data.sensitivity="high" AND compliance.context="DiGA"

5.2.3 설문 응답 처리 분석

설문별 성능 분석:

# PHQ-9 설문 처리 성능
Operation: questionnaire.processing
Tags: questionnaire.type="PHQ-9"

# 설문 처리 시간 분포
AVG: 234ms, P95: 567ms, P99: 1.2s

6. 성능 모니터링

6.1 SLI/SLO 모니터링

분산 추적 SLI

-- 트레이스 완성도 (BigQuery)
SELECT
TIMESTAMP_TRUNC(timestamp, HOUR) as hour,
COUNT(DISTINCT trace_id) as total_traces,
COUNTIF(parent_span_id IS NULL) as complete_traces,
SAFE_DIVIDE(
COUNTIF(parent_span_id IS NULL),
COUNT(DISTINCT trace_id)
) * 100 as completeness_percentage
FROM `{PROJECT}.traces.otel_traces`
WHERE timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
GROUP BY hour
ORDER BY hour DESC;

엔드투엔드 지연시간 SLI

-- 서비스별 P95 지연시간
WITH trace_durations AS (
SELECT
service_name,
trace_id,
TIMESTAMP_DIFF(
MAX(timestamp),
MIN(timestamp),
MILLISECOND
) as total_duration_ms
FROM `{PROJECT}.traces.otel_traces`
WHERE timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
AND parent_span_id IS NULL
GROUP BY service_name, trace_id
)
SELECT
service_name,
PERCENTILE_CONT(total_duration_ms, 0.95) OVER (
PARTITION BY service_name
) as p95_duration_ms,
COUNT(*) as trace_count
FROM trace_durations
GROUP BY service_name, total_duration_ms
ORDER BY p95_duration_ms DESC;

6.2 알림 정책

Cloud Monitoring 알림

# 트레이스 수집 중단 알림
displayName: "분산 추적 수집 중단"
conditions:
- conditionThreshold:
filter: 'resource.type="cloud_trace"'
comparison: COMPARISON_LESS_THAN
thresholdValue: 10 # 시간당 10개 미만
duration: "300s"

Jaeger 기반 알림

# Jaeger API를 통한 알림 데이터 수집
curl "https://jaeger-prod.europe-west3.run.app/api/traces?service=dta-wide-api&lookback=1h" \
| jq '.data[].errors | length' \
| awk '{sum+=$1} END {if(sum>10) print "High error rate detected: " sum}'

7. 문제 해결

7.1 일반적인 문제

문제 1: Jaeger UI에 트레이스가 표시되지 않음

진단:

# 1. Jaeger 서비스 상태 확인
curl -f https://jaeger-stage.europe-west3.run.app/health || echo "Jaeger service down"

# 2. OTLP 엔드포인트 연결 테스트
curl -X POST "https://jaeger-stage.europe-west3.run.app/v1/traces" \
-H "Content-Type: application/json" \
-d '{"resourceSpans": []}' || echo "OTLP endpoint error"

# 3. 애플리케이션 트레이스 전송 확인
gcloud logging read "resource.type=cloud_run_revision AND
resource.labels.service_name=dta-wide-api AND
textPayload:jaeger" --limit=10

해결책:

  1. Jaeger 재시작: Cloud Run 서비스 재배포
  2. 네트워크 설정: VPC 커넥터 및 방화벽 규칙 확인
  3. 환경 변수: JAEGER_ENDPOINT 설정 확인

문제 2: Cloud Trace에서 트레이스가 누락됨

진단:

# 1. Cloud Trace API 상태 확인
gcloud services list --filter="name:cloudtrace.googleapis.com" --enabled

# 2. 서비스 계정 권한 확인
gcloud projects get-iam-policy dta-cloud-de-stage \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:*tracing*"

# 3. 최근 트레이스 확인
gcloud logging read "protoPayload.serviceName=cloudtrace.googleapis.com" --limit=5

해결책:

  1. API 활성화: gcloud services enable cloudtrace.googleapis.com
  2. 권한 부여: roles/cloudtrace.agent 역할 추가
  3. 샘플링 확인: 샘플링 비율이 너무 낮지 않은지 확인

문제 3: 높은 지연시간 오버헤드

진단:

-- 트레이싱 오버헤드 측정 (BigQuery)
WITH tracing_overhead AS (
SELECT
service_name,
operation_name,
AVG(duration_ms) as avg_duration_with_tracing,
COUNT(*) as sample_size
FROM `{PROJECT}.traces.otel_traces`
WHERE timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
AND attributes LIKE '%opentelemetry%'
GROUP BY service_name, operation_name
)
SELECT
service_name,
operation_name,
avg_duration_with_tracing,
sample_size
FROM tracing_overhead
WHERE sample_size > 10
ORDER BY avg_duration_with_tracing DESC;

해결책:

// 1. 샘플링 비율 조정
OTEL_TRACES_SAMPLER_ARG=0.1 // 10%로 감소

// 2. 배치 크기 최적화
const spanProcessor = new BatchSpanProcessor(traceExporter, {
maxQueueSize: 1000,
scheduledDelayMillis: 5000, // 5초 배치 간격
exportTimeoutMillis: 30000
});

// 3. 불필요한 속성 제거
span.setAttributes({
// 필수 속성만 유지
'service.name': 'dta-wide-api',
'operation.name': 'process_request'
// 고용량 속성 제거: request_body, response_body 등
});

7.2 성능 최적화

Jaeger UI 성능 개선

# Jaeger 메모리 최적화
jaeger_config:
memory_max_traces: 10000 # 트레이스 수 제한
cpu_limit: "1000m" # CPU 리소스 증가
memory_limit: "2Gi" # 메모리 리소스 증가

Cloud Trace 쿼리 최적화

# 인덱스된 필드로 필터링
service_name="dta-wide-api" AND span_name="POST /api/sleep-logs"

# 시간 범위 제한
start_time>=2025-01-22T09:00:00 AND start_time<=2025-01-22T10:00:00

# 불필요한 태그 제외
NOT (span_name CONTAINS "health" OR span_name CONTAINS "metrics")

📞 지원 및 참고 자료

문서 링크

지원 채널

  • 기술 지원: 내부 Slack #dta-infrastructure
  • 문제 보고: GitHub Issues
  • 긴급 상황: PagerDuty (Prod 환경만)

작성자: DTA-Wide 인프라팀
최종 업데이트: 2025-08-13
버전: 1.0.0