런타임 데드 코드 분석 도구 Scavenger 사용법

지찬우·2023년 4월 6일
0

TIP

목록 보기
1/1
post-thumbnail

런타임 데드 코드 분석 도구 Scavenger - 당신의 코드는 생각보다 많이 죽어있다.

2023년 2월 28일에 다녀온 NAVER DEVIEW 2023에서 가장 재미있고 인상 깊게 보았던 Scavenger를 사용해 보았다. Naver Platform Labs의 김태연 님과 권오준 님께서 이해하기 쉽게 설명해 주셔서 나 같은 개린이(개발 어린이)도 집중해서 들을 수 있었던 것 같다. 또한 나는 Java를 메인으로 개발을 하기 때문에 더욱 좋았던 시간이었다. (모든 발표를 마치시고 그 자리에서 Github repository를 public으로 바꾸셨는데 몇몇 분들이 환호하시고 다 같이 웃어서 분위기가 매우 좋았다!)

Dead Code?

우선 Dead Code에 대해 이야기를 해보면 좋을 것 같다. Dead Code는 API Client들이 서비스를 중단하거나 기획의 스펙 아웃 등의 이유로 더 이상 사용하지 않는 코드를 의미한다. API를 사용하는 Client에서 사용을 하지 않게 되어 서버 개발자에게 알려주면 좋지만, 이를 매번 알려주는 것도 한계가 있다. 시간이 지나며 데드 코드는 점점 늘어나고 방치되어 성능에 영향을 미칠 수 있다.

이런 데드 코드를 런타임 시점에 추적•분석할 수 있는 도구가 바로 ‘Scavenger’이다.

GitHub - naver/scavenger: a runtime dead code analysis tool


README.md에 나와있는 대로 차근차근 따라서 해보았다. 그래서 이번에 Scavenger의 사용 방법에 대해 이야기해 볼까 한다.

사용을 해보기 위해 따라 하다가 여러 오류를 만나고 헤매다가 Github Discussion에 질문을 남겼는데, 김태연 님께서 빠르고 친절하게 답변을 해주셔서 성공적으로 동작시킬 수 있었다. 감사합니다 김태연 님 ㅠㅠ


Scavenger 사용해 보기

시작하기에 앞서 Scavenger는 Java 11 이상을 지원하니 참고하자.

Releases · naver/scavenger
우선 3개의 jar 파일과 Scavenger configuration 파일이 필요하다. 위의 release에서 최신 버전의 jar 파일을 다운로드한다.

  1. scavenger-collector-boot-{version}.jar
  2. scavenger-api-boot-{version}.jar
  3. scavenger-agent-java-{version}.jar

우리는 위의 세 개의 jar 파일을 순서대로 실행시킬 것이다.


scavenger collector 실행

일반적인 jar 파일을 실행하는 것과 동일하다.

java -jar scavenger-collector-boot-{version}.jar

collector는 기본적으로 8080 포트를 사용한다. 만약 다른 포트를 사용하고 싶다면 -D 옵션을 사용하면 된다.

java -Darmeria.port={port} -jar scavenger-collector-boot-{version}.jar

collector는 로컬 profile에서 in-memory H2를 사용하기 때문에 애플리케이션이 시작될 때마다 데이터가 초기화된다. H2 profile을 활성화하여 이 문제를 해결할 수 있다.

java -Dspring.profiles.active=h2 -jar scavenger-collector-boot-{version}.jar

나는 port는 기본인 8080을 사용하여 그냥 실행했었는데, UNAUTHENTICATED Error가 발생하여 여쭤보았다. h2 프로필을 활성화하여 실행시켜 보라고 하셔서 해봤더니 잘 동작했다. 만약 해당 에러가 발생한다면 h2 프로필을 활성화하여 실행시켜 보면 될 것 같다.


scavenger api 실행

이제 API를 실행시킬 차례이다. (collector를 실행시켜 둔 상태이어야 한다.) API는 collector의 포트 번호를 설정하여 실행시켜야 한다. 기본으로 했으면 8080, 만약 다른 포트로 설정하여 collector를 실행했다면 해당 포트로 설정하면 된다.

java -Dscavenger.collector-server-url=http://localhost:{collector's_port} -jar scavenger-api-boot-{version}.jar

API 또한 h2 프로필을 활성화하여 실행할 수 있다. 나는 API도 collector와 마찬가지로 h2 프로필을 활성화하여 실행시켰다.

java -Dscavenger.collector-server-url=http://localhost:{collector's_port} -Dspring.profiles.active=h2 -jar scavenger-api-boot-{version}.jar

scavenger agent 실행

API가 잘 실행됐다면 브라우저를 통해 http://localhost:8081/scavenger로 접속을 하면 다음과 같은 화면을 볼 수 있다.


좌측 하단에 있는 Create workspace 버튼을 눌러 새로운 workspace를 만든다. 이름은 자유롭게 지정하면 된다.

생성된 workspace로 들어가서 Show Scavenger configurationfile generator를 눌러 아까 얘기했던 scavegner configuration 파일을 생성할 수 있다.


여기서 packages 설정을 통해 우리가 데드 코드를 분석할 패키지를 지정할 수 있다. 각자가 분석할 애플리케이션의 패키지 또는 특정 내부 패키지를 입력하면 된다. 추가적인 설정 정보에 관해서는 사진 아래의 링크에 자세하게 나와있다. 설정을 완료하고 다운로드 버튼을 누르면 scavenger.conf 파일이 생성되고 다운로드 된다.

scavenger/installation.md at develop · naver/scavenger



이제 우리의 애플리케이션을 scavenger.conf 설정 파일, scavenger agent와 함께 실행하면 된다. 같이 실행하기 위해 세 개의 파일(내 애플리케이션.jar, scavenger-agent.jar, scavenger.conf)을 같은 경로에 두는 것이 편하다.

java -Dscavenger.configuration=scavenger.conf -javaagent:scavenger-agent-java-{version}.jar -jar {own_application}.jar

나는 빌드 툴로 Gradle을 사용한다. Gradle의 경우 터미널에서 ./gradlew build를 입력하여 애플리케이션을 빌드 할 수 있다. 그럼 xxx/build/libs 경로에 jar 파일이 생성된다. plain이 붙지 않은 jar 파일을 실행한다.


실행이 완료되고 생성했던 workspace에 들어가 새로고침을 해보면 agent가 추가된 것을 확인할 수 있다.


Snapshot 생성

이제 스냅샷을 하나 만들어 주도록 하자. Create 버튼을 눌러 스냅샷을 생성한다. Snapshot에서 또 package를 지정할 수 있는데 나는 그냥 입력하지 않았다.


스냅샷이 잘 생성되었다.


돋보기 버튼을 누르면 좌측에 내가 만든 애플리케이션의 package 구조를 확인할 수 있고 package 또는 Class 단위에서 어느 정도의 method가 호출되었는지 확인할 수 있다! 신기하다.


이렇게 Scavenger와 애플리케이션을 실행하고 API를 호출해 보았다. 드라마틱 하게 바로바로 갱신이 되지는 않지만 런타임에 분석을 할 수 있는 게 신기하고 유용하게 사용할 수 있을 것 같다. 아직 나는 공부하는 입장이기에 규모가 크고 복잡한 애플리케이션을 개발하지는 않지만, 만약 그런 애플리케이션을 개발한다면 편리하게 Scavenger를 통해 데드 코드를 분석하고 제거할 수 있을 것 같다.

profile
좋은 개발자가 되자.

0개의 댓글