본문으로 건너뛰기

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