CCAR-P 개념 카드

■ observability 세 신호

metrics · log events · traces3.4 본편

표시가 없는 문장은 공식 문서에서 확인한 내용이에요. 다른 표시는 읽는 법

왜 배우나 — 시험이 요구하는 것

시험 목표 3.4 대규모 관측 · D3 연결 19%
Analyze observability challenges and select monitoring strategies at scale

이 개념으로 푸는 판단 (할 수 있어야 하는 것)

  • 3.4① 수천 세션 중 일부만 30초씩 걸린다 — 모델 호출인지 CRM 도구인지 무엇으로 찾나? — 관측 신호 고르기 (메트릭 · 로그 이벤트 · 트레이스)
  • 4.6① 비용 급증 알림이 떴다 — 대시보드만 보면 원인이 나오나? (빈 목표) — 모니터링(무엇이 움직였나)과 관측(왜 — 실행 추적)을 구분해 쓰기

한눈에

에이전트 텔레메트리는 서로 독립인 세 신호다. 켜는 스위치와 내보내는 곳이 따로라 필요한 것만 켠다 (Claude Code · Agent SDK 기준. 직접 API 앱은 같은 틀로 내가 계측 — 업계 일반)

  • 메트릭 : 카운터(토큰 · 비용 · 세션 · 코드 줄 · 도구 결정)다. 대시보드, 추세, 알림에 쓴다. "무엇이 움직였나" 에 답한다
  • 로그 이벤트 : 프롬프트 · API 요청 · API 오류 · 도구 결과마다 남기는 구조화 기록이다. 감사 · 검색에 쓴다
  • 트레이스 : 한 턴(interaction) 아래 모델 요청 · 도구 호출 · hook span 을 붙인다. "이 실행의 어느 단계가 느린가" 에 답한다 (베타)

비유 Prometheus(메트릭), 액세스 로그(이벤트), X-Ray/Jaeger 분산 추적(트레이스)에 해당한다

에이전트 텔레메트리는 메트릭(무엇이 움직였나)·로그 이벤트(감사·검색)·트레이스(어느 단계가 느린가)의 독립된 세 신호이고 각각 따로 켠다는 그림.
그림으로 보기 (AI 생성 · Codex · 누르면 크게)

ELI5

가게를 살필 때 쓰는 도구 세 개예요.

  • 계산대 숫자판은 오늘 손님이 몇 명인지, 매출이 얼마인지 보여 줘요.
  • 방문 일지는 누가 언제 무엇을 했는지 한 줄씩 적어요.
  • 손님 한 명을 따라가는 영상은 어디서 오래 기다렸는지 보여 줘요.
  • "왜 이 손님만 오래 걸렸지?"는 영상을 봐야 알아요.

개념 설명

영상 — 어느 단계가 느린지, 무엇을 보면 알까? (약 42초 · 소리 없음 · 자막). 실행 10건과 막대 길이(도구 호출이 길다는 것)는 그림용 가정 — 3.1초만 카드 흐름 값 작은 화면에서는 전체화면(⛶)으로 보세요.

원리

세 신호는 서로 다른 질문에 답한다

  • 메트릭 : 숫자를 시간에 따라 모은다. "얼마나 · 언제부터 · 어느 모델·팀이"에 답한다. 추세·알림에 강하다. 한 실행 안의 순서는 모른다.
  • 로그 이벤트 : 일이 생길 때마다 한 건씩 구조화해 기록한다(프롬프트 · API 요청 · API 오류 · 도구 결과 · 도구 결정). "무엇이 일어났나"에 답한다. 감사·검색에 쓴다.
  • 트레이스 : 한 턴을 뿌리(span)로 두고 그 아래 모델 호출·도구 호출·hook 을 자식으로 붙인다. "이 실행에서 어느 단계가 시간을 먹었나"에 답한다.

Claude Code · Agent SDK 에서

  • SDK 는 스스로 텔레메트리를 만들지 않는다. 안에서 돌리는 CLI 가 OpenTelemetry 로 내보낸다. 설정은 환경변수로 한다.
  • 세 신호는 스위치와 exporter 가 따로다. 그래서 필요한 것만 켠다.
  • 트레이스는 베타다(별도 스위치). 서브에이전트 span 은 부모의 도구 span 아래 붙는다. 그래서 위임(delegation) 사슬이 한 트레이스에 담긴다.
  • 앱이 이미 트레이스를 쓰고 있으면 TRACEPARENT 로 이어 붙인다. 그러면 앱 트레이스 안에 에이전트 실행이 보인다.

