AI 코딩 어시스턴트를 위한 통합 로컬 관측성 (Observability) 도구
요약
AI Observer는 Claude Code, Gemini CLI, OpenAI Codex CLI와 같은 로컬 AI 코딩 도구의 사용량을 모니터링하기 위한 OpenTelemetry 호환 관측성 도구입니다. 단일 바이너리 형태로 제공되어 외부 의존성 없이 토큰 사용량, 비용, 지연 시간 및 에러율을 실시간 대시보드에서 통합 관리할 수 있습니다.
핵심 포인트
- Claude, Codex, Gemini 등 다양한 AI 코딩 도구의 토큰 사용량 및 비용 추적 지원
- OpenTelemetry(OTLP) 표준 프로토콜을 지원하여 데이터 수집 및 호환성 확보
- DuckDB 기반의 빠른 분석과 단일 바이너리/Docker를 통한 간편한 셀프 호스팅
- 개인정보 보호를 위해 모든 텔레메트리 데이터를 로컬에 유지
AI 코딩 어시스턴트를 위한 통합 로컬 관측성 (Observability)
AI Observer는 Claude Code, Gemini CLI, OpenAI Codex CLI와 같은 로컬 AI 코딩 도구를 모니터링하기 위해 특별히 설계된, 셀프 호스팅(self-hosted)이 가능한 단일 바이너리 형태의 OpenTelemetry 호환 관측성 백엔드(observability backend)입니다.
실시간 업데이트와 외부 의존성 제로를 통해, 모든 AI 코딩 어시스턴트의 토큰 사용량, 비용, API 지연 시간 (latency), 에러율 및 세션 활동을 하나의 통합된 대시보드에서 추적하세요.
AI 코딩 어시스턴트는 필수적인 개발 도구가 되고 있지만, 그 동작 방식과 비용을 이해하는 것은 여전히 과제로 남아 있습니다:
가시성 (Visibility): 세션 전반에 걸쳐 AI 도구가 어떻게 작동하는지 정확히 확인
비용 추적 (Cost tracking): 토큰 사용량과 API 호출을 모니터링하여 지출 파악
디버깅 (Debugging): 에러 및 느린 응답을 특정 상호작용으로 추적
개인정보 보호 (Privacy): 텔레메트리 (telemetry) 데이터를 로컬에 유지 — 제3자 서비스가 필요 없음
멀티 도구 지원 (Multi-tool support) — Claude Code, Gemini CLI, OpenAI Codex CLI와 연동 가능
실시간 대시보드 (Real-time dashboard) — 텔레메트리가 도착함에 따라 WebSocket을 통해 라이브 업데이트 제공
커스터마이징 가능한 위젯 (Customizable widgets) — 다양한 위젯 유형을 갖춘 드래그 앤 드롭 대시보드 빌더
이력 가져오기 (Historical import) — 비용 계산 기능과 함께 로컬 JSONL/JSON 파일에서 과거 세션 가져오기
비용 추적 (Cost tracking) — Claude, Codex, Gemini 전반에 걸친 67개 이상의 모델에 대한 내장 가격 데이터 포함
빠른 분석 (Fast analytics) — 대규모 데이터셋에 대한 즉각적인 쿼리를 위해 DuckDB 기반 저장소 사용
단일 바이너리 (Single binary) — 프론트엔드가 내장된 약 54MB의 실행 파일 하나로 구성 — 외부 의존성 없음
멀티 아키텍처 Docker (Multi-arch Docker) — linux/amd64 및 linux/arm64를 위한 즉시 실행 가능한 약 97MB 이미지
OTLP 네이티브 (OTLP-native) — 표준 OpenTelemetry 프로토콜 (OTLP) 수집 (HTTP/JSON 및 HTTP/Protobuf)
- Import 명령 — 로컬 AI 도구 파일에서 과거 세션 데이터 가져오기
- Export 명령 — 아카이빙 및 공유를 위해 텔레메트리 데이터를 Parquet 파일로 내보내기
- 가격 시스템 (Pricing System) — Claude, Codex 및 Gemini 모델에 대한 비용 계산
docker run -d \
-p 8080:8080 \
-p 4318:4318 \
...
대시보드: http://localhost:8080
데이터 영속성 (Data Persistence)을 위한 로컬 디렉토리 사용:
# 로컬 데이터 디렉토리 생성
mkdir -p ./ai-observer-data
# 로컬 볼륨 마운트와 함께 실행
...
이렇게 하면 DuckDB 데이터베이스가 로컬의 ./ai-observer-data 디렉토리에 저장되어, 백업하거나 검사하기가 용이해집니다.
brew tap tobilg/ai-observer
brew install ai-observer
ai-observer
Releases에서 사용 중인 플랫폼에 맞는 최신 릴리스를 다운로드한 후, 다음을 실행하세요:
./ai-observer
git clone https://github.com/tobilg/ai-observer.git
cd ai-observer
make setup # 의존성 설치
...
| 변수 (Variable) | 기본값 (Default) | 설명 (Description) |
|---|---|---|
AI_OBSERVER_API_PORT | 8080 | HTTP 서버 포트 (대시보드 + API) |
AI_OBSERVER_OTLP_PORT | 4318 | OTLP 수집 (Ingestion) 포트 |
AI_OBSERVER_DATABASE_PATH | ./data/ai-observer.duckdb (binary) 또는 /app/data/ai-observer.duckdb (Docker) | DuckDB 데이터베이스 파일 경로 |
AI_OBSERVER_FRONTEND_URL | http://localhost:5173 | 허용된 CORS 오리진 (개발 모드) |
AI_OBSERVER_LOG_LEVEL | INFO | 로그 레벨: DEBUG, INFO, WARN, ERROR |
CORS 및 WebSocket 오리진은 AI_OBSERVER_FRONTEND_URL과 더불어 http://localhost:5173 및 http://localhost:8080을 허용합니다. 커스텀 UI 오리진을 제공할 때는 AI_OBSERVER_FRONTEND_URL을 설정하세요.
ai-observer [command] [options]
명령어 (Commands):
| 명령어 (Command) | 설명 (Description) |
|---|---|
import | AI 도구 파일로부터 로컬 세션 가져오기 |
export | 텔레메트리 (Telemetry) 데이터를 Parquet 파일로 내보내기 |
delete | 데이터베이스에서 텔레메트리 데이터 삭제 |
setup | AI 도구들을 위한 설정 안내 표시 |
serve | OTLP 서버 시작 (명령어가 없을 경우 기본값) |
글로벌 옵션 (Global Options):
| 옵션 (Option) | 설명 (Description) |
|---|---|
-h, --help | 도움말 메시지를 표시하고 종료 |
-v, --version | 버전 정보를 표시하고 종료 |
예시 (Examples):
# 서버 시작 (기본값, 명령어 불필요)
ai-observer
# 버전 표시
...
로컬 AI 코딩 도구 파일로부터 과거 세션 데이터를 AI Observer로 가져옵니다.
ai-observer import [claude-code|codex|gemini|all] [options]
| 옵션 | 설명 |
|---|---|
--from DATE | DATE (YYYY-MM-DD) 이후의 세션만 가져옵니다 |
--to DATE | DATE (YYYY-MM-DD) 이전의 세션만 가져옵니다 |
--force | 이미 가져온 파일들을 다시 가져옵니다 |
--dry-run | 변경 사항을 적용하지 않고 무엇이 가져와질지 보여줍니다 |
--skip-confirm | 확인 프롬프트를 건너뜁니다 |
--purge | 가져오기 전에 해당 기간 내의 기존 데이터를 삭제합니다 |
--pricing-mode MODE | Claude를 위한 비용 계산 모드: auto (기본값), calculate, display |
--verbose | 상세한 진행 과정을 보여줍니다 |
파일 위치:
| 도구 | 기본 위치 |
|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
| ... | |
환경 변수로 재정의할 수 있습니다: AI_OBSERVER_CLAUDE_PATH, AI_OBSERVER_CODEX_PATH, AI_OBSERVER_GEMINI_PATH |
예시:
# 모든 도구로부터 가져오기
ai-observer import all
# 특정 날짜 범위에서 Claude 데이터 가져오기
...
상세한 문서는 docs/import.md를, 비용 계산에 대한 자세한 내용은 docs/pricing.md를 참조하세요.
텔레메트리 (Telemetry) 데이터를 선택 사항인 DuckDB 뷰 (Views) 데이터베이스가 포함된 휴대 가능한 Parquet 파일로 내보냅니다.
ai-observer export [claude-code|codex|gemini|all] --output <directory> [options]
| 옵션 | 설명 |
|---|---|
--output DIR | 출력 디렉토리 (필수) |
--from DATE | 시작 날짜 필터 (YYYY-MM-DD) |
--to DATE | 종료 날짜 필터 (YYYY-MM-DD) |
--from-files | 데이터베이스 대신 원시 JSON/JSONL 파일에서 읽어옵니다 |
--zip | 내보낸 파일들을 하나의 ZIP 아카이브로 생성합니다 |
--dry-run | 무엇이 내보내질지 미리 보여줍니다 |
--verbose | 상세한 진행 과정을 보여줍니다 |
--yes | 확인 프롬프트를 건너뜁니다 |
출력 파일:
traces.parquet — 모든 트레이스 (Trace)/스팬 (Span) 데이터
logs.parquet — 모든 로그 (Log) 레코드
metrics.parquet — 모든 메트릭 (Metric) 데이터 포인트
ai-observer-export-{SOURCE}-{RANGE}.duckdb — 상대 경로가 포함된 뷰 (Views) 데이터베이스
예시:
# 데이터베이스에서 모든 데이터 내보내기
ai-observer export all --output ./export
# 날짜 필터를 사용하여 Claude 데이터 내보내기
...
상세한 문서는 docs/export.md를 참조하세요.
시간 범위를 지정하여 데이터베이스에서 텔레메트리 (Telemetry) 데이터를 삭제합니다.
ai-observer delete [logs|metrics|traces|all] --from DATE --to DATE [options]
| 옵션 | 설명 |
|---|---|
--from DATE | 시작 날짜 (YYYY-MM-DD, 필수) |
--to DATE | 종료 날짜 (YYYY-MM-DD, 필수) |
--service NAME | 특정 서비스의 데이터만 삭제 |
--yes | 확인 프롬프트 건너뛰기 |
예시:
# 지정된 날짜 범위 내의 모든 데이터 삭제
ai-observer delete all --from 2025-01-01 --to 2025-01-31
# 지정된 날짜 범위 내의 로그만 삭제
...
Claude Code
다음 환경 변수 (Environment Variables)를 설정하세요:
# 텔레메트리 활성화 (필수)
export CLAUDE_CODE_ENABLE_TELEMETRY=1
# 익스포터 (Exporters) 설정
...
세션 간에 설정을 유지하려면 이를 ~/.bashrc, ~/.zshrc 또는 셸 프로필 (Shell Profile)에 추가하세요.
설정 후 Claude Code는 메트릭 (Metrics)과 이벤트 (Events)를 AI Observer로 자동 전송합니다.
Gemini CLI
OTLP 발행과 관련된 버그가 이전 모든 버전에서 발생했으므로, 최소 v0.34.0 버전 이상의 Gemini CLI를 사용 중이라고 가정합니다.
~/.gemini/settings.json에 다음을 추가하세요:
{
"telemetry": {
"enabled": true,
...
필수 환경 변수 (Gemini CLI의 타이밍 이슈에 대한 해결책):
export OTEL_METRIC_EXPORT_TIMEOUT=10000
export OTEL_LOGS_EXPORT_TIMEOUT=5000
OpenAI Codex CLI
~/.codex/config.toml에 다음을 추가하세요:
[otel]
log_user_prompt = true # 프롬프트를 비식별화하려면 false로 설정
exporter = { otlp-http = { endpoint = "http://localhost:4318/v1/logs", protocol = "binary" } }
...
참고: Codex CLI는 로그 (Logs)와 트레이스 (Traces)를 내보내지만, 메트릭 (Metrics)은 내보내지 않습니다. trace_exporter 옵션은 문서화되어 있지는 않지만 사용 가능하며, 생략할 경우 트레이스는 로그와 동일한 엔드포인트 (Endpoint)로 전송됩니다.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Claude Code │ │ Gemini CLI │ │ Codex CLI │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
...
기술 스택 (Tech Stack):
백엔드 (Backend): Go 1.24+, chi router, DuckDB, gorilla/websocket
프론트엔드 (Frontend): React 19, TypeScript, Vite, Tailwind CSS v4, Zustand, Recharts
AI Observer는 두 개의 HTTP 서버를 노출합니다:
텔레메트리 (Telemetry) 데이터를 수신하기 위한 표준 OpenTelemetry Protocol (OTLP) 엔드포인트.
- 전송 방식은 HTTP/1.1 + h2c입니다 (gRPC 리스너는 노출되지 않음).
- 압축된 페이로드 (Payload)를 위해
Content-Encoding: gzip을 지원합니다.
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
POST | /v1/traces | 트레이스 스팬 (Trace spans) 수집 (protobuf 또는 JSON) |
POST | /v1/metrics | 메트릭 (Metrics) 수집 (protobuf 또는 JSON) |
POST | /v1/logs | 로그 (Logs) 수집 (protobuf 또는 JSON) |
GET | /health | 상태 확인 (Health check) |
저장된 텔레메트리 데이터를 쿼리하기 위한 REST API. 별도로 지정하지 않는 한, from 및 to는 기본적으로 지난 24시간으로 설정됩니다.
트레이스 (Traces)
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
GET | /api/traces | 필터링 및 페이지네이션 (Pagination)을 포함한 트레이스 목록 조회 |
GET | /api/traces/recent | 가장 최근의 트레이스 조회 |
GET | /api/traces/{traceId} | 특정 트레이스 조회 |
GET | /api/traces/{traceId}/spans | 특정 트레이스의 모든 스팬 (Spans) 조회 |
/api/traces를 위한 쿼리 파라미터 (Query parameters):
service — 서비스 이름으로 필터링
search — 전체 텍스트 검색
from, to — 시간 범위 (ISO 8601)
limit, offset — 페이지네이션
메트릭 (Metrics)
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
GET | /api/metrics | 필터링을 포함한 메트릭 목록 조회 |
GET | /api/metrics/names | 모든 메트릭 이름 목록 조회 |
GET | /api/metrics/series | 메트릭에 대한 시계열 (Time series) 데이터 조회 |
POST | /api/metrics/batch-series | 한 번의 요청으로 여러 시계열 데이터 조회 |
/api/metrics/series를 위한 쿼리 파라미터 (Query parameters):
name — 메트릭 이름 (필수)
service — 서비스로 필터링
from, to — 시간 범위 (ISO 8601)
interval — 집계 간격 (예: 1 minute, 1 hour)
aggregate — 모든 시계열을 하나로 집계 (기본값: false)
배치 시계열 (Batch series) (POST /api/metrics/batch-series) 요청 본문 (Request body):
- 각 쿼리는
id와name이 필요하며,service,aggregate,interval은 선택 사항입니다. - 요청당 최대 50개의 쿼리가 가능합니다.
- 본문의
from/to역시 생략될 경우 기본적으로 지난 24시간으로 설정됩니다.
로그 (Logs)
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
GET | /api/logs | 필터링 및 페이지네이션 (Pagination)을 포함한 로그 목록 조회 |
GET | /api/logs/levels | 심각도 레벨 (Severity level)별 로그 수 조회 |
/api/logs를 위한 쿼리 파라미터 (Query parameters):
service
— 서비스 이름으로 필터링
severity
— 심각도로 필터링 (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
traceId
— 특정 트레이스 (Trace)와 연결된 로그 필터링
search
— 전체 텍스트 검색 (Full-text search)
from , to
— 시간 범위 (ISO 8601)
limit , offset
— 페이지네이션 (Pagination)
대시보드 (Dashboards)
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
GET | /api/dashboards | 모든 대시보드 목록 조회 |
POST | /api/dashboards | 새 대시보드 생성 |
GET | /api/dashboards/default | 위젯 (Widgets)이 포함된 기본 대시보드 조회 |
GET | /api/dashboards/{id} | ID로 대시보드 조회 |
PUT | /api/dashboards/{id} | 대시보드 업데이트 |
DELETE | /api/dashboards/{id} | 대시보드 삭제 |
PUT | /api/dashboards/{id}/default | 기본 대시보드로 설정 |
POST | /api/dashboards/{id}/widgets | 위젯 추가 |
PUT | /api/dashboards/{id}/widgets/positions | 위젯 위치 업데이트 |
PUT | /api/dashboards/{id}/widgets/{widgetId} | 위젯 업데이트 |
DELETE | /api/dashboards/{id}/widgets/{widgetId} | 위젯 삭제 |
기타 (Other)
| 메서드 (Method) | 엔드포인트 (Endpoint) | 설명 |
|---|---|---|
GET | /api/services | 텔레메트리 (Telemetry)를 전송하는 모든 서비스 목록 조회 |
GET | /api/stats | 집계 통계 (Aggregate statistics) 조회 |
GET | /ws | 실시간 업데이트를 위한 웹소켓 (WebSocket) |
GET | /health | 상태 확인 (Health check) |
AI Observer는 표준 OpenTelemetry 데이터를 수신합니다:
| 시그널 (Signal) | 설명 | 데이터 예시 |
|---|---|---|
| 트레이스 (Traces) | 분산 트레이싱 스팬 (Distributed tracing spans) | API 호출, 도구 실행, 세션 타임라인 |
| 메트릭 (Metrics) | 수치 측정값 | 토큰 수, 지연 시간 히스토그램 (Latency histograms), 요청률 |
| 로그 (Logs) | 구조화된 로그 레코드 | 에러, 프롬프트 (활성화된 경우), 시스템 이벤트 |
모든 데이터는 DuckDB에 로컬로 저장됩니다. 외부 서비스로 전송되는 것은 아무것도 없습니다.
각 AI 코딩 도구는 서로 다른 텔레메트리 (Telemetry) 신호를 내보냅니다. 관찰할 수 있는 항목은 다음과 같습니다:
Claude Code 메트릭 (Metrics) 및 이벤트 (Events)
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub AI Coding Assistants의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기