TRENDSHIFT #10 · 2026.06.10

splitrail 딥다이브
— 여러 AI 코딩 CLI의 토큰·비용을 한 번에 추적하는 Rust 도구

Claude Code·Gemini CLI·Codex·Copilot 같은 AI 코딩 도구를 여러 개 쓰다 보면, 각각 토큰을 얼마나 먹었고 돈이 얼마 나갔는지 따로따로 흩어진다. splitrail은 이 도구들이 컴퓨터에 남긴 대화 로그를 전부 긁어모아 한 화면에 합쳐 보여주는 단일 실행 파일이다. Rust로 짜여 빠르고, 터미널 대시보드·MCP 서버·VS Code 확장까지 한 코드베이스로 제공한다. (저장소: Piebald-AI/splitrail · Rust · ★191 · TrendShift 10위 · MIT)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 레포가 무엇을 하는 물건인가.

핵심 메시지

"여러 AI 코딩 도구가 쓴 토큰과 돈을,
한 명령으로 모아 보여주는 '주행거리계'."

자동차 계기판이 연료를 얼마나 썼는지 알려주듯, splitrail은 AI 코딩 도구가 토큰을 얼마나 태웠고 비용이 얼마인지 한눈에 보여준다. 다른 점은, 차가 여러 대(Claude Code, Gemini CLI, Codex…)인데 계기판 하나로 전부 합산해 준다는 것.

요즘은 코딩할 때 AI 도구를 하나만 쓰지 않는다. 어떤 작업은 Claude Code로, 어떤 건 Gemini CLI로, VS Code 안에서는 Copilot이나 Cline으로… 이렇게 쓰다 보면 각 도구가 토큰을 얼마나 먹었는지, 한 달에 돈이 얼마 나가는지 도무지 한눈에 안 들어온다. splitrail은 이 도구들이 각자 컴퓨터에 남겨 놓은 대화 로그 파일을 직접 읽어 하나의 표·그래프로 합쳐 보여준다.

핵심은 "추가 설정 없이 그냥 돈다"는 점이다. 도구에 별도 플러그인을 심을 필요 없이, 이미 디스크에 쌓여 있는 로그를 분석할 뿐이다. splitrail 한 번이면 터미널 대시보드가 뜨고, 파일이 바뀌면 실시간으로 숫자가 갱신된다.

용어
토큰 (token)
AI가 글을 처리하는 최소 단위. 대략 영어 단어 4분의 3, 한글은 글자 한두 개가 1토큰쯤 된다. AI API 요금은 보통 "토큰 100만 개당 몇 달러" 식으로 매겨지므로, 토큰을 세면 곧 돈을 세는 것과 같다.
용어
CLI (Command-Line Interface, 명령줄 도구)
마우스 클릭이 아니라 터미널에 명령어를 쳐서 쓰는 프로그램. Claude Code·Gemini CLI 등 요즘 AI 코딩 도구 상당수가 이 형태다.

2왜 주목받는가

트렌딩 이유 · 경쟁 대비 장점.

AI 코딩 도구 사용량을 보는 도구로는 ccusage(Claude Code 전용, Node.js)가 먼저 유명했다. splitrail이 끌리는 이유는 세 가지다. 첫째, 한 도구가 아니라 십수 개를 동시에 본다. 둘째, Rust로 만든 단일 실행 파일이라 런타임 설치 없이 바로 돈다. 셋째, 터미널 대시보드만이 아니라 MCP 서버·VS Code 확장·클라우드 동기화까지 한 묶음으로 준다.

비교 항목ccusage 등 기존splitrail
지원 도구주로 Claude Code 1종Claude Code·Gemini·Codex·Copilot·Cline·Roo·Kilo·OpenCode·Pi 등 14종
실행 방식Node.js 런타임 필요의존성 없는 단일 바이너리
속도JS 파싱SIMD JSON + 병렬 처리로 매우 빠름
인터페이스주로 표 출력실시간 TUI + MCP + VS Code + 클라우드
기존 방식의 한계
도구마다 비용이 따로 논다

Claude Code는 Claude Code대로, Gemini는 Gemini대로 사용량이 흩어져 있어 "이번 달 AI에 총 얼마 썼지?"에 답하기 어렵다. 도구마다 로그 형식·저장 위치도 제각각이라 직접 합산하기는 사실상 불가능.