표준 지표와 비용

  • OTel GenAI 표준(v1.37.0) 지표 다섯 개에는 비용이 없다. 비용은 Claude Code 고유 지표이고 근사치다.

내보내기의 함정

  • 실패하면 조용히 버린다(에이전트는 정상). 주기적으로 묶어 보내서 짧은 작업·강제 종료 때 유실된다.

규칙과 판단

트레이스만 비면 베타 변수를, 전부 비면 켰는지와 exporter 를 보고, 둘 다 했는데 비면 내보내기 실패가 조용히 삼킨 것이니 진단 변수로 확인하는 결정 나무.
그림으로 보기 (AI 생성 · Codex · 누르면 크게)

갈림길

①② 어느 신호 [3.4①] [4.6①]

무엇을 알고 싶나?
무엇이 움직였나

메트릭

카운터(토큰 · 비용 · 세션 · 코드 줄 · 도구 결정)를 모은다. 대시보드, 추세, 알림에 쓴다

어느 단계가 느린가

트레이스

claude_code.interaction 루트 아래에 claude_code.llm_request(모델명·지연(latency)·토큰)와 claude_code.tool(권한 대기 span + 실행 span)이 붙는다

감사·검색

로그 이벤트

프롬프트 · API 요청 · API 오류 · 도구 결과마다 구조화 기록을 남긴다

②③ 비용 숫자 [4.6①]

비용 숫자를 어디서 보나?
Claude Code 메트릭 (claude_code.cost.usage)

근사치

비용(USD)은 근사치다. 실제 청구액은 Console 등 제공자 기준이다

표준 OTel GenAI 지표

비용은 없다

비용은 Claude Code 고유 지표(claude_code.cost.usage)에만 있다

④ 빈 대시보드 [3.4①]

무엇이 비었나?
트레이스만

베타 변수

트레이스는 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 도 켜야 한다

전부
켰나?CLAUDE_CODE_ENABLE_TELEMETRY=1 + exporter 둘 다
아니오 (변수 자체를 안 켰다)

켠다

CLAUDE_CODE_ENABLE_TELEMETRY=1 과 신호별 exporter 를 설정한다

켰는데 exporter 가 없다

아무것도 안 나간다

exporter 를 하나도 안 고르면 켜도 아무것도 안 나간다

예 (둘 다)

조용한 실패

내보내기 실패는 조용하다. 에이전트는 정상이고 데이터만 버린다. 진단은 CLAUDE_CODE_OTEL_DIAG_STDERR=1 로 한다. 프로세스가 죽으면 버퍼에 남은 것은 유실된다

흐름

그림 속 이름·금액·시간·토큰 수는 예시예요. 공식 한도·동작은 카드 본문 값이 기준.

장면 글로 보기

칸 : 에이전트 → 버퍼 → 수집기

블록 : 메트릭, 로그 이벤트, 트레이스

규칙 (버퍼) : 기본 주기 : 메트릭 60초 · 트레이스·로그 5초

질문 : 대시보드가 비어 있으면 에이전트가 안 돈 걸까?

① 켜고 들어오는지 확인한다 ✓

  1. 시작 : 에이전트 — 쪽지 : CLAUDE_CODE_ENABLE_ / TELEMETRY=1 / + 신호별 exporter
  2. 메트릭 : 메트릭 → 버퍼 : 신호별 exporter 로 모은다 — 쪽지 : claude_code.cost.usage / +0.04 USD
  3. 타이머 : 버퍼 : 메트릭 60초
  4. 메트릭 : 버퍼 → 수집기 : 실제로 들어오는지 확인한다 — 쪽지 : 수집기 수신 / cost.usage 1건
  5. 끝 : 켠 뒤에는 수집기에 실제로 들어오는지 확인한다

