Jaeger & Google Cloud Trace 통합 가이드
OpenTelemetry 분산 추적 데이터를 Jaeger UI와 Google Cloud Trace에서 활용하는 방법을 설명합니다.
📋 목차
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 기본 트레이스 조회
최근 트레이스 확인
- Time Range: 최근 1시간 선택
- 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
해결책:
- Jaeger 재시작: Cloud Run 서비스 재배포
- 네트워크 설정: VPC 커넥터 및 방화벽 규칙 확인
- 환경 변수:
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
해결책:
- API 활성화:
gcloud services enable cloudtrace.googleapis.com - 권한 부여:
roles/cloudtrace.agent역할 추가 - 샘플링 확인: 샘플링 비율이 너무 낮지 않은지 확인
문제 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