splitrail의 해결
전부 같은 형식으로 정규화해 합산

도구별 로그를 각자의 분석기(Analyzer)가 읽어, 내부적으로 똑같은 메시지 구조로 변환한다. 그래서 도구가 14개든 1개든 날짜별·모델별·비용별로 한 표에 합쳐서 비교할 수 있다.

3기술 스택 전체 지도

"빠른 단일 바이너리"를 떠받치는 크레이트들.

splitrail은 100% Rust 백엔드(코어)에 얇은 TypeScript VS Code 확장이 얹힌 구조다. Rust 생태계의 라이브러리(크레이트)를 성능 위주로 골라 썼다.

레이어기술 / 크레이트역할
언어·런타임Rust 2024 (nightly) + tokio코어 전체 + 비동기 런타임(MCP·업로드)
CLI 파싱clap 4 (derive)upload·config·stats·mcp 서브명령
터미널 UIratatui 0.30 + crossterm실시간 대시보드(표·탭·정렬)
JSON 파싱simd-jsonSIMD 가속 — serde_json 대신 모든 파싱에
병렬 처리rayon분석기·파일을 동시에 파싱(par_iter)
동시성 자료구조dashmap · parking_lot잠금 적은 캐시 · 빠른 Mutex/RwLock
메모리 최적화mimalloc · lasso · tinyvec할당자 교체 · 문자열 인터닝 · 인라인 벡터
해싱xxhash-rust · sha2빠른 로컬 해시 · 서버 중복제거용 SHA-256
MCP 서버rmcp 0.12 + schemars공식 Rust MCP SDK · 도구 입력 스키마
HTTPreqwest (rustls)클라우드 업로드 · 버전 확인(OpenSSL 불필요)
데이터베이스rusqlite (bundled)SQLite 로그 읽기(OpenCode·Piebald·Antigravity)
토큰 계산tiktoken-rsCopilot처럼 토큰 수를 안 주는 도구 직접 계산
용어
크레이트 (crate)
Rust의 라이브러리/패키지 단위. 파이썬의 pip 패키지, JS의 npm 모듈에 해당한다. Cargo.toml 파일에 어떤 크레이트를 쓸지 적어 둔다.
용어
TUI (Text-based User Interface, 텍스트 기반 화면)
그래픽 창이 아니라 터미널 안에서 도는 화면형 앱. 표·탭·키보드 조작이 되는 대시보드를 까만 터미널 위에 그린다. ratatui가 이 화면을 그려 주는 크레이트.
용어
MCP (Model Context Protocol, 모델 컨텍스트 프로토콜)
AI 비서(예: Claude)가 외부 도구·데이터에 표준화된 방식으로 접근하게 해 주는 규약. splitrail을 MCP 서버로 띄우면, AI가 "내 토큰 사용량 알려줘"를 직접 조회할 수 있다.

4아키텍처 심화 분석

로그 파일이 어디서 어떻게 화면까지 흐르는가.

splitrail의 일은 다섯 단계로 흐른다: ① 발견 → ② 파싱 → ③ 중복제거 → ④ 집계 → ⑤ 출력(TUI·업로드·MCP). 먼저 전체 그림 한 장:

┌─ ① 발견(discover) ─────────────────────────────┐ │ 각 Analyzer가 OS별 경로를 훑어 │ │ (walkdir/glob) 로그 파일 목록을 만든다 │ └───────────────────────────┬────────────────────┘ │ rayon: 분석기 + 파일을 동시에 ▼ ┌─ ② 파싱(parse) ────────────────────────────────┐ │ JSONL/JSON/SQLite 를 읽어 │ │ ConversationMessage(공통 구조)로 변환 │ │ 메시지마다 비용을 models.rs로 계산 │ └───────────────────────────┬────────────────────┘ ▼ ┌─ ③ 중복제거(dedup) ────────────────────────────┐ │ global_hash(SHA-256)로 같은 메시지 제거 │ │ (Claude Code는 이어쓰기/분기 세션 추가 병합) │ └───────────────────────────┬────────────────────┘ ▼ ┌─ ④ 집계(aggregate) ────────────────────────────┐ │ 날짜별 BTreeMap<date, DailyStats>로 합산 │ │ (토큰·비용·파일작업·모델별 카운트) │ └──────────┬───────────────┬──────────────┬───────┘ ▼ ▼ ▼ ⑤ TUI 대시보드 클라우드 업로드 stats/MCP(JSON) (ratatui + (reqwest POST, (simd_json 출력 notify 감시) 청크+재시도) / rmcp stdio)