② 내보내기 실패 ≠

  1. 시작 : 에이전트 — 쪽지 : CLAUDE_CODE_ENABLE_ / TELEMETRY=1 / + 신호별 exporter
  2. 메트릭 : 메트릭 → 버퍼 : 에이전트는 정상이다 — 쪽지 : claude_code.cost.usage / +0.04 USD
  3. 타이머 : 버퍼 : 메트릭 60초
  4. 실패 : 버퍼 : 내보내기 실패는 조용하다 — 쪽지 : export 오류 / (화면엔 안 찍힘)
  5. 건너뜀 : 수집기
  6. 끝 : 에이전트는 정상이고 데이터만 버린다. 진단은 CLAUDE_CODE_OTEL_DIAG_STDERR=1 로 한다

③ 프로세스가 죽는다 ≠

  1. 시작 : 에이전트 — 쪽지 : CLAUDE_CODE_ENABLE_ / TELEMETRY=1 / + 신호별 exporter
  2. 트레이스 : 트레이스 → 버퍼 : 5초마다 내보낸다 — 쪽지 : span claude_code.tool / 3.1초
  3. 죽음 : 에이전트 : 주기 전에 강제 종료된다 — 쪽지 : kill -9
  4. 건너뜀 : 수집기
  5. 끝 : 프로세스가 죽으면 버퍼에 남은 것은 유실된다

나머지 규칙

  1. 무엇을 기록하나(본문 opt-in · 사용자 귀속)는 ■ 텔레메트리 기록 범위 에 있다

규칙 원문 ①②③④ (갈림길로 그린 규칙)
  1. 일부 실행만 느리고 모델인지 도구인지 모르면 트레이스를 본다. claude_code.interaction 루트 아래에 claude_code.llm_request(모델명·지연·토큰)와 claude_code.tool(권한 대기 span + 실행 span)이 붙는다 [3.4①]

    서브에이전트의 span 은 부모의 claude_code.tool span 아래 붙는다. 그래서 위임(delegation) 사슬이 한 트레이스에 담긴다

    여러 호출을 한 줄로 보려면 session.id 로 거른다. 내 앱 트레이스 안에 넣으려면 W3C trace context(TRACEPARENT)를 쓴다. 이것은 자동 전파된다(SDK · claude -p 만, 대화형 CLI 는 무시)

  2. 추세와 비용 알림은 메트릭으로 본다. 토큰은 종류·사용자·팀·모델별로 쪼개 본다. 비용(USD)은 근사치다. 실제 청구액은 Console 등 제공자 기준이다 [4.6①]

  3. 표준 OTel GenAI 지표(semconv v1.37.0)는 다섯이다. 비용은 없다. 비용은 Claude Code 고유 지표(claude_code.cost.usage)에만 있다

    • 토큰 사용량
    • 작업 시간
    • 서버 요청 시간
    • 출력 토큰당 시간
    • TTFT
  4. 켜기 : CLAUDE_CODE_ENABLE_TELEMETRY=1 과 신호별 exporter 를 설정한다. 트레이스는 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 도 켜야 한다

    exporter 를 하나도 안 고르면 켜도 아무것도 안 나간다. 베타 플래그는 트레이스에만 필요하다(메트릭·이벤트는 없어도 된다)

    내보내기 실패는 조용하다. 에이전트는 정상이고 데이터만 버린다. 그래서 수집기에 실제로 들어오는지 확인한다. 진단은 CLAUDE_CODE_OTEL_DIAG_STDERR=1 로 한다

    기본 주기는 메트릭 60초, 트레이스·로그 5초다. 프로세스가 죽으면 버퍼에 남은 것은 유실된다

더 깊이 : 판단 규칙 · 상황 변수 (설명)

판단 규칙

