Claude Code 사용량·성능 모니터링

Claude Code 사용량·성능 모니터링 (OpenTelemetry)

Claude Code 세션이 OpenTelemetry 표준으로 내보내는 메트릭·추적·로그를 활용해 사용량과 성능을 모니터링하는 방법을 다루는 페이지입니다. 데이터는 OTLP(HTTP/gRPC), Prometheus, 콘솔로 내보낼 수 있습니다. 텔레메트리는 기본 꺼져 있으며, CLAUDE_CODE_ENABLE_TELEMETRY=1로 켭니다. 이렇게 수집한 데이터를 멀티팀 조직에서 팀별·비용센터별로 집계할 수도 있습니다.

출처: 공식문서

본문

개요

텔레메트리는 세션 중 발생하는 요청·내부 이벤트·하드웨어 사용률 데이터를 수집해 내보냅니다. 스키마의 비안정(beta) 필드는 세부 구성 요소 이름이 바뀔 수 있습니다. 데이터는 네 가지 신호로 나뉩니다:

  • Metrics (카운터·게이지): 호출 로그 기반 카운터와 상시 측정 게이지
  • Traces + Spans: 전체 세션 트레이스와 그 안의 span
  • Logs: 특정 이벤트와 리소스 사용률 로그

내보낼 수 있는 것

신호 지표 내보내기 세부 정보
Metrics claude_code.session.active (게이지) OTLP, Prometheus, 콘솔, 파일 항상 캡처
Metrics claude_code.session.count (카운터) OTLP, Prometheus, 콘솔, 파일 항상 캡처
Logs/Events 요청 & 내부 이벤트 OTLP 로그 (otel), 콘솔 A·D 베타 클래스만, 명시적 옵트인
Traces + Spans 세션 & 완료된 요청 OTLP 트레이스 베타, 명시적 옵트인

기본 꺼짐: 모든 내보내기는 CLAUDE_CODE_ENABLE_TELEMETRY=1이 필요한 옵트인입니다. 로그 스키마는 아직 불안정하여 기본 로깅은 필터링됩니다.

시작하기 (Quick start)

로그로 텔레메트리를 켜고 확인하는 가장 빠른 경로:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=console
claude
claude -p "hello"

claude가 켜지면 콘솔 로그로 내보냅니다. claude -p "hello" 같은 일회성 세션은 명령이 끝나면 정리되므로 로그가 아예 안 나올 수 있습니다 — 세션을 켜둔 채 몇 초간 /status로 확인하세요.

조직에서 시그널 → 엔드포인트(Otel Collector 등) → 백엔드(Jaeger·Grafana Cloud·New Relic 등) 파이프라인이 흔히 쓰입니다. 외부 공급자는 OpenTelemetry Collector 또는 Langfuse@langfuse/vercel-ai SDK로 그릴 수 있습니다. 내부 개발은 Claude Code SDK languageModel 훅과 통합합니다.

[OTLP 엔드포인트 설정] 주 배출구인 OTLP는 환경변수 3개로 구성합니다. 기본값: OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318, OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318     # 기본값
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf             # 기본값
export OTEL_METRICS_EXPORTER=otlp

로그만으로 검증

무언가가 안 들어온다면 먼저 로그만 켭니다:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=console
claude

세션이 완료되면 콘솔에 이벤트가 나타납니다. 로그가 보이면 텔레메트리는 동작 중이라는 뜻 — 메트릭·추적이 안 보이는 것은 로그 스키마가 아닌 내보내기 구성 문제일 가능성이 높습니다.

OTLP gRPC 예시

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

시그널별 내보내기

