문제 상황
- 이미지 저장 시, p6spy 로그 길이가 너무 길어짐
- 운영서버에 적용하지 않은 로그였지만, 개발 서버의 로그 용량이 불필요하게 커졌다.
이 글에서 다루지 않는 부분
- 성능 이슈
- 설치법
해결 방법
다음 블로그를 참고했다. p6spy 구조를 잘 정리해놨고, 샘플 코드도 있다.
https://backtony.tistory.com/34
여유가 있다면 글을 정독하는 것도 좋다.
post 테이블의 image 컬럼에 test
란 값을 넣을 때 바인딩 로그는 다음과 같다.
insert into post (image,id) values ('test',default)
우리가 보내는 데이터는 작은따옴표(’
)로 둘러쌓이기 때문에 이 값들만 뽑아내, 길다 싶은 문자열을 잘라내거나 다른 문자로 치환하면 된다.
이 값을 추출하는 작업을 정규표현식으로 처리했다.
([^']*)
전체 코드는 다음과 같다.
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 org.springframework.util.StringUtils;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@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) {
sql = replaceStringLengthMore50(sql); // 긴 값을 대체하는 메소드
sql = FormatStyle.HIGHLIGHT.getFormatter().format(sql);
sql = formatSql(category, sql);
return String.format("[%s] | %d ms | %s", category, elapsed, formatSql(category, sql));
}
/**
* 복붙한 코드
* reference: https://backtony.tistory.com/34
*/
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;
}
/**
* sql 내부에서 길이가 50자 이상인 값은 대체 문자열로 치환
* @param sql 바인딩된 원본 sql
* @return 치환된 문자열이 있는 sql
*/
private String replaceStringLengthMore50(String sql) {
Pattern pattern = Pattern.compile("\'(.*?)\'");
Matcher matcher = pattern.matcher(sql);
while (matcher.find()) {
String value = matcher.group();
if (StringUtils.hasLength(value) && value.length() > 50) {
sql = sql.replace(value, "'USE DEBUG MODE'");
}
}
return sql;
}
}
이렇게 만든 클래스를 p6spy Config에 등록한다.
import com.p6spy.engine.spy.P6SpyOptions;
import jakarta.annotation.PostConstruct;
import org.springframework.context.annotation.Configuration;
@Configuration
public class P6spyConfig {
@PostConstruct
public void setLogMessageFormat() {
P6SpyOptions.getActiveInstance().setLogMessageFormat(P6SpySqlFormatter.class.getName());
}
}
이제 매우 긴 데이터를 보내면 다음과 같이 처리된다.
RequestBody
{
"image": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
}
치환 전
insert into post (image,id) values ('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz',default)
치환 후
insert into post (image,id) values ('USE DEBUG MODE',default)
Reference
'개발' 카테고리의 다른 글
ArrayBuffer, Blob (0) | 2024.11.09 |
---|---|
단위 테스트 적용하기 (0) | 2024.10.26 |
[python] pandas csv 분할 중 .0 .1 문제 (0) | 2024.08.29 |
proxyBeanMethods=false를 써야 하는지 (0) | 2024.07.21 |
[Java] 토큰 인증 처리에 대한 정리 (0) | 2024.05.18 |