coverband 도입 시도 및 한계
데드 코드 검출의 가장 확실한 방법은 프로덕션 시스템의 실행 정보를 수집하는 것이었습니다. 초기에는 유지보수 및 성능을 고려하여 coverband gem을 선정했습니다. 다른 소규모 서비스에는 성공적으로 도입하여 Redis를 통해 커버리지 데이터를 수집하고 별도 서버에서 결과를 확인하는 아키텍처를 구축했습니다. 사용자 피드백을 반영하여 최종 실행 시각 기능을 coverband에 기여하기도 했습니다.
그러나 freee Kakei에 coverband를 도입하는 과정에서 서비스 규모의 한계에 부딪혔습니다. 너무 많은 파일 수로 인해 목록 화면이 열리지 않았고, 대규모 Rails 서버로 인해 Redis의 CPU 사용률이 100%에 달했습니다. 이러한 부하를 감당할 Redis를 구축하는 데 드는 비용이 효용성에 비해 너무 높았으며, 특히 Resque 비동기 작업이 완료될 때마다 데이터를 전송하여 Redis 부하를 가중시켰습니다. 결국 coverband의 기존 코드를 대규모 서비스에 맞게 수정하는 것이 복잡하다고 판단하여 도입을 포기하고 자체 개발로 전환했습니다.
자체 개발 데드 코드 검출 시스템
coverband 도입 실패 후, 타베로그(食べログ)의 데드 코드 분석 기반 사례를 참고하여 자체 시스템을 개발했습니다. 이 시스템의 개요는 다음과 같습니다.
-
배포 시점: CI/CD 워크플로우에서 메서드 정의 정보를 분석하여 AWS S3에 저장합니다.
-
실행 시점: 프로덕션 애플리케이션에서 전용 gem이 동적 실행 정보를 행 단위로 수집하고, 몇 분마다 fluentd를 통해 AWS S3로 전송합니다.
-
집계 시점: 하루 한 번 Golang으로 개발된 배치 프로세스가 행 단위 및 메서드 단위 커버리지 결과를 AWS S3에 저장합니다.
내부적으로는 Ruby 표준 라이브러리의 coverage를 래핑하고 oneshot_lines 모드를 사용하여 성능 영향을 최소화했습니다. Golang으로 배치 처리를 구현하여 데이터 다운로드 및 집계를 병렬화하고 언어 버전 업데이트에 따른 부담을 줄였습니다.
사용자들은 Redash 대시보드를 통해 AWS Athena(S3 데이터에 직접 SQL 쿼리)를 경유하여 집계 결과를 시각적으로 확인할 수 있습니다. Redash는 클래스명, 메서드명, 파일 경로 등으로 증분 검색이 가능하며, 파일 경로 링크를 통해 GitHub로 이동하여 북마클릿을 실행하면 실행된 코드가 강조 표시됩니다. 또한 Ruby 3.2부터 eval로 평가된 코드(예: ERB 템플릿)의 커버리지도 측정할 수 있게 되어 오래된 화면의 실행 상황을 추적하는 데 큰 도움이 되었습니다. 이 시스템은 사내에서 좋은 평가를 받아 현재 freee Kakei를 포함한 4개 서비스에서 활발히 사용되고 있습니다.
MCP 서버를 활용한 자동화 시도
AI를 활용한 데드 코드 자동 삭제 가능성을 모색하기 위해 클래스명, 메서드명, 파일명을 입력하면 데드 코드 여부를 판정하는 MCP 서버를 개발했습니다. 이 서버는 진입점을 기반으로 재귀적으로 검색하여 삭제 가능 여부를 판단하는 동작을 보였으나, 프롬프트 조정에도 불구하고 정확도가 불안정했고 코드 리뷰 작업이 병목이 되어 완전 자동화에는 이르지 못했습니다. 향후 AI 기술의 발전이 이러한 과제를 해결해 줄 수 있을 것으로 기대합니다.