Back to list

Personal Assistant - 로깅 시스템

목차7

TL;DR

  • 목적: 추후 업무 자동화 및 병목 지점 개선을 위한 로깅 시스템 구축
  • 핵심
    • 로그 작성 파이프라인 구축
    • 동시성, 간결성, 확실성 보장 필요

개요

처음 이 프로젝트를 시작할 때, 강력한 로깅 시스템을 구축해야겠다는 생각을 했었다. 여기서 말하는 콘솔에서 띄우는 진단 로그 외로, 내가 언제 어떤 작업을 지시했는지, 개발 과정에서 어떤 이슈가 있었고 언제 해결되었는지 등을 의미한다.

내가 생각하는 로깅 시스템에서, 가장 중요한 요소는 세 가지였다:

  • 동시성: 여러 세션에서 작업이 진행되어도 로그가 작성되어야 함
  • 간결성: 필요한 내용만 작성하되, 언제든 grep으로 추적 가능하도록
  • 확실성: 완료된 작업은 ‘확실하게’ 로그가 작성되어야 함.

또한, 언제 무슨 작업을 지시했는지는 task-log로, Assistant 개발 일지는 별도의 dev-log로 나누어 관리하기로 하였다.


초기 설계

초기에는, 단순히 마크다운 파일에 새로운 로그를 append하는 방식이었다. 다만 무한정 append 할 경우 파일이 너무 길어질 수 있기에, 2026-06처럼 월별로 로그를 찍는 방식을 생각하였다.

기능 추가는 주로 하나의 전용 세션에서 진행하고 있으므로 dev-log에서는 이 방법이 대체로 유효했다. 그러나 task-log의 경우, 동시에 여러 작업이 돌아가므로 lost-update가 발생할 가능성이 있었기에, 최소한의 안전장치를 두었다.

  1. 어떤 작업이 시작되면 작업이 open되었음을 기록
  2. 작업이 끝나면 결과를 반환
  3. 작업이 끝나면 해당 작업이 closed 되었음을 기록 (sealed)

이러면, 중간에 작업이 실패하거나 lost-update가 되더라도 일부 케이스는 방어할 수 있었다. 예를 들어 두 세션이 동시에 write를 시도하여 lost-update가 발생하더라도, 작업을 열고 닫는 두 번의 작업에서 한 번은 감지될 기회가 있으므로 “open은 있는데 왜 sealed가 없지? (혹은 반대)“로 이상현상을 조기에 감지할 수 있었다.

그러나 이 메커니즘은 이후 오히려 큰 문제를 일으키고야 말았다…

동시 쓰기를 고려한 Spooling

처음 설계는 아래 그림과 같았다:

작업에 따라 그림은 조금 달라질 수 있으나, 큰 구조는 같다.

  1. 사용자의 작업 지시
  2. Rust BE에서 claude session을 spawn, 혹은 입력 전송
  3. 해당 작업이 시작되었음을 기록 (open)
  4. Claude session에서 작업을 완료, 작업을 완결처리하고(seal) 로그 스풀링

Spooling을 위해 WorkLog라는 모듈을 따로 만들었으며, Rust BE 혹은 Claude가 이 모듈을 통해 동일한 방식으로 로그를 남길 수 있도록 하였다. 스풀링된 로그들은 Rust BE쪽에서 90초 단위로 한번씩 drain하여 실제 로그 파일에 한번에 append한다.

당장 작성할 수 있는 로그도 90초 단위로 쓰여지게 된다는 단점이 있으나, 이 시간 텀은 필요하다면 더 줄일 수 있으니 큰 상관은 없었다.

Claude에서 실제로 로그를 찍는가?

위의 그림에서, Claude 세션은 크게 아래의 과정을 거치게 된다:

  1. 작업 open
  2. 작업 수행 (서브 에이전트를 호출하거나, n턴동안 대화 주고받으며)
  3. 작업 마무리되면 작업 결과 반환
  4. 작업 종료 (sealed) 처리 후 로그 스풀링

그러나 문제는 정작 로그가 한 줄도 찍히지 않았다는 점이었다. 이유는 여러 가지가 있었는데, 공통적으로 open된 작업이 sealed 되지 않았기 때문이었다.