여기서 핵심 설계는 Analyzer 트레이트다. 도구가 14개라고 코드가 14벌인 게 아니라, "분석기라면 이런 일을 할 줄 알아야 한다"는 인터페이스(트레이트) 하나를 정해 두고, 각 도구는 그 빈칸만 채운다.

pub trait Analyzer {
    // 화면에 보일 이름 (예: "Claude Code")
    fn display_name(&self) -> &str;
    // 로그 파일이 어디 있는지 찾는다
    fn discover_data_sources(&self) -> Vec<DataSource>;
    // 파일 하나를 읽어 공통 메시지로 변환
    fn parse_source(&self, src: &DataSource) -> Vec<ConversationMessage>;
    // 실시간 감시할 폴더
    fn get_watch_directories(&self) -> Vec<PathBuf>;
}

모든 분석기는 결국 ConversationMessage라는 똑같은 구조체로 결과를 토해 낸다. 그래서 그 뒤의 중복제거·집계·화면 코드는 도구가 뭐였는지 신경 쓸 필요가 없다.

pub struct ConversationMessage {
    pub application: Application,   // 어느 도구? (enum)
    pub date: DateTime<Utc>,
    pub model: Option<String>,     // 어떤 모델
    pub stats: Stats,              // 토큰·비용·파일작업…
    pub local_hash: Option<String>, // 도구 내 중복제거(xxh3)
    pub global_hash: String,        // 기기 간 중복제거(SHA-256)
}

흐름 한 줄기 따라가기 — "Claude Code 파일이 바뀌면"

이 레포에서 가장 똑똑한 부분은 실시간 증분 갱신이다. 보통은 파일이 하나 바뀌면 전체를 다시 읽어야 하는데, splitrail은 그러지 않는다.

watcher.rsnotify 크레이트로 ~/.claude/projects 폴더를 감시한다. 파일 하나가 바뀌면, 그 파일 하나만 다시 파싱한다. 캐시에 저장해 둔 그 파일의 예전 기여분(contribution)을 현재 합계에서 빼고, 새로 파싱한 값을 더한다. 전체를 다시 스캔하지 않으니 거의 즉시(O(1)) 숫자가 갱신된다.

설계 패턴
트레이트 객체 플러그인 (trait object plugin)
Box<dyn Analyzer> 목록으로 분석기들을 한 바구니에 담는 패턴. 새 도구 지원을 추가하려면 트레이트를 구현한 구조체 하나만 만들어 등록하면 된다 — 나머지 코드는 손대지 않는다. "콘센트 규격(트레이트)만 맞추면 어떤 가전(분석기)이든 꽂힌다."

5디렉토리 구조 해부

어떤 폴더가 무슨 일을 하나.

