Skip to content

Commit 9892051

Browse files
committed
FEAT:(CORE) ON_ERROR 로깅 버전 추가 및 LogEnabled와 Interceptor 책임 분리
1 parent 994467a commit 9892051

File tree

11 files changed

+215
-66
lines changed

11 files changed

+215
-66
lines changed

lib/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ tasks.named('test') {
5252
useJUnitPlatform()
5353
}
5454

55-
version = '1.0.8'
55+
version = '1.0.9'
5656

5757
publishing {
5858
repositories {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package kr.teamo2.utils.interceptor;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import jakarta.servlet.http.HttpServletResponse;
5+
import kr.teamo2.utils.trackingUtil.TrackingIdContext;
6+
import lombok.extern.log4j.Log4j2;
7+
import org.springframework.stereotype.Component;
8+
import org.springframework.web.servlet.HandlerInterceptor;
9+
10+
@Log4j2
11+
@Component
12+
public class HttpLoggingInterceptor implements HandlerInterceptor {
13+
14+
private static final String START_TIME_ATTRIBUTE = "startTime";
15+
16+
@Override
17+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
18+
request.setAttribute(START_TIME_ATTRIBUTE, System.currentTimeMillis());
19+
return true;
20+
}
21+
22+
@Override
23+
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
24+
Long startTime = (Long) request.getAttribute(START_TIME_ATTRIBUTE);
25+
if (startTime != null) {
26+
long duration = System.currentTimeMillis() - startTime;
27+
String method = request.getMethod();
28+
String uri = request.getRequestURI();
29+
String queryString = request.getQueryString();
30+
String fullUrl = queryString != null ? uri + "?" + queryString : uri;
31+
int status = response.getStatus();
32+
String trackingId = TrackingIdContext.getTrackingId();
33+
34+
log.info("{}: {} | [{}] {} - {}ms", trackingId, status, method, fullUrl, duration);
35+
}
36+
}
37+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package kr.teamo2.utils.interceptor;
2+
3+
import java.io.IOException;
4+
import kr.teamo2.utils.trackingUtil.TrackingIdContext;
5+
import lombok.extern.log4j.Log4j2;
6+
import org.springframework.http.HttpRequest;
7+
import org.springframework.http.client.ClientHttpRequestExecution;
8+
import org.springframework.http.client.ClientHttpRequestInterceptor;
9+
import org.springframework.http.client.ClientHttpResponse;
10+
11+
@Log4j2
12+
public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor {
13+
14+
@Override
15+
public ClientHttpResponse intercept(
16+
HttpRequest request,
17+
byte[] body,
18+
ClientHttpRequestExecution execution) throws IOException {
19+
20+
long startTime = System.currentTimeMillis();
21+
22+
try {
23+
ClientHttpResponse response = execution.execute(request, body);
24+
long duration = System.currentTimeMillis() - startTime;
25+
26+
String host = request.getURI().getHost();
27+
String fullUrl = request.getURI().toString();
28+
log.info("{}: {} | [{}] {} -> {} - {}ms",
29+
TrackingIdContext.getTrackingId(),
30+
response.getStatusCode().value(),
31+
request.getMethod(),
32+
fullUrl,
33+
host,
34+
duration);
35+
36+
return response;
37+
} catch (Exception e) {
38+
long duration = System.currentTimeMillis() - startTime;
39+
String fullUrl = request.getURI().toString();
40+
log.error("{}: ERROR | [{}] {} - {}ms - {}",
41+
TrackingIdContext.getTrackingId(),
42+
request.getMethod(),
43+
fullUrl,
44+
duration,
45+
e.getMessage());
46+
throw e;
47+
}
48+
}
49+
}
Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package kr.teamo2.utils.loggingUtil;
22

3+
import static kr.teamo2.utils.trackingUtil.TrackingIdContext.getTrackingId;
4+
35
import com.fasterxml.jackson.core.JsonProcessingException;
46
import com.fasterxml.jackson.databind.ObjectMapper;
57
import kr.teamo2.utils.HttpServletUtil;
8+
import kr.teamo2.utils.trackingUtil.TrackingIdContext;
69
import lombok.RequiredArgsConstructor;
710
import lombok.extern.log4j.Log4j2;
811
import org.aspectj.lang.JoinPoint;
9-
import org.springframework.http.HttpMethod;
12+
import org.aspectj.lang.reflect.MethodSignature;
1013
import org.springframework.http.ResponseEntity;
1114
import org.springframework.stereotype.Component;
1215

@@ -18,54 +21,74 @@ public class ApiLogger extends LoggingPointCut {
1821
private final ObjectMapper objectMapper;
1922

2023
public void beforeLog(JoinPoint joinPoint) {
21-
String trackingId = HttpServletUtil.generateAndSetTrackingId();
24+
LogEnabled logEnabled = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(LogEnabled.class);
25+
String customTrackingId = logEnabled != null ? logEnabled.trackingId() : "";
2226

23-
Object[] args = joinPoint.getArgs();
27+
String trackingId = !customTrackingId.isEmpty() ? customTrackingId :
28+
(getTrackingId() != null ? getTrackingId() :
29+
HttpServletUtil.generateAndSetTrackingId());
30+
31+
TrackingIdContext.setTrackingId(trackingId);
2432

25-
String urlAndQueryString = HttpServletUtil.getUrlAndQueryString();
26-
RequestLog.RequestLogBuilder requestLogBuilder = RequestLog.builder()
27-
.requestID(trackingId)
28-
.url(urlAndQueryString)
29-
.method(HttpServletUtil.getHttpMethod())
30-
.header(HttpServletUtil.requestToHeaderMap());
33+
Version version = logEnabled != null ? logEnabled.version() : Version.FULL;
34+
35+
if (version == Version.ON_ERROR) {
36+
return;
37+
}
38+
39+
requestLog(joinPoint);
40+
}
41+
42+
public void afterLog(ResponseEntity response, JoinPoint joinPoint) {
43+
LogEnabled logEnabled = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(LogEnabled.class);
44+
Version version = logEnabled != null ? logEnabled.version() : Version.FULL;
45+
boolean isSuccessful = response.getStatusCode().is2xxSuccessful();
46+
47+
if(version == Version.ON_ERROR){
48+
if(isSuccessful){
49+
return;
50+
}
51+
else {
52+
requestLog(joinPoint);
53+
responseLog(response);
54+
return;
55+
}
56+
}
57+
58+
responseLog(response);
59+
}
60+
61+
private void requestLog(JoinPoint joinPoint) {
62+
String trackingId = getTrackingId();
63+
Object[] args = joinPoint.getArgs();
64+
RequestLog.RequestLogBuilder requestLogBuilder = RequestLog.builder();
3165

3266
for (Object o : args) {
33-
if (HttpServletUtil.getHttpMethod().equals(HttpMethod.POST.name())) {
34-
try {
35-
String bodyJson = objectMapper.writeValueAsString(o);
36-
requestLogBuilder.body(bodyJson);
37-
} catch (Exception e) {
38-
requestLogBuilder.body("Failed to serialize body: " + e.getMessage());
39-
}
67+
try {
68+
String requestJson = objectMapper.writeValueAsString(o);
69+
requestLogBuilder.request(requestJson);
70+
} catch (Exception e) {
71+
requestLogBuilder.request("Failed to serialize request: " + e.getMessage());
4072
}
4173
}
42-
log.info("[ApiLogger] - {}", requestLogBuilder.build());
74+
log.info("{}: {}", trackingId, requestLogBuilder.build());
4375
}
4476

45-
public void afterLog(ResponseEntity response) {
77+
private void responseLog(ResponseEntity response) {
78+
String trackingId = getTrackingId();
4679
ResponseLog responseLog;
47-
boolean isSuccessful = response.getStatusCode().is2xxSuccessful();
48-
4980
Object body = response.getBody();
50-
String bodyJson = null;
51-
81+
String responseJson = null;
5282
try {
53-
bodyJson = this.objectMapper.writeValueAsString(body);
83+
responseJson = this.objectMapper.writeValueAsString(body);
5484
} catch (JsonProcessingException e) {
55-
bodyJson = String.valueOf(body);
85+
responseJson = String.valueOf(body);
5686
}
5787

58-
responseLog = isSuccessful
59-
? ResponseLog.initSuccess()
60-
.requestId(HttpServletUtil.getTrackingId())
61-
.body(bodyJson)
62-
.build()
63-
: ResponseLog.initFail()
64-
.requestId(HttpServletUtil.getTrackingId())
65-
.body(bodyJson)
66-
.statusCode(response.getStatusCode().value())
67-
.build();
68-
69-
log.info("[ApiLogger] - {}", responseLog);
88+
responseLog = ResponseLog.builder()
89+
.response(responseJson)
90+
.build();
91+
92+
log.info("{}: {}", trackingId, responseLog);
7093
}
7194
}

lib/src/main/java/kr/teamo2/utils/loggingUtil/ApiLoggingAspect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void apiBeforeLogging(JoinPoint joinPoint) {
2525
}
2626

2727
@AfterReturning(value = "logEnabled()", returning = "response")
28-
public void apiAfterLogging(ResponseEntity response) {
29-
apiLogger.afterLog(response);
28+
public void apiAfterLogging(JoinPoint joinPoint, ResponseEntity response) {
29+
apiLogger.afterLog(response, joinPoint);
3030
}
3131
}

lib/src/main/java/kr/teamo2/utils/loggingUtil/LogEnabled.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@
1717
String collection() default "";
1818

1919
boolean isEnabled() default true;
20+
21+
Version version() default Version.FULL;
22+
23+
String trackingId() default "";
2024
}

lib/src/main/java/kr/teamo2/utils/loggingUtil/RequestLog.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,5 @@
1414
@ToString
1515
public class RequestLog {
1616

17-
private String requestID;
18-
19-
private String url;
20-
21-
private String method;
22-
23-
private Object header;
24-
25-
private Object body;
17+
private Object request;
2618
}

lib/src/main/java/kr/teamo2/utils/loggingUtil/ResponseLog.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,14 @@
1313
@ToString
1414
public class ResponseLog {
1515

16-
private String requestID;
17-
18-
private Integer statusCode;
19-
20-
private Object body;
16+
private Object response;
2117

2218
private boolean isError;
2319

24-
@Builder(builderClassName = "InitSuccess", builderMethodName = "initSuccess")
25-
public ResponseLog(String requestId, Object body) {
26-
this.requestID = requestId;
27-
this.statusCode = 200;
28-
this.body = body;
20+
@Builder
21+
public ResponseLog(Object response) {
22+
this.response = response;
2923
this.isError = false;
3024
}
31-
32-
@Builder(builderClassName = "InitFail", builderMethodName = "initFail")
33-
public ResponseLog(String requestId, Object body, Integer statusCode) {
34-
this.requestID = requestId;
35-
this.statusCode = statusCode;
36-
this.body = body;
37-
this.isError = true;
38-
}
3925
}
4026

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package kr.teamo2.utils.loggingUtil;
2+
3+
public enum Version {
4+
ON_ERROR,
5+
FULL
6+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package kr.teamo2.utils.trackingUtil;
2+
3+
public class TrackingIdContext {
4+
5+
private static final ThreadLocal<String> trackingIdHolder = new ThreadLocal<>();
6+
7+
public TrackingIdContext() {
8+
}
9+
10+
public static String getTrackingId() {
11+
return trackingIdHolder.get();
12+
}
13+
14+
public static void setTrackingId(String trackingId) {
15+
trackingIdHolder.set(trackingId);
16+
}
17+
18+
public static void clear() {
19+
trackingIdHolder.remove();
20+
}
21+
}

0 commit comments

Comments
 (0)