Skip to content

Commit b51f1fa

Browse files
authored
Merge pull request #1346 from utmstack/backlog/mdc-request-context-logging
Backlog/mdc request context logging
2 parents 6ec2069 + aa03fb1 commit b51f1fa

56 files changed

Lines changed: 708 additions & 428 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<properties>
1515
<!-- Build properties -->
1616
<maven.version>3.3.9</maven.version>
17-
<java.version>11</java.version>
17+
<java.version>17</java.version>
1818
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1919
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
2020
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
@@ -33,7 +33,7 @@
3333
<jhipster-dependencies.version>7.3.1</jhipster-dependencies.version>
3434
<!-- The spring-boot version should match the one managed by
3535
https://mvnrepository.com/artifact/tech.jhipster/jhipster-dependencies/${jhipster-dependencies.version} -->
36-
<spring-boot.version>2.5.5</spring-boot.version>
36+
<spring-boot.version>3.1.5</spring-boot.version>
3737
<!-- The hibernate version should match the one managed by
3838
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/${spring-boot.version} -->
3939
<hibernate.version>5.4.32.Final</hibernate.version>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.park.utmstack.advice;
2+
3+
4+
import com.park.utmstack.security.TooMuchLoginAttemptsException;
5+
import com.park.utmstack.service.application_events.ApplicationEventService;
6+
import com.park.utmstack.util.ResponseUtil;
7+
import com.park.utmstack.util.exceptions.TfaVerificationException;
8+
import lombok.RequiredArgsConstructor;
9+
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.http.ResponseEntity;
12+
import org.springframework.security.authentication.BadCredentialsException;
13+
import org.springframework.web.bind.annotation.ExceptionHandler;
14+
import org.springframework.web.bind.annotation.RestControllerAdvice;
15+
16+
import javax.servlet.http.HttpServletRequest;
17+
import java.util.NoSuchElementException;
18+
19+
@Slf4j
20+
@RestControllerAdvice
21+
@RequiredArgsConstructor
22+
public class GlobalExceptionHandler {
23+
24+
private final ApplicationEventService applicationEventService;
25+
26+
@ExceptionHandler(TfaVerificationException.class)
27+
public ResponseEntity<?> TfaVerificationException(TfaVerificationException e, HttpServletRequest request) {
28+
return ResponseUtil.buildErrorResponse(HttpStatus.PRECONDITION_FAILED, e.getMessage());
29+
}
30+
31+
@ExceptionHandler(BadCredentialsException.class)
32+
public ResponseEntity<?> handleForbidden(BadCredentialsException e, HttpServletRequest request) {
33+
return ResponseUtil.buildUnauthorizedResponse(e.getMessage());
34+
}
35+
36+
@ExceptionHandler(TooMuchLoginAttemptsException.class)
37+
public ResponseEntity<?> handleTooManyLoginAttempts(TooMuchLoginAttemptsException e, HttpServletRequest request) {
38+
return ResponseUtil.buildLockedResponse(e.getMessage());
39+
}
40+
41+
@ExceptionHandler(NoSuchElementException.class)
42+
public ResponseEntity<?> handleNotFound(NoSuchElementException e, HttpServletRequest request) {
43+
return ResponseUtil.buildNotFoundResponse(e.getMessage());
44+
}
45+
46+
@ExceptionHandler(Exception.class)
47+
public ResponseEntity<?> handleGenericException(Exception e, HttpServletRequest request) {
48+
return ResponseUtil.buildInternalServerErrorResponse(e.getMessage());
49+
}
50+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.park.utmstack.aop.logging;
2+
3+
import com.park.utmstack.domain.application_events.enums.ApplicationEventType;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
@Target(ElementType.METHOD)
11+
@Retention(RetentionPolicy.RUNTIME)
12+
public @interface AuditEvent {
13+
ApplicationEventType value();
14+
String message() default "";
15+
}
16+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.park.utmstack.aop.logging;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Target(ElementType.METHOD)
9+
@Retention(RetentionPolicy.RUNTIME)
10+
public @interface Loggable {
11+
}
12+
13+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.park.utmstack.aop.logging;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Target(ElementType.TYPE)
9+
@Retention(RetentionPolicy.RUNTIME)
10+
public @interface NoLogException {}
11+

backend/src/main/java/com/park/utmstack/aop/logging/AlertLoggingAspect.java renamed to backend/src/main/java/com/park/utmstack/aop/logging/impl/AlertLoggingAspect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.park.utmstack.aop.logging;
1+
package com.park.utmstack.aop.logging.impl;
22

33
import com.park.utmstack.config.Constants;
44
import com.park.utmstack.domain.UtmAlertLog;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.park.utmstack.aop.logging.impl;
2+
3+
import com.park.utmstack.aop.logging.AuditEvent;
4+
import com.park.utmstack.aop.utils.AuditContextExtractor;
5+
import com.park.utmstack.loggin.LogContextBuilder;
6+
import com.park.utmstack.service.application_events.ApplicationEventService;
7+
import lombok.RequiredArgsConstructor;
8+
import org.aspectj.lang.ProceedingJoinPoint;
9+
import org.aspectj.lang.annotation.Around;
10+
import org.aspectj.lang.annotation.Aspect;
11+
import org.springframework.stereotype.Component;
12+
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
@Aspect
17+
@Component
18+
@RequiredArgsConstructor
19+
public class AuditEventAspect {
20+
21+
private final ApplicationEventService applicationEventService;
22+
private final LogContextBuilder logContextBuilder;
23+
private final List<AuditContextExtractor> extractors;
24+
25+
@Around("@annotation(auditEvent)")
26+
public Object logAuditEvent(ProceedingJoinPoint joinPoint, AuditEvent auditEvent) throws Throwable {
27+
Object result = joinPoint.proceed();
28+
29+
Map<String, Object> args = logContextBuilder.buildArgs();
30+
for (AuditContextExtractor extractor : extractors) {
31+
args.putAll(extractor.extract(joinPoint));
32+
}
33+
applicationEventService.createEvent(auditEvent.message(), auditEvent.value(), args);
34+
35+
return result;
36+
}
37+
}
38+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.park.utmstack.aop.logging.impl;
2+
3+
import com.park.utmstack.aop.logging.NoLogException;
4+
import com.park.utmstack.loggin.LogContextBuilder;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.extern.slf4j.Slf4j;
7+
import net.logstash.logback.argument.StructuredArguments;
8+
import org.aspectj.lang.ProceedingJoinPoint;
9+
import org.aspectj.lang.annotation.Around;
10+
import org.aspectj.lang.annotation.Aspect;
11+
import org.aspectj.lang.reflect.MethodSignature;
12+
import org.slf4j.MDC;
13+
import org.springframework.stereotype.Component;
14+
15+
@Aspect
16+
@Slf4j
17+
@Component
18+
@RequiredArgsConstructor
19+
public class ControllerTracingAspect {
20+
21+
private final LogContextBuilder logContextBuilder;
22+
23+
@Around("within(@org.springframework.web.bind.annotation.RestController *)")
24+
public Object enrichMDC(ProceedingJoinPoint joinPoint) throws Throwable {
25+
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
26+
String context = signature.getDeclaringType().getSimpleName() + "." + signature.getMethod().getName();
27+
MDC.put("context", context);
28+
29+
try {
30+
return joinPoint.proceed();
31+
} catch (Exception e) {
32+
if (!e.getClass().isAnnotationPresent(NoLogException.class)) {
33+
String msg = String.format("%s: %s", context, e.getMessage());
34+
log.error(msg, e, StructuredArguments.keyValue("args",logContextBuilder.buildArgs(e)));
35+
}
36+
throw e;
37+
}
38+
}
39+
}
40+

backend/src/main/java/com/park/utmstack/aop/logging/LoggingAspect.java renamed to backend/src/main/java/com/park/utmstack/aop/logging/impl/LoggingAspect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.park.utmstack.aop.logging;
1+
package com.park.utmstack.aop.logging.impl;
22

33
import org.aspectj.lang.JoinPoint;
44
import org.aspectj.lang.ProceedingJoinPoint;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.park.utmstack.aop.logging.impl;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.aspectj.lang.ProceedingJoinPoint;
5+
import org.aspectj.lang.annotation.Around;
6+
import org.aspectj.lang.annotation.Aspect;
7+
import org.slf4j.MDC;
8+
import org.springframework.stereotype.Component;
9+
10+
@Aspect
11+
@Component
12+
@Slf4j
13+
public class LoggingMethodAspect {
14+
@Around("@annotation(com.park.utmstack.aop.logging.Loggable)")
15+
public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable {
16+
String traceId = MDC.get("traceId");
17+
String methodName = joinPoint.getSignature().toShortString();
18+
long start = System.currentTimeMillis();
19+
20+
try {
21+
Object result = joinPoint.proceed();
22+
long duration = System.currentTimeMillis() - start;
23+
log.debug("[{}] Method {} executed successfully in {}ms", traceId, methodName, duration);
24+
return result;
25+
} catch (Exception ex) {
26+
log.error("[{}] Method {} failed: {}", traceId, methodName, ex.getMessage(), ex);
27+
throw ex;
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)