콘텐츠로 이동

Claude Code

cctrace는 Claude Code를 두 경로로 수집한다. Claude Code가 서버로 직접 보내는 OTEL 텔레메트리와 동기화 데몬이 올리는 세션 로그다. 둘 다 Claude Code 설정 파일에서 구성된다.

설정 기록 위치

cctrace init, cctrace env apply, cctrace profile add, cctrace config set은 프로필의 Claude 홈에 있는 설정 파일에 쓴다. 기본 프로필은 ~/.claude/settings.json, 이름 있는 프로필은 그 프로필이 가리키는 디렉터리. 프로필 참고.

cctrace가 관리하지 않는 키는 모두 유지된다. 쓰기 전에 스냅숏을 떠서 자기 키 외의 값이 바뀌면 쓰기를 거부하고, 유효한 JSON이 아닌 설정 파일도 덮어쓰지 않는다. 파일은 원자적으로 교체되며 권한은 0600.

OTEL 환경변수

env 아래 설정되는 변수:

변수 값
CLAUDE_CODE_ENABLE_TELEMETRY 1
OTEL_METRICS_EXPORTER otlp
OTEL_LOGS_EXPORTER otlp
OTEL_METRICS_INCLUDE_ACCOUNT_UUID 1
OTEL_EXPORTER_OTLP_PROTOCOL 프로필의 프로토콜, 기본 grpc. 사설 CA면 http/protobuf(아래)
OTEL_EXPORTER_OTLP_ENDPOINT 프로필의 OTEL 엔드포인트. 사설 CA면 OTLP/HTTP 포트(아래)
OTEL_EXPORTER_OTLP_HEADERS Authorization=Bearer <upload token>
OTEL_METRIC_EXPORT_INTERVAL 기본 60000 (options.metrics_export_interval)
OTEL_LOGS_EXPORT_INTERVAL 기본 5000 (options.logs_export_interval)
OTEL_BSP_MAX_QUEUE_SIZE 4096
OTEL_BSP_SCHEDULE_DELAY 5000
OTEL_BSP_MAX_EXPORT_BATCH_SIZE 512
OTEL_BSP_EXPORT_TIMEOUT 30000
OTEL_RESOURCE_ATTRIBUTES 프로필의 사용자 ID·이름·이메일·팀, URL 이스케이프(아래 예시)
NODE_EXTRA_CA_CERTS server.ca_cert_file. 사설 CA일 때만 씀(아래)
OTEL_RESOURCE_ATTRIBUTES=user.id=alice,user.name=Alice%20Doe,user.profile.email=alice@example.com,user.team=platform

프로필 값이 빈 속성은 생략된다.

이 키들은 cctrace 소유. 사용자가 직접 넣은 값이 있어도 init이 덮어쓰고 reset이 지운다. NODE_EXTRA_CA_CERTS만 예외다. 사내 프록시 CA로 이미 쓰이는 경우가 많아서, cctrace는 자기가 쓴 값을 cctrace 객체에 기록하고 그 값만 바꾸거나 지운다. 사용자가 직접 넣은 값은 남고, server.ca_cert_file과 다르면 init·config set이 그 값을 유지한 채 두 경로를 출력한다. 두 CA를 함께 쓰려면 한 PEM 파일로 합친다.

사설 CA

프로필에 server.ca_cert_file이 있고 OTEL 엔드포인트가 https://이면 cctrace는 Claude Code를 gRPC 포트 옆의 OTLP/HTTP 포트(4317→4318, 5317→5318)로 http/protobuf 전송하게 하고 NODE_EXTRA_CA_CERTS를 CA 파일로 지정한다. server.protocol은 저장된 대로 두고 init·config set이 이를 한 줄로 알린다. CA가 없거나 http://이면 바뀌는 것이 없다.

근거는 사설 CA 서버 인증서에 Claude Code 2.1.291(macOS)을 붙인 측정이다.

프로토콜 CA 전달 결과
grpc OTEL_EXPORTER_OTLP_CERTIFICATE(settings·프로세스 env) TLS 핸드셰이크 중단 -- CA 불신
grpc NODE_EXTRA_CA_CERTS(settings·프로세스 env) 같은 실패
http/protobuf OTEL_EXPORTER_OTLP_CERTIFICATE(settings env) 같은 실패
http/protobuf NODE_EXTRA_CA_CERTS(프로세스 env) 메트릭·로그 도착
http/protobuf NODE_EXTRA_CA_CERTS(settings env) 메트릭·로그 도착

grpc가 OS 키체인에 설치한 CA를 신뢰하는지는 측정하지 않았다.

세션 훅

세션 로그 동기화(options.sync_enabled)가 켜져 있으면 hooks 아래 훅 두 개가 matcher가 빈 그룹에 추가된다.

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/local/bin/cctrace sync --daemon --log-to-file --claude-dir /Users/alice/.claude --auto-profile --interval 1s"
          }
        ]
      }
    ],
    "SessionEnd": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/local/bin/cctrace sync --daemon --once --log-to-file --claude-dir /Users/alice/.claude --auto-profile",
            "async": true,
            "timeout": 30
          }
        ]
      }
    ]
  }
}
  • 명령은 훅을 쓴 바이너리의 절대 경로로 시작. 임시 디렉터리의 바이너리는 쓰지 않고 PATH에서 찾은 cctrace로 대체. 바이너리를 옮긴 뒤에는 cctrace env apply 실행
  • --claude-dir은 프로필의 Claude 홈, --auto-profile은 일치하는 프로필 선택. 플래그는 동기화 데몬 참고
  • SessionStart는 프로필의 데몬 시작. SessionEnd는 30초 제한의 비동기 동기화를 한 번 더 실행하고 데몬은 유지
  • 기존 훅은 유지. cctrace 훅이 이미 있으면 새로 추가하지 않고 그 자리에서 갱신

나중에 options.sync_enabled를 꺼도 훅은 지워지지 않는다. 이때 훅은 실행되지만 동기화 없이 종료한다. 훅 제거는 cctrace reset.

자가 복구 스탬프

cctrace는 생성한 내용의 해시를 담은 최상위 cctrace 객체도 쓴다. 동기화 데몬은 시작할 때마다 해시를 다시 계산하고, 업그레이드된 바이너리가 다른 변수나 훅을 쓸 상황이면 설정 파일을 다시 쓴다. reset이 이 객체를 지운다.

변경 반영 시점

Claude Code는 세션 시작 시점에 환경변수와 훅을 읽는다. init, env apply, config set 뒤에는 새 Claude Code 세션 시작. 이미 실행 중이던 세션은 텔레메트리를 보내지 않는다. 그 세션 로그는 데몬이 처음 발견한 지점부터만 올라간다.