조건답근거
일부 세션만 느리다. 모델인지 도구인지 모른다트레이스를 본다 (interaction 아래 llm_request · tool span)monitoring-usage · agent-sdk/observability
서브에이전트까지 포함한 위임 사슬을 보고 싶다트레이스를 본다. 서브 span 이 부모 tool span 아래 붙는다agent-sdk/observability
비용·토큰 추세와 어느 모델·팀인지를 본다메트릭을 본다 (claude_code.token.usage · claude_code.cost.usage)monitoring-usage
청구 금액이 정확해야 한다제공자(Console 등) 청구 데이터를 쓴다monitoring-usage "Cost metrics are approximations."
표준 OTel GenAI 지표만으로 비용까지 보려 한다안 된다. 표준 다섯 지표에는 비용이 없다OTel semconv v1.37.0 gen-ai-metrics
누가 어떤 도구를 불렀나로그 이벤트를 본다 (■ 텔레메트리 기록 범위)agent-sdk/observability
텔레메트리를 켰는데 수집기에 안 들어온다진단 변수로 exporter 오류를 확인한다 (기본은 조용히 버린다)agent-sdk/observability
에이전트 실행을 앱 트레이스 안에 넣으려 한다W3C trace context 가 자동 전파된다 (SDK · claude -p)agent-sdk/observability

상황 변수

변수값답 쪽등급근거
질문 모양"얼마나 · 언제부터 늘었나"메트릭agent-sdk/observability
질문 모양"이 실행의 어디가 느린가"트레이스agent-sdk/observability
질문 모양"누가 무엇을 했나"로그 이벤트monitoring-usage
트레이스 스위치안 켰다 (CLAUDE_CODE_ENHANCED_TELEMETRY_BETA)span 이 없다. 메트릭·이벤트만 나온다agent-sdk/observability
실행 방식대화형 CLI들어오는 TRACEPARENT 를 무시한다agent-sdk/observability
작업 길이메트릭 주기(60초)보다 짧다종료 flush 에 기댄다. 강제 종료면 유실된다계산뒤집히는 때 3
수집기 공유에이전트 여러 개가 한 수집기를 쓴다service.name · resource attribute 로 구분한다agent-sdk/observability
앱 형태Claude Code·SDK 가 아닌 직접 API 앱이다같은 세 신호 틀로 내가 계측한다업계 일반—

연습 문제

운영팀이 CLAUDE_CODE_ENABLE_TELEMETRY=1 과 exporter 를 설정해 텔레메트리를 켰다켰음. 그런데 일주일째 대시보드에 메트릭도 이벤트도 하나도 안 뜬다전부 비었음. 에이전트는 평소처럼 잘 돈다. 누군가 "오류가 0건이니 문제 없다"고 한다. 먼저 무엇을 의심해야 하나?

시험 대비

함정

  • "p99 대시보드(메트릭)를 보면 원인이 나온다" 는 함정이다. 메트릭은 무엇이 움직였는지까지만 보여 준다. 어느 단계인지는 트레이스로 본다
  • "OTel GenAI 표준 지표로 토큰·비용·지연을 한 번에 본다" 는 함정이다. 표준에는 비용이 없다
  • 비용 메트릭을 청구 근거로 쓰는 것은 함정이다. 비용 메트릭은 근사치다
  • "대시보드에 아무것도 안 뜨니 문제 없다" 는 함정이다. 내보내기 실패가 조용히 삼켰을 수 있다
  • 트레이스를 정식 기능으로 가정하는 것은 함정이다. 트레이스는 베타다. span 이름·속성이 바뀔 수 있다

신호

"The CLI exports three independent OpenTelemetry signals."

"Each user prompt starts a claude_code.interaction root span. API calls, tool calls, and hook executions are recorded as its children."

"Cost metrics are approximations."

"The CLI fails silently on export errors by default"

"Adding full production tracing let us diagnose why agents failed and fix issues systematically." (멀티 에이전트 연구 글)

보통은 어느 단계가 느린지 트레이스로 보지만, 어느 팀·모델이 늘었는지는 메트릭, span 이 안 보이면 베타 스위치, 60초보다 짧은 작업은 내보내기 주기를 낮춘다.
그림으로 보기 (AI 생성 · Codex · 누르면 크게) — 자세한 조건은 아래 '더 깊이'에 있어요
더 깊이 : 뒤집히는 때 · 오답 재료 (설명)

뒤집히는 때

1. 메트릭이 답인 때

  • 조건 : "지난주보다 토큰 비용이 30% 늘었다. 어느 팀·어느 모델인가?" 를 묻는다.
  • 판단 : 한 실행의 순서가 아니라 집계를 묻는다. 그래서 메트릭을 팀·모델로 쪼갠다. 트레이스는 원인 실행을 찾은 다음 단계에 쓴다.
  • 근거 : monitoring-usage (type · user · team · model 로 분해)

