스프링 부트 3 버전에서 p6spy를 적용하는 방법을 알아보자.
build.gradle
아래 의존성을 build.gradle에 추가해 준다.
// P6spy
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
그리고 코끼리 모양의 'Load Gradle Changes'를 클릭해 주고 프로젝트를 실행한다.
그리고 쿼리가 실행되는 콘솔을 보면 이렇게 파라미터가 들어가 있다.
이렇게만 해도 사실 파라미터에 무슨 값이 들어가 있는지 확인은 가능하지면 여전히 한눈에 띄진 않는다.
콘솔 출력 형식을 바꾸려면 formatter를 커스텀해서 적용해 주면 된다.
P6SpyFormatter
아래는 configure 설정 코드 내용이다.
import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.P6SpyOptions;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import jakarta.annotation.PostConstruct;
import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.springframework.context.annotation.Configuration;
import java.util.Locale;
@Configuration
public class P6SpySqlFormatter implements MessageFormattingStrategy {
@PostConstruct
public void setLogMessageFormat() {
P6SpyOptions.getActiveInstance().setLogMessageFormat(this.getClass().getName());
}
@Override
public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
// 배치 테이블 관련 쿼리 제외
if (isBatchTableQuery(sql)) {
return ""; // 배치 테이블 관련 쿼리는 로그에서 제외
}
return String.format("[%s] | %d ms | %s", category, elapsed, formatSql(category, sql));
}
private boolean isBatchTableQuery(String sql) {
if (sql != null) {
String lowerCaseSql = sql.toLowerCase(Locale.ROOT);
return lowerCaseSql.contains("batch_job_instance") ||
lowerCaseSql.contains("batch_job_execution") ||
lowerCaseSql.contains("batch_step_execution") ||
lowerCaseSql.contains("batch_step_execution_context");
}
return false;
}
private String formatSql(String category, String sql) {
if (sql != null && !sql.trim().isEmpty() && Category.STATEMENT.getName().equals(category)) {
String trimmedSQL = sql.trim().toLowerCase(Locale.ROOT);
if (trimmedSQL.startsWith("create") || trimmedSQL.startsWith("alter") || trimmedSQL.startsWith("comment")) {
sql = FormatStyle.DDL.getFormatter().format(sql);
} else {
sql = FormatStyle.BASIC.getFormatter().format(sql);
}
return sql;
}
return sql;
}
}
이 코드는 스프링 부트 프로젝트에서 P6Spy 라이브러리를 사용하여 SQL 쿼리 로깅을 커스터마이징 하기 위한 것이다.
P6SpySqlFormatter 클래스는 MessageFormattingStrategy 인터페이스를 구현하여 SQL 쿼리의 로그 형식을 정의한다. 이 클래스는 몇 가지 중요한 기능을 수행한다:
커스텀 로그 메시지 형식 설정
formatMessage 메서드는 로그 메시지의 형식을 정의한다. 이 메서드는 연결 ID, 현재 시간, 쿼리 수행 시간, 쿼리 카테고리, 준비된 쿼리 문자열, 실행된 SQL, 데이터베이스 URL을 인자로 받는다. 메서드는 이러한 정보를 사용하여 로그 메시지를 포맷한다.
특정 쿼리 로그 제외
isBatchTableQuery 메서드는 SQL 쿼리 문자열을 분석하여 특정 키워드(여기서는 batch_job_instance, batch_job_execution, batch_step_execution, batch_step_execution_context)가 포함되어 있는지 확인한다. 이 메서드는 배치 관련 테이블에 대한 쿼리를 식별하여 로그에서 제외하는 데 사용된다.
(제외한 이유는 나중에 프로젝트 실행할 때 배치 테이블에 관한 쿼리가 너무 많이 나와서 제외했다.)
SQL 포맷팅
formatSql 메서드는 SQL 쿼리 문자열을 받아 해당 카테고리에 따라 포맷한다. DDL(Data Definition Language) 관련 쿼리(예: CREATE, ALTER, COMMENT)는 FormatStyle.DDL을 사용하여 포맷하고, 그 외의 쿼리는 FormatStyle.BASIC을 사용한다. 이 포맷팅은 쿼리를 더 읽기 쉽게 만든다.
P6Spy 설정에 클래스 적용
@PostConstruct 어노테이션이 붙은 setLogMessageFormat 메서드는 스프링 컨텍스트가 초기화된 후에 실행된다. 이 메서드는 P6Spy의 LogMessageFormat 설정을 현재 클래스(P6SpySqlFormatter)로 지정하여, P6Spy가 이 클래스를 사용해 로그 메시지를 포맷하도록 한다.
로깅 결과 변경
이러한 설정을 적용한 후, 콘솔에 출력되는 로그는 기본 P6Spy 형식에서 커스텀 포맷으로 변경된다. 변경 전에는 준비된 쿼리와 실행된 쿼리가 별도로 표시되었지만, 변경 후에는 포맷팅된 쿼리 하나만 보이게 된다.
이러한 방식으로, P6SpySqlFormatter 클래스는 SQL 쿼리 로그의 출력을 사용자 정의하고, 특정 유형의 쿼리(여기서는 배치 관련 쿼리)를 로그에서 제외함으로써 로그의 가독성과 관련성을 향상하는 역할을 한다.
결론적으로, P6SpySqlFormatter를 사용하면 SQL 쿼리 로그의 형식을 개선하고, 로그의 가독성과 관련성을 높일 수 있다. 이로 인해 콘솔에 출력되는 로그의 형식이 변경된 것이다.
🔻 JAVA에서 람다 표현식에서 final 변수나 effectively final 변수를 사용해야 하는 이유가 궁금하다면? 🔻
[JAVA] 람다 표현식에서 final 변수나 effectively final 변수를 사용해야 하는 이유
'Spring > Spring Boot' 카테고리의 다른 글
Spring Boot 3 버전에서 AWS SNS를 통한 SMS 발송하기 (3) | 2023.12.29 |
---|---|
헥사고날 아키텍처 실전 적용 (1) - 클래스 의존성 주입 및 도메인, 엔티티의 객체 변환 과정 (0) | 2023.12.16 |
[Spring Boot] 스프링 배치와 JPA를 활용해 누락된 SNS 이벤트 재발행 (0) | 2023.11.29 |
[Spring Boot] SNS MessageAttributes를 이용한 분산 시스템 추적용 Trace Id 전달 방법 (0) | 2023.11.28 |
[Spring Boot] 스프링 배치에서 chunk와 JPA pageSize 설정의 관계성 (0) | 2023.11.27 |