대표적인 사례는 백그라운드에서 실행되는 이메일 요약 작업이었다. 당시에는 이메일 요약 작업을 위해 임시 세션을 하나 스폰한 후 결과만 받아왔는데, 이 과정에서 open으로 작업은 시작하지만 작업 결과 반환 이후 세션이 죽어버려서 sealed가 불가능해져 영구 미결 작업으로 남아버린 것이었다.

여기서 빨간색으로 표시된 영역 중, 작업 --sealed, 로그 spooling이 동작하지 않았던 것.
여기서 빨간색으로 표시된 영역 중, 작업 --sealed, 로그 spooling이 동작하지 않았던 것.

그런데 사실 스풀링만 잘 된다면, 굳이 open & sealed로 작업의 시작과 끝을 명시할 필요가 없지 않을까? 이전에야 Spooling이 안되는 구조였기에 작업의 상태를 추적할 필요가 있었으나, 이 시점에서는 이미 필요없는 작업이지 않았을까?

따라서, 지금과 같은 로깅 시스템으로 다시 개편되었다.

최종 버전

우선, 지난 시스템의 실패를 교훈삼아 로깅 시스템의 원칙부터 다시 세웠다.

  • 스풀링 시스템은 그대로 유지
  • 복잡한 트랜젝션(어떤 작업의 open ~ closed 까지의 단계)을 직접 관리하지 않는다.
  • CLI Tool로 인터페이스화: LLM과 Rust BE 알고리즘이 동일한 인터페이스를 통해 로그를 작성하게끔 함

이를 반영하여 기존 시스템을 변경한 결과, 현재와 같은 최종 로깅 시스템이 만들어졌다.

최종 액티비티 다이어그램
최종 액티비티 다이어그램

우선, dev log는 큰 차이가 없다. 시스템/코드 변경이 있을 시, CLAUDE.md를 통해서 최종적으로 읽게되는 “로깅 규칙”을 통해 dev log를 직접 편집한다.

중요한건 그 외의 파란색 박스 영역이다. 단순히 어떤 작업을 실행할 경우에는 그 시점에 바로 로그를 spool 후 drain 해버린다 (--log) — 충돌 가능성이 작으므로. 종료 시점을 명확히 알 수 없는 백그라운드 작업이나 서브 에이전트를 호출한 경우, --spool을 통해 일단 올려만놓고, 추후 작업이 완료되거나 90초 주기로 발생하는 --drain 시 한번에 처리된다.

스크린샷 2026-07-14 121326


결과

- `2026-07-10 09:20`**automation** — Gmail ingest: ▽ If Microsoft sold off Xbox, who would even buy it? → newsletter · 2026-07-10-verge-if-microsoft-sold-xbox.md · The Verge 데일리 — 본문 페치 불가(Zapier 미인증), 제목·발신 기준 "MS가 Xbox 매각하면 누가 사겠나" 리드 논평 뉴스레터로 추정 적재 · ~113453 tok
- `2026-07-10 16:26`**research** — 2팀 병렬 ideate→PRD 회의(Workflow 30에이전트·Opus 판정, 105만토큰/15분). Team A=triage(AI-PR '완료주장 vs 실제 diff' 트리아지 CLI, A1채택) · Team B='Owned or Licensed?' 디지털 소유권 디코더 사례집(B3채택). PRD 2장+README → outputs/2026-07-10-3day-service-prd/. 근거=Gmail inbox 22편(NotebookLM 방법론노트북 ff51565e 소실→직행). 회의실 창 대신 Workflow 직접경로(dispatch 승인 막힘 조정).

실제 작성되고 있는 로그는 위와 같다.

한가지 특이한 점은, 클로드가 작성하는 로그일 경우에는 실제 소모된 ‘토큰’수가 표시된다는 점이다. (나중에는 다른 작업에서도 소모된 토큰을 취합하여 로그로 박아두면 좋을 것 같다는 생각은 드는데, 일단 이건 나중 작업같아서 미뤄두었다.) 로깅의 이유 중 하나로, 토큰이 많이 소모되는 작업은 시간날 때 한번씩 점검해보면서 토큰을 더 아낄 수 있는 방법이 있을지 알아보기 위함이 있었다.

로깅 시스템은 아직도 조금씩 개선중인 부분이다. 나중에는 전날 작업 요약, 토큰 사용량 분석, 반복되는 작업들의 자동화 가능성 보고 등, 여러 분야로 활용해볼 계획이다.

Comments

링크가 복사되었습니다