From 35cf8203bacc4a32b9d8d06ed6362e718fca3a6c Mon Sep 17 00:00:00 2001 From: sohot8653 Date: Mon, 1 Sep 2025 16:12:48 +0900 Subject: [PATCH] =?UTF-8?q?[TRACE=20ID=20=EA=B4=80=EB=A6=AC]=20TraceIdFilt?= =?UTF-8?q?er=20=EB=B0=8F=20TraceIdUtils=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20HTTP=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=EC=97=90=20TRACE=20ID=EB=A5=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EA=B3=A0=20=EA=B4=80=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=ED=95=98=EC=98=80=EC=9C=BC=EB=A9=B0,=20HttpLoggingFilter?= =?UTF-8?q?=EC=97=90=EC=84=9C=20TRACE=20ID=EB=A5=BC=20=EB=A1=9C=EA=B9=85?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0=ED=95=98?= =?UTF-8?q?=EC=98=80=EC=8A=B5=EB=8B=88=EB=8B=A4.=20application.properties?= =?UTF-8?q?=EC=97=90=EC=84=9C=20Hibernate=20SQL=20=ED=95=98=EC=9D=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EC=84=A4=EC=A0=95=EC=9D=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EA=B3=A0,=20logback-spring.xml?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=A1=9C=EA=B7=B8=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=EC=97=90=20TRACE=20ID=EB=A5=BC=20=ED=8F=AC=ED=95=A8=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=ED=95=98=EC=98=80?= =?UTF-8?q?=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/filter/HttpLoggingFilter.java | 14 ++++- .../global/filter/TraceIdFilter.java | 51 +++++++++++++++++++ .../global/utils/TraceIdUtils.java | 27 ++++++++++ src/main/resources/application.properties | 2 +- src/main/resources/logback-spring.xml | 6 +-- 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/bio/bio_backend/global/filter/TraceIdFilter.java create mode 100644 src/main/java/com/bio/bio_backend/global/utils/TraceIdUtils.java diff --git a/src/main/java/com/bio/bio_backend/global/filter/HttpLoggingFilter.java b/src/main/java/com/bio/bio_backend/global/filter/HttpLoggingFilter.java index fd525b7..0bd92b0 100644 --- a/src/main/java/com/bio/bio_backend/global/filter/HttpLoggingFilter.java +++ b/src/main/java/com/bio/bio_backend/global/filter/HttpLoggingFilter.java @@ -6,6 +6,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.springframework.core.annotation.Order; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper; @@ -14,9 +15,11 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.*; +import org.slf4j.MDC; @Slf4j @Component +@Order(2) public class HttpLoggingFilter extends OncePerRequestFilter { private static final int MAX_LOG_BODY = 10 * 1024; // 10 KB @@ -38,7 +41,7 @@ public class HttpLoggingFilter extends OncePerRequestFilter { : new ContentCachingResponseWrapper(response); log.info("********************************************************************************"); - log.info("* [START] HTTP LOGGING"); + log.info("* [START] HTTP LOGGING | TRACE ID: {}", getCurrentTraceId()); log.info("* Method: {} | URI: {}", wrappedRequest.getMethod(), wrappedRequest.getRequestURI()); log.info("* Headers: {}", getRequestHeaders(wrappedRequest)); log.info("********************************************************************************"); @@ -151,4 +154,13 @@ public class HttpLoggingFilter extends OncePerRequestFilter { || path.equals("/favicon.ico") || path.startsWith("/actuator/health"); } + + /** + * 현재 스레드의 TRACE ID를 반환합니다. + * @return TRACE ID 또는 "N/A" + */ + private String getCurrentTraceId() { + String traceId = MDC.get("traceId"); + return traceId != null ? traceId : "N/A"; + } } diff --git a/src/main/java/com/bio/bio_backend/global/filter/TraceIdFilter.java b/src/main/java/com/bio/bio_backend/global/filter/TraceIdFilter.java new file mode 100644 index 0000000..b91647e --- /dev/null +++ b/src/main/java/com/bio/bio_backend/global/filter/TraceIdFilter.java @@ -0,0 +1,51 @@ +package com.bio.bio_backend.global.filter; + +import org.slf4j.MDC; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.UUID; + +@Component +@Order(1) +public class TraceIdFilter extends OncePerRequestFilter { + + private static final String TRACE_ID_HEADER = "X-Trace-Id"; + private static final String TRACE_ID_MDC_KEY = "traceId"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + + try { + // 헤더에서 TRACE ID를 가져오거나 새로 생성 + String traceId = request.getHeader(TRACE_ID_HEADER); + if (traceId == null || traceId.trim().isEmpty()) { + traceId = generateTraceId(); + } + + // MDC에 TRACE ID 설정 + MDC.put(TRACE_ID_MDC_KEY, traceId); + + // 응답 헤더에 TRACE ID 추가 + response.addHeader(TRACE_ID_HEADER, traceId); + + filterChain.doFilter(request, response); + + } finally { + // 요청 처리 완료 후 MDC 정리 + MDC.remove(TRACE_ID_MDC_KEY); + } + } + + private String generateTraceId() { + // UUID 기반 TRACE ID 생성 (8자리로 축약) + return UUID.randomUUID().toString().substring(0, 8); + } +} diff --git a/src/main/java/com/bio/bio_backend/global/utils/TraceIdUtils.java b/src/main/java/com/bio/bio_backend/global/utils/TraceIdUtils.java new file mode 100644 index 0000000..27c3187 --- /dev/null +++ b/src/main/java/com/bio/bio_backend/global/utils/TraceIdUtils.java @@ -0,0 +1,27 @@ +package com.bio.bio_backend.global.utils; + +import org.slf4j.MDC; + +/** + * TRACE ID 관리를 위한 유틸리티 클래스 + */ +public class TraceIdUtils { + + private static final String TRACE_ID_KEY = "traceId"; + + /** + * 현재 스레드의 TRACE ID를 반환합니다. + * @return TRACE ID 또는 null + */ + public static String getCurrentTraceId() { + return MDC.get(TRACE_ID_KEY); + } + + /** + * TRACE ID가 존재하는지 확인합니다. + * @return TRACE ID 존재 여부 + */ + public static boolean hasTraceId() { + return getCurrentTraceId() != null; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 31078e2..faefe87 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -32,7 +32,7 @@ spring.jpa.hibernate.ddl-auto=none spring.jpa.open-in-view=false spring.jpa.show-sql=false spring.jpa.properties.hibernate.format_sql=true -spring.jpa.properties.hibernate.highlight_sql=true +spring.jpa.properties.hibernate.highlight_sql=false spring.jpa.properties.hibernate.use_sql_comments=false # 배치 처리 설정 diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 1eab898..64c736d 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -3,7 +3,7 @@ - %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n @@ -21,7 +21,7 @@ 1GB - %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n @@ -40,7 +40,7 @@ 500MB - %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n