splitrail/ ├── src/ │ ├── main.rs 진입점: clap CLI · 분석기 등록 · 할당자 설정 ★ │ ├── analyzer.rs Analyzer 트레이트 + 레지스트리 + 증분 캐시 │ ├── analyzers/ 도구별 분석기 14종 ★ │ │ ├── claude_code.rs 가장 복잡(파일 간 중복제거) │ │ ├── codex_cli.rs OpenAI Codex │ │ ├── gemini_cli.rs Gemini CLI │ │ ├── copilot.rs tiktoken으로 토큰 직접 계산 │ │ ├── opencode.rs JSON + SQLite 색인 │ │ ├── antigravity.rs SQLite + 손수 짠 protobuf 파서 │ │ └── … (pi_agent, cline, roo_code, kilo …) │ ├── models.rs ~2974줄: 모델별 가격표 + 비용 계산 ★ │ ├── types.rs ConversationMessage · Stats · 집계 타입 │ ├── tui.rs ratatui 대시보드(2638줄) · 키 입력 │ ├── watcher.rs notify 파일 감시 + 실시간 증분 갱신 │ ├── upload.rs 클라우드 업로드(청크·재시도·백오프) │ ├── mcp/ MCP 서버(rmcp): 도구 6종 + 리소스 2종 │ ├── cache/ 모델명 문자열 인터닝(lasso) │ └── contribution_cache/ 파일별 기여분 캐시(증분 갱신 핵심) ├── vscode-splitrail/ VS Code 확장(TypeScript, CLI 호출) ├── .github/workflows/ 크로스플랫폼 빌드·서명·릴리스 ├── Cargo.toml 크레이트 의존성 목록 └── CLAUDE.md / AGENTS.md AI 협업용 코드 규약
파일/폴더역할
src/analyzers/도구마다 1파일. 로그 위치를 찾고 공통 메시지로 변환. 새 도구 지원의 출발점.
src/models.rs모델별 가격표가 코드에 박혀 있음. 출처 URL 주석 포함. 비용 계산의 단일 진실원.
src/tui.rsratatui 대시보드. 표·탭·정렬·검색(/)·vim 키(h/j/k/l).
src/watcher.rs파일 변경 감지 → 증분 갱신. 실시간성의 심장.
src/contribution_cache/파일별 요약(32~100바이트)을 캐싱해 add/subtract로 즉시 갱신.
vscode-splitrail/파싱을 다시 짜지 않고 splitrail stats CLI를 호출해 JSON을 받아 웹뷰에 그림.

6학습 포인트 (기술별)

이 레포에서 배울 만한 것 + 어디를 보면 되는지.

포인트 1 · 아키텍처

트레이트 객체로 짠 플러그인 구조

"공통 인터페이스(트레이트) + 구현체 N개" 패턴의 모범 사례. async-trait, 트레이트 기본 메서드(공통 로직을 트레이트에 넣어 각 분석기는 핵심만 구현), Send + Sync 경계까지 자연스럽게 배운다. src/analyzer.rsanalyzers/pi_agent.rs(가장 단순)부터 읽으면 좋다.

포인트 2 · TUI

ratatui + crossterm 대시보드 루프

터미널 앱의 정석 루프를 볼 수 있다. enable_raw_mode → 대체 화면 진입 → terminal.draw(|f| …)event::poll로 키 입력. 표·탭·정렬·검색이 어떻게 위젯으로 조립되는지 src/tui.rs에서 확인.

포인트 3 · MCP

Rust로 MCP 서버 만들기

공식 SDK rmcp로 도구를 노출하는 최신 예제. 매크로(#[tool])로 도구를 정의하고 schemars로 입력 스키마를 자동 생성한다. splitrail mcp를 띄우면 AI가 사용량을 직접 조회.

# MCP 서버로 실행
splitrail mcp
# 노출되는 도구 예: get_daily_stats,
#   get_cost_breakdown, compare_tools …
포인트 4 · 성능

"빠르다"를 만드는 구체적 기법들

이 레포의 진짜 보석. rayon로 분석기·파일을 2중 병렬 파싱, simd-json으로 SIMD 파싱, mimalloc 할당자 교체, lasso로 모델명을 2바이트 키로 인터닝, tinyvec로 작은 벡터를 힙 없이 저장. 빠른 로컬 해시(xxh3) vs 안정적 글로벌 해시(SHA-256)를 용도별로 나눠 쓰는 것도 배울 점.

용어
문자열 인터닝 (string interning)
같은 문자열(예: 모델 이름 "claude-sonnet-4")이 수천 번 나올 때, 매번 24바이트 String을 복제하지 않고 2바이트짜리 번호표 하나로 대체하는 기법. 메모리가 크게 줄고 비교도 빨라진다.

7시스템 요구사항

그냥 쓰려면 / 직접 빌드하려면 무엇이 필요한가.

항목요구사항
실행(권장)릴리스 페이지의 OS별 바이너리 다운로드 — 별도 런타임 불필요
지원 OSLinux(gnu·musl, x86_64·aarch64) · macOS(Intel·Apple Silicon) · Windows(x86_64)
빌드 도구체인Rust nightly(rust-toolchain.toml로 고정), Cargo
Windows 빌드lld-link.exe(LLVM) — 컴파일 속도용. winget install LLVM.LLVM
분석 대상이미 사용 중인 AI 코딩 도구의 로컬 로그(자동 탐색)
선택클라우드 동기화 시 splitrail.dev 계정·API 토큰

8직접 해볼 수 있는 실습 과제

난이도별로 손에 익히는 단계.

실습 1

바이너리 받아 대시보드 띄우기 난이도 ★☆☆ 입문

릴리스 페이지에서 내 OS용 파일을 받아 실행만 하면 된다. 이미 Claude Code나 Gemini CLI를 써 봤다면 곧바로 사용량이 뜬다. 토큰·비용이 날짜별로 어떻게 합산되는지 관찰해 보자.

# 받은 바이너리를 그냥 실행
splitrail
# 표만 빠르게 보고 싶으면(JSON 출력)
splitrail stats
실습 2

설정 파일 만져보기 난이도 ★☆☆ 입문

~/.splitrail.toml을 열어 숫자 표기(천 단위 콤마)·소수 자릿수·로케일을 바꿔 보고 화면이 어떻게 달라지는지 본다. 모르는 모델 가격을 직접 추가하는 [models] 섹션도 실험해 보자.

# ~/.splitrail.toml
[formatting]
number_comma = true
decimal_places = 2
locale = "ko"
실습 3

MCP 서버로 AI에 물려보기 난이도 ★★☆ 중급

splitrail mcp로 MCP 서버를 띄우고, Claude 같은 AI 비서에 연결한다. 그다음 "이번 주 도구별 비용 비교해 줘"처럼 자연어로 물으면 AI가 compare_tools 도구를 호출해 답하게 만들어 보자.

실습 4

소스 빌드 + 코드 읽기 난이도 ★★☆ 중급

저장소를 클론해 cargo run으로 빌드하고, 가장 단순한 analyzers/pi_agent.rs를 정독해 분석기 한 채가 어떻게 생겼는지 파악한다.

git clone https://github.com/Piebald-AI/splitrail
cd splitrail
cargo run   # nightly 도구체인 자동 적용
실습 5

새 분석기 추가하기 난이도 ★★★ 고급

아직 지원 안 되는 도구가 있다면 Analyzer 트레이트를 구현하는 파일을 하나 만들고 main.rs의 레지스트리에 등록해 본다. "발견 → 파싱"만 채우면 중복제거·집계·화면은 공짜로 따라온다. (저장소 .claude/skills/new-analyzer 가이드 참고)

9관련 기술 심화 학습 로드맵

한 주씩 따라가는 계획.

주차주제학습 자료
1주차Rust 기본 + Cargo + clap CLIThe Rust Book · Cargo.toml·main.rs 정독
2주차트레이트·트레이트 객체·제네릭analyzer.rs + analyzers/pi_agent.rs
3주차ratatui·crossterm로 TUI 만들기ratatui 공식 튜토리얼 · tui.rs
4주차동시성: rayon·tokio·parking_lotRayon 문서 · 파싱 병렬화 코드
5주차성능: simd-json·인터닝·할당자cache/·models.rs + 벤치 실험
6주차MCP 서버(rmcp)·reqwest 업로드mcp/server.rs · upload.rs · MCP 명세

10핵심 키워드 사전

본문에 나온 용어 빠른 참조.

용어의미
토큰AI가 글을 처리하는 최소 단위. 요금 부과의 기준이라 토큰=돈.
Analyzer도구별 로그를 읽어 공통 메시지로 바꾸는 모듈. splitrail의 플러그인 단위.
트레이트(trait)"이런 일을 할 줄 알아야 한다"는 Rust의 인터페이스. 자바의 interface와 비슷.
TUI터미널 안에서 도는 화면형 앱. ratatui로 그린다.
MCPAI 비서가 외부 도구를 표준 방식으로 호출하게 하는 규약.
JSONL한 줄에 JSON 한 개씩 쌓는 로그 형식. 대부분의 AI CLI가 이렇게 기록.
SIMDCPU가 한 명령으로 여러 데이터를 동시에 처리하는 기술. simd-json이 이걸로 파싱 가속.
할당자(allocator)프로그램이 메모리를 받아오는 창구. 기본 대신 mimalloc으로 바꿔 속도↑.
인터닝반복되는 문자열을 짧은 번호표로 대체해 메모리·비교 비용을 줄이는 기법.
중복제거(dedup)같은 메시지가 여러 파일/기기에 중복 기록될 때 한 번만 세는 처리. 해시로 판별.

11참고 링크