1. 하려는 것
현재 진행중인 프로젝트(코지메이트)는 스프링 부트를 사용해서 개발중이고 배포를 기다리는 중입니다.
기능 개발은 배포를 진행중이니 필요한 기능들은 모두 완료되어있고, 이제는 자잘한 리팩토링과 성능 최적화, 로깅, 보안, 확장성, 안정성 등 실제 운영 환경에서 중요하게 고려해야하는 부분을 보완해야할 시점입니다.
이 중에서 현재 저는 로깅에 관련하여 구체화를 진행하고 있습니다.
지금까지 로깅을 위해 로그 메시지를 커스텀해서 필요한 정보를 출력하도록 하는 설정을 했고, 에러가 발생했을 때에는 Sentry를 사용해서 개발자들에게 알림을 줄 수 있도록 구성해두었습니다.
이번에는 Sentry의 기능 중 하나인 Performance 통계에서 Query 응답속도를 수집할 수 있도록 설정해보고자 합니다.
2. 필요성
- Sentry를 사용하면서, 다양한 기능들을 사용해보고 싶은 욕망이 있습니다.
- 마침 쿼리 응답속도에 관련한 데이터는 수집하고 있지 않습니다.
- 또한 쿼리 응답속도에 대한 데이터를 수집한다면, 리팩토링 시 쿼리 최적화가 필요한 우선순위를 정하는 기준점이 될 것입니다.
- 쿼리 응답속도를 측정할 수 있는 방법 중 간단하게 구성할 수 있는 편이라고 생각했습니다.
3. 방법
Performance에 들어가면 아래와 같은 창을 볼 수 있는데요. 이번 목표는 Most Time-Consuming Queries에 값이 나오도록 하는 겁니다.
강조된 부분을 보면 documentation이 있는데요. 바로 아래 링크입니다.
https://docs.sentry.io/product/insights/backend/queries/
Queries
Monitor the performance of your database queries and drill into samples to investigate further.
docs.sentry.io
뭔가 열심히 Queries에 대한 설명을 해주지만, 아쉽게도 여기에선 Spring Boot에 대한 명확한 정보를 얻을 수는 없습니다.
그래서 다른 자료를 또 열심히 찾아봤는데요. 실제로 Spring Boot에서 적용한 자료 자체가 거의 없어서 다른 분들이 한 자료를 참고할 수는 없었고, 다른 공식 문서를 찾았습니다.
https://docs.sentry.io/platforms/java/guides/spring-boot/tracing/instrumentation/jdbc/
JDBC Instrumentation | Sentry for Spring Boot
Learn how to capture tracing information from database queries executed with JDBC.
docs.sentry.io
https://blog.sentry.io/troubleshooting-spring-boot-applications-with-sentry/#jdbc-instrumentation
Troubleshooting Spring Boot Applications with Sentry
Some months ago we wrote a quick guide on how to use Sentry with Spring Boot and Logback. Since then, we've continued working on improving the development exper...
blog.sentry.io
위 두 문서면 어느정도 해결이 가능합니다. 자료만 잘 찾으면 쉽게 구성할 수 있는 부분이었습니다.
(그치만 자료만 30분 찾은 것 같긴 합니다.. 삽질하고 하면서...)
위 문서들을 읽으면, 간단하게 추가될 것 같다는 생각이 듭니다. 아래처럼 말이죠.
(저는 기존에 Sentry 설정을 위해 아래 라이브러리를 사용하고 있습니다.)
io.sentry:sentry-spring-boot-starter-jakarta
여기에 JDBC 관련 Sentry 라이브러리를 추가해줘야합니다.
io.sentry:sentry-jdbc
해당 라이브러리는 Sentry에 SentryJdbcEventListener를 제공한다고 합니다.
또 쿼리 추적을 위해서 P6Spy를 사용하여 쿼리가 실행될 때 가로채서 로그를 수집하게 됩니다.
P6Spy는 Sentry JDBC 8.0.0-rc.4 버전 기준으로 3.9.1 버전을 의존성으로 사용하는데요. 마지막 업데이트가 20년도인걸 보니 이후에 업데이트가 될 때 다른 의존성으로 변경될 것 같기도 합니다. (뇌피셜이지만..)
이렇게 라이브러리를 추가해줬으면, Configure에서 DataSource에 대한 설정을 p6spy를 경유해서 jdbc를 사용하도록 변경하면 모든 설정이 끝난다고 합니다.
맨 위에 링크에서 보았던 페이지와는 전혀 다른 이야기를 하고 있어서, 자료를 정말 잘 찾아야겠구나 하는 생각이 드네요! 그대로 믿다가는 이런저런 삽질을 할 수도 있으니 여러 방면을 잘 찾아봐야겠습니다.
4. 적용 과정
이제 이걸 실제로 적용을 합니다.
1) 라이브러리 추가
// 아래 두 라이브러리는 버전을 통일해서 사용하길 권장합니다.
implementation 'io.sentry:sentry-spring-boot-starter-jakarta:7.20.0'
implementation 'io.sentry:sentry-jdbc:7.20.0'
2) application.yml 수정
spring:
datasource:
url: jdbc:p6spy:mysql://localhost:3306/dev
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
username: username
password: password
'jdbc:mysql' 로 구성되어있던 프로토콜의 사이에 p6spy를 끼워넣어줍니다.
이 방식은 p6spy 라이브러리에서 사용하는 방식과 동일합니다.
드라이버도 마찬가지로 p6spy를 사용합니다.
(많은 DB의 종류가 가능하지만, 지원하지 않는 종류 - ElasticSearch 등.. 이 있을 수도 있으니 특이한 DB를 사용한다면 우선 확인이 필요합니다. - 아래는 가장 처음 찾은 Document에서의 내용을 일부 발췌함)
Sentry tries to extract metrics for all SQL-like dialects, as well as MongoDB. Other NoSQL databases like Elasticsearch, graph databases like Neo4j, and other non-SQL database systems are not currently eligible for this feature.
Sentry는 MongoDB뿐만 아니라 모든 SQL 유사 방언에 대한 메트릭을 추출하려고 시도합니다. Elasticsearch와 같은 다른 NoSQL 데이터베이스, Neo4j와 같은 그래프 데이터베이스 및 기타 비 SQL 데이터베이스 시스템은 현재 이 기능에 적합하지 않습니다.
3) spy.properties (추가)
modulelist=com.p6spy.engine.spy.P6SpyFactory
해당 파일은 p6spy의 설정 파일로, 없어도 기본적으로 적용되는 설정이 있으니 Sentry에서 쿼리 정보를 수집하는데에는 문제없습니다.
하지만 이 파일도 추가해주는 것을 공식문서에서도 추천하고, 저도 필수라고 생각합니다.
해당 설정을 안하고 실행하게 된다면 새로운 파일이 하나 추가되는데요. 바로 spy.log입니다.
아래 이미지와 같은 엄청나게 저장공간을 잡아먹을 것 같은 로그 파일이 생성되는데, 우리는 Sentry에서 확인할 것이기 때문에 용량 최적화 측면에서도 없애주는것이 나아 보입니다. (놀랍게도 로컬에서 프로젝트를 실행만 했을 뿐인데, 40줄의 로그가 쌓였습니다 ㅋㅋ)
5. 결과
이렇게 간단한 과정을 마치게 되면 우리는 이제 Sentry에서 쿼리 관련 통계 데이터를 확인할 수 있게 됩니다.
이런 기능을 적용하는건 리팩토링 과정에서 정말 효율적으로 우선순위를 파악할 수 있는 기준이 될 것이라고 생각합니다.
하지만 이 기능을 반드시 넣어야한다는 생각을 하지는 않는데요. 이런 로그 데이터를 수집하게 되면서 응답 시간에서의 손실이 약간이지만 발생할 것이기 때문입니다. (쿼리가 실행될 때마다 중간 과정이 추가되는 것이기 때문에...)
이 기능을 넣으실 분들은 실제 활발하게 운영되고 있는 서버에 적용할 것이라면 이런 트레이드오프를 한번쯤 더 생각해보면 좋을 것 같습니다. 이 세상에 완벽한 아키텍처나, 구조는 정해지지 않았기 때문에 어떤 점을 더 고려하느냐에 따라서 여러분의 시스템에 가장 적합한 선택을 하시길 바랍니다!
읽어주셔서 감사합니다 :)
'💻 개발' 카테고리의 다른 글
블루-그린 무중단 배포에서 Downtime을 측정해보자 (0) | 2025.05.12 |
---|---|
프리티어에서 블루-그린 무중단 배포를 해보자 (0) | 2025.03.16 |
FastAPI 프로젝트에 Ruff 포맷팅을 적용해보자 (0) | 2025.02.03 |
Spring Boot에서 DB에 초기 데이터를 넣어보자 (0) | 2025.02.02 |
@OneToOne 연관에서 발생한 N+1 문제를 해결하자 (0) | 2025.01.17 |