2. 트레이스를 골랐는데 span 이 안 보이는 때

  • 조건 : 트레이스 exporter 만 설정하고 베타 스위치를 안 켰다. 또는 대화형 CLI 세션에서 앱의 TRACEPARENT 를 기대한다.
  • 판단 : 트레이스는 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 이 필요하다. 대화형 CLI 는 들어오는 trace context 를 무시한다. "트레이스가 답"인 지문에서도 설정 전제가 빠지면 보기가 틀릴 수 있다.
  • 근거 : agent-sdk/observability

3. 짧은 작업의 메트릭이 비는 때

  • 조건 : 20초짜리 배치 작업을 컨테이너로 돌리고, 끝나면 바로 죽인다.
  • 계산 : 메트릭 기본 주기 60초 > 작업 20초 다. 그래서 첫 주기 전에 끝난다. 정상 종료면 flush 를 시도하지만 짧은 시간 제한이 있다. 강제 종료면 버퍼가 통째로 유실된다.
  • 처방 : 내보내기 주기를 낮춘다 (예 OTEL_TRACES_EXPORT_INTERVAL 1000ms 류). 정상 종료한다.
  • 등급 : 계산 (60초 · 5초 · 유실 규칙은 확인)
  • 근거 : agent-sdk/observability

4. "아무것도 안 뜬다 = 문제 없음"이 틀리는 때

  • 조건 : 대시보드에 오류 0, 트레이스 0 이 뜬다.
  • 판단 : exporter 오류는 기본적으로 조용히 버려진다. 먼저 수집기에 알려진 이벤트 하나가 들어오는지 확인한다(양성 대조).
  • 근거 : agent-sdk/observability

오답 재료

오답왜 끌리나왜 틀리나등급근거
"토큰·지연(latency) 대시보드(메트릭) p99 를 보면 원인이 나온다"p99 가 튄 게 보이니까메트릭은 무엇이 움직였는지까지만 보여 준다. 어느 단계인지는 트레이스로 본다agent-sdk/observability
"OTel GenAI 표준 지표 세트로 토큰·비용·지연을 한 번에"표준이면 다 있을 것 같다표준 v1.37.0 에는 비용 지표가 없다OTel semconv v1.37.0 gen-ai-metrics
"비용 메트릭을 청구 대사에 쓴다"USD 단위로 나오니까근사치다. 실제 청구액은 제공자 기준이다monitoring-usage
"알림 임계값을 더 촘촘히 하면 원인을 안다"빨리 알면 빨리 고친다알림은 무엇이 움직였는지만 알려 준다. 원인은 실행 추적으로 찾는다업계 일반목록 4.6① 매력적인 오답
"로그를 다 남기면 트레이스는 필요 없다"로그에 다 있을 것 같다이벤트는 건별 기록이다. 단계 간 부모-자식·시간 관계는 트레이스로 본다monitoring-usage
"서브에이전트 호출은 별도 트레이스로 흩어진다"다른 에이전트니까부모 tool span 아래 붙어 한 트레이스에 담긴다agent-sdk/observability

참고

더 깊이 : 출처 · 상태 · 미해결 (참고)

출처

상태

  • 업계 일반 1줄(직접 API 앱 계측)

미해결

  1. OTel GenAI semconv 는 v1.37.0 만 확인했다. 더 새 버전에 비용 지표가 생겼는지는 보지 않았다 (목록 3.4① 도 "새 저장소 최신 판은 근거 확인 필요").
  2. 직접 Messages API 로 만든 앱의 observability(관측 가능성 : 요청 ID · usage 필드 기록 등)는 받은 원문 밖이다. 업계 일반으로만 둔다.
  3. Managed Agents 에는 Console 세션 뷰어(타임라인 · 도구별 통계 · 스레드별 활동)가 있다 (릴리스 노트). 이 카드의 OTel 세 신호와의 관계는 원문을 안 받아 확인하지 못했다.
  4. 조직 비용 분해(Usage & Cost Admin API)는 목록 4.6① 소재다. 원문을 받지 않았다. 4.6 카드 몫이다.