커스텀 백엔드 구성을 위해 시그널별 내보내기·엔드포인트를 설정할 수 있습니다. OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTER로 시그널별 exporter를, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT·OTEL_EXPORTER_OTLP_METRICS_ENDPOINT·OTEL_EXPORTER_OTLP_LOGS_ENDPOINT로 시그널별 엔드포인트를 지정합니다(메트릭·로그 기본값 http://localhost:4318/v1/metrics·/v1/logs, 트레이스 http://localhost:4318/v1/traces).

메트릭과 커스텀 속성

핵심 메트릭

메트릭 유형 설명
claude_code.session.active Gauge 현재 활성 세션 수 (시작에서 종료까지)
claude_code.session.count Counter 새 세션 시작 수

커스텀 속성 (다중 팀)

OTEL_RESOURCE_ATTRIBUTES로 팀·부서·비용센터를 구분하는 사용자 지정 속성을 추가할 수 있습니다:

export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"

이 속성은 모든 메트릭·이벤트 측정점에 포함되어 팀별 필터·비용센터별 비용 추적·팀별 대시보드·알림에 씁니다. 커스텀 키는 vcs.* 저장소 속성을 제외하면 user.id·session.id 같은 표준 속성을 덮어쓰지 않습니다(키가 겹치면 내장 값 유지). 커스텀 키가 모든 시리즈 라벨이 되므로 고카디널리티 값은 백엔드 저장 비용이 늘어납니다. 리소스 블록에만 보내고 측정점 라벨에서 빼려면 OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=false.

⚠️ OTEL_RESOURCE_ATTRIBUTES는 쉼표 구분 key=value 쌍을 엄격히 요구합니다: 값에 공백 불가, US-ASCII만, 제어문자·공백·큰따옴표·쉼표·세미콜론·백슬래시 제외, 특수문자는 퍼센트 인코딩. 공백이 필요하면 _나 camelCase 사용. 값 인용부호는 이스케이프하지 않습니다(org.name="My Company"는 따옴표까지 리터럴 값).

트레이스: 트레이스·스팬·이벤트

트레이스와 스팬

기본 트레이스에서 세션 시작~종료 Span, 각 세션당 요청 서브스팬(토큰 수.count·duration.ms 속성 포함)을 배출합니다. 베타 추적에서 claude.code.execution 등 추가 스팬이 나옵니다.

스팬 유형 설명
claude_code.session Root 세션 전체 지속 시간
claude_code.request Child 세션당 완료된 요청 (하나 이상)
claude.code.execution (베타) Nested 요청을 세분화한 하위 스팬

컨텍스트 속성

컨텍스트 속성은 에이전트 학습·대시보드·비교에 쓰입니다. 예: 프로젝트 메타데이터 claude_code.project.directory·claude_code.project.repository.name, 세션 메타데이터 claude_code.session.id·claude_code.session.mode·claude_code.session.optout(프라이버시 설정 적용 여부), 요청 메타데이터 claude_code.request.agent·claude_code.request.cost_estimate_min·claude_code.request.cost_estimate_max·claude_code.request.total_cost_usd(0=계산 안 되거나 무료 플랜)·claude_code.request.url_override, 모델 및 토큰 claude_code.request.model·claude_code.request.tokens.in·claude_code.request.tokens.out·claude_code.request.tokens.cache_write·claude_code.request.tokens.cache_read·claude_code.request.stop_reason.

스팬 속성 (베타)

베타 추적으로 배출되는 추가 속성(불안정 스키마): claude.code.event.context_management.ratio·.allowed_fraction, claude.code.request.duration, claude.code.request.stop_reason, claude.code.request.status, claude.code.request.tokens_in.total, claude.code.zoom.base_tokens, claude.code.zoom.actual_tokens. claude.code.message.usage.input_tokens·claude.code.message.usage.output_tokens·claude.code.message.usage.cache_creation_input_tokens·claude.code.message.usage.cache_read_input_tokens 등 사용량 스팬도 있습니다. 콘텐츠 포함 속성(new_context, system_prompt_preview, user_system_prompt, tool_input, response.model_output)은 상세 베타 추적 중에만 배출되며 안정 스키마가 아닙니다. user_system_prompt는 추가로 OTEL_LOG_USER_PROMPTS=1이 필요하고, SDK systemPrompt 옵션 또는 --system-prompt·--append-system-prompt 플래그로 준 시스템 프롬프트만 담으며(기본 60KB 제한), 세션당 한 번 배출됩니다.

동적 헤더

동적 인증이 필요한 엔터프라이즈 환경은 헤더를 생성하는 스크립트를 구성할 수 있습니다. 동적 헤더는 http/protobuf·http/json 프로토콜에만 적용되고, grpc는 정적 헤더 변수(OTEL_EXPORTER_OTLP_HEADERS 및 시그널별 변형)만 씁니다. .claude/settings.json에:

{
  "otelHeadersHelper": "/path/to/generate-otel-headers.sh"
}

값은 실행 파일 경로(공백 포함 가능) 또는 인자가 있는 셸 명령줄. Windows는 항상 셸을 거치므로 JSON 값 안의 공백 경로를 인용하세요. 스크립트는 HTTP 헤더를 나타내는 문자열 key-value의 유효한 JSON을 출력해야 합니다:

#!/bin/bash
echo "{\"Authorization\": \"Bearer $(get-token.sh)\", \"X-API-Key\": \"$(get-api-key.sh)\"}"

실패하거나 형식이 맞지 않으면 /status 출력, --debug·/debug 시 디버그 로그, -p 비대화형 세션의 stderr에 보고됩니다. 헬퍼는 시작 시·주기적으로 실행돼(기본 29분 간격, CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS로 조정) 토큰 갱신을 지원합니다.

예시 구성

claude 실행 전에 환경변수를 설정하세요. 적용 확인은 세션 시작 후 백엔드에서 claude_code.session.count 메트릭을 봅니다.

1초 간격 콘솔 디버깅:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=1000

gRPC OTLP:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

Prometheus (http://localhost:9464/metrics 스크레이프):

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=prometheus

다중 exporter:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console,otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json

메트릭·로그를 서로 다른 엔드포인트로:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://metrics.example.com:4318
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://logs.example.com:4317

트레이스·스팬 활성화 (베타)

베타 추적을 켜려면 CLAUDE_CODE_ENABLE_TELEMETRY=1 위에 OTEL_TRACES_EXPORTER=otlp와 트레이스 엔드포인트를 설정합니다. 베타는 스키마 변경 가능성이 있으며, 대규모가 아닌 소규모 배포에 적합합니다. 구조: 루트 스팬 claude_code.session(세션 지속), 자식 claude_code.request(완료 요청), claude.code.execution 베타 하위 스팬(요청 세분화). 자세한 못지 않은 span 세부사항은 비안정 스키마입니다.

mTLS (베타)

OTLP 엔드포인트에 대한 상호 TLS(mTLS)를 베타로 지원합니다. .claude/settings.json에:

{
  "otelMtlsClientCert": "/path/to/client.crt",
  "otelMtlsClientKey": "/path/to/client.key",
  "otelMtlsServerCert": "/path/to/server-ca.crt"
}

두 인증서(클라이언트 cert를 줄 때 클라이언트 key)는 함께 지정해야 합니다. 환경변수로도 설정 가능합니다: CLAUDE_CODE_OTEL_MTLS_CLIENT_CERT, CLAUDE_CODE_OTEL_MTLS_CLIENT_KEY, CLAUDE_CODE_OTEL_MTLS_SERVER_CERT. mTLS는 자동으로 특정 OTLP 내보내기에만 적용되며 설정을 쓰려면 재시작이 필요할 수 있습니다. 클라이언트 인증서는 시스템 인증서 저장소에서 로드됩니다.

이벤트 (로그 / 베타)

상세 로깅은 베타이며 명시적 옵트인이 필요합니다. A 클래스(OBSERVABILITY_ENABLED_MS·OBSERVABILITY_PROMPT·CLAUDE_CODE_ENABLE_DEBUG_OUTPUT·클래스 A 로그를 허용하는 --verbose)와 D 클래스(앱 로그, --debug)만 로그 스키마로 우선 배출됩니다. 로그 기반 추적 지표는 호출 로그에서 파생됩니다. 기본 오픈텔레메트리 로그 스키마를 넘어 일반 로그를 위해선 OTEL_LOGS_EXPORTER 구성과 베타 옵션이 필요합니다.

저장소 속성

vcs.* 속성이 저장소 메타데이터를 운반합니다. 일부는 OTLP 리소스 블록에서만 나오고, 일부는 user.id·session.id처럼 리소스 및 데이터포인트/이벤트 속성으로 나옵니다. 각 저장소 이름은 리포지토리 원격 URL에서 파생됩니다. 사용자 지정 속성과 달리 vcs.* 속성은 여러 저장소를 동시에 작업할 때 데이터 포인트마다 값이 달라, 신중하게 사용해 카디널리티를 피하세요.

알려진 제한 사항

Konfig 시그널은 그리기 어려울 수 있고, 선택한 사용자 지정 속성은 리소스 블록으로 그룹화되며 청구·지출 요약에 포함되지 않을 수 있습니다.

더 알아보기