사용 통계와 끄는 법
앱(dira teams)은 GA4로 사용 통계를 보내고, 앱에서 오류가 나면 그 오류를 dira 서버로
제보합니다. 둘은 스위치 하나로 같이 켜지고 같이 꺼집니다. 엔진(tick.sh, tickets.py)은 아무것도
보내지 않습니다. 이 장에서 다루는 내용은 전부 앱에 관한 것입니다.
보내는 것 - 이벤트 8종
이름 8개가 전부입니다. 코드에 이 표에 없는 이벤트가 생긴다면 그것은 결함입니다.
| 이벤트 | 언제 | 파라미터 |
|---|---|---|
app_open | 사용자 세션이 시작될 때(첫 이벤트 앞, 30분 무활동 뒤 재시작) | app_version, shell(desktop|browser) |
screen_view | 화면 진입 | screen(root|board|ticket|workers|personas|protocols|ontology|home) |
project_add | 프로젝트가 하나 늘었을 때 | method(create|register) |
worker_create | 워커 생성 성공 | engine(엔진 카탈로그의 id 그대로. 지금은 claude|codex|grok|agy이고, 직접 적은 값은 other로 분류된다), cron_ok(bool) |
ticket_create | 티켓 발행이나 요구 접수 성공 | kind(work|request|feedback) |
answer_submit | 답변 왕복의 답을 사람이 썼을 때 | 없음 |
feedback_submit | 의견 보내기 폼에서 보내기를 눌렀을 때 | 없음 |
analytics_off | 통계를 끌 때(끄기 직전 마지막 한 번) | 없음 |
값은 개수, 불리언, 미리 정한 enum뿐입니다. .done 전환이나 디스패치처럼 엔진이 만드는 사실은
이벤트가 아닙니다. 화면 동작만 집계합니다. 오류는 이 표의 이벤트로 세지 않고, 아래 오류 제보에서
설명하는 별도 요청으로 보냅니다.
보내지 않는 것
아래는 어떤 이벤트의 어떤 파라미터에도 들어가지 않습니다.
파일 경로, 프로젝트 이름, 큐 루트, 티켓 해시, 티켓 제목, 티켓 본문, 페르소나 이름, 워커 이름, 사람 이름, 토큰, 프롬프트(에이전트에 넣는 지시나 에이전트의 출력), IP를 유추할 값.
screen_view도 URL 자체는 안 보냅니다. /p/<project>/tickets/<hash>는 프로젝트 이름과 티켓
해시를 둘 다 담고 있어서, 보내는 것은 그 경로를 미리 정한 화면 이름(ticket 등) 하나로 바꾼
값입니다. 의견 보내기 폼에 쓰신 자유 입력도 GA로 가지 않습니다. 그 내용은 GitHub 이슈로만
전달되고, GA에는 "보낸 사실"(feedback_submit)만 남습니다.
이 목록은 GA로 가는 이벤트에 대한 약속입니다. 오류 제보는 원본 로그를 그대로 싣기 때문에 이 약속이 적용되지 않습니다. 무엇이 섞여 들어갈 수 있는지는 바로 아래에 적었습니다.
오류 제보
사용 통계가 켜져 있으면, 앱에서 오류가 날 때 그 오류를 스택 트레이스와 원본 로그째 dira 서버(웹사이트와 같은 Vercel 프로젝트)로 보냅니다. 오류를 받아 봐야 고칠 수 있어서 넣은 기능입니다. 오류가 잡히는 곳은 셋입니다. 내 맥에서 도는 앱 서버, 화면(렌더러), 데스크톱 앱 본체입니다.
제보 한 건은 JSON 한 벌이고 256 KB를 넘지 않습니다. 들어가는 키는 아래가 전부입니다.
| 키 | 값 |
|---|---|
v | 형식 버전. 지금은 1 |
install_id, session_id | GA로 보내는 것과 같은 설치 식별자와 세션 식별자. 그래서 제보 한 건과 그 설치의 사용 통계가 같은 값으로 이어집니다 |
app_version, shell | app_open에 실리는 것과 같은 값 |
source | 오류가 난 곳. server|renderer|main |
kind | 오류 종류. uncaught|unhandled_rejection|request_error|boundary|child_exit|renderer_gone|ready_timeout |
message | 오류 메시지 원문 |
stack | 스택 트레이스 원문 |
raw | 오류 직전의 원본 로그. 앱 서버는 stderr와 stdout 최근 200줄, 데스크톱 앱 본체는 앱 서버가 남긴 stderr 전체와 stdout 끝부분, 화면은 콘솔 오류 최근 50건입니다. 64 KB를 넘으면 앞부분을 잘라 냅니다 |
route | 오류가 난 화면의 경로 패턴(/p/[project]/tickets/[hash]). 실제 URL은 보내지 않습니다 |
at | 오류가 난 시각(ISO 8601) |
내용을 바꾸는 가공은 한 가지뿐입니다. 모든 문자열에서 홈 디렉터리 절대 경로를 ~로 바꿉니다.
/Users/<사용자 이름>/Projects/app/.dira는 ~/Projects/app/.dira로 들어갑니다. 그 밖에는
원문 그대로입니다. 그래서 스택과 원본 로그에는 홈 아래의 파일 경로, 프로젝트 이름, 티켓 해시,
오류가 나던 순간 로그에 찍힌 문장이 섞일 수 있습니다. 이것을 보내고 싶지 않으면 사용 통계를
끄시면 됩니다.
같은 오류가 되풀이되어도 제보가 쏟아지지 않게 앱이 묶어서 보냅니다. 같은 오류는 10분에 한 번만 보내고, 설치 하나가 한 시간에 보내는 제보는 20건까지입니다. 보내기에 실패한 제보는 다시 시도하지 않고 버립니다.
서버는 받은 제보를 한 건씩 Vercel에 비공개로 저장하고 90일 동안 보관합니다.
전송 조건 - 자격값 두 개
전송은 GA_MEASUREMENT_ID와 GA_API_SECRET 두 값이 있어야 나갑니다. 이 둘은 릴리스 빌드에만
CI가 넣고, 레포에는 커밋되지 않습니다. 값이 없으면 코드가 아무것도 보내지 않습니다.
pnpm dev로 띄운 개발 서버와 직접 빌드한 .app은 둘 다 이 상태입니다. 개발 중에 실행되는
세션이 통계를 오염시키지 않는 이유가 이것입니다. 오류 제보도 같은 조건을 따르므로, 개발
빌드에서 난 오류는 어디로도 가지 않습니다.
설정 다이얼로그의 사용 통계도 이 값의 유무를 그대로 보여줍니다. 자격값이 없는 빌드에서는
보내지 않습니다 한 줄과 그 이유만 뜨고 끄는 버튼 자체가 없습니다. 끌 것이 없으니까요.
끄는 법
우측 위 톱니바퀴로 설정을 열고 왼쪽 트리에서 사용 통계를 고르세요(화면 소개
참고). 기본은 켜짐이고, 버튼 하나로 끄시면 됩니다. 끄면 그 순간부터 아무 이벤트도 나가지
않고, 위의 한 줄이 보내지 않습니다로 바뀝니다. 오류 제보도 같은 순간에 멈춥니다. 오류
제보만 따로 끄는 스위치는 없습니다.
지우는 법
통계 파일은 ~/.config/dira/analytics.json 하나입니다. 여기 든 값은 둘뿐입니다. 하나는
install_id(GA4에 client_id와 사용자 속성 install_id로 보내는 익명 설치 식별자)이고,
다른 하나는 enabled(껐을 때만 false로 적힙니다)입니다. 파일을 지우면 다음 실행에서 새
install_id가 발급되고, 이전 통계와 이어지지 않는 새 설치로 집계됩니다. 아래 한 줄을 터미널에
입력하시면 됩니다.
rm ~/.config/dira/analytics.json이 파일을 지워도 이미 보낸 오류 제보는 서버에서 지워지지 않고, 보관 기간 90일이 지나야 사라집니다.
무엇을 왜 보내는지, 보존 기간과 위탁처는 개인정보처리방침에 있습니다.
다음은 커맨드입니다.