목차
Post not found: springboot/spring-aop/log-trace/log-trace-01
Post not found: springboot/spring-aop/log-trace/log-trace-02
Post not found: springboot/spring-aop/log-trace/log-trace-03
Spring 핵심원리 고급편 - Logging Filter 파라미터 동기화 개발Logging Filter 파라미터 동기화 개발@Slf4j@Componentpublic class HelloTraceV2 { private static final String START_PREFIX = "-->"; private static final String COMPLETE_PREFIX = "<--"; private static final String EX_PREFIX = "<X-"; public TraceStatus begin(String message) { TraceId traceId = new TraceId(); Long startTimeMs = System.currentTimeMillis(); log.info("[{}] {}{}", traceId.getId(), addSpace(START_PREFIX, traceId.getLevel()), message); return new TraceStatus(traceId, startTimeMs, message); } public TraceStatus beginSync(TraceId beforeTraceId, String message) { TraceId nextId = beforeTraceId.createNextId(); Long startTimeMs = System.currentTimeMillis(); log.info("[{}] {}{}", nextId.getId(), addSpace(START_PREFIX, nextId.getLevel()), message); return new TraceStatus(nextId, startTimeMs, message); } public void end(TraceStatus status) { complete(status, null); } public void exception(TraceStatus status, Exception e) { complete(status, e); } private void complete(TraceStatus status, Exception e) { Long stopTimeMs = System.currentTimeMillis(); long resultTimeMs = stopTimeMs - status.getStartTimeMs(); TraceId traceId = status.getTraceId(); if (e == null) { log.info("[{}] {}{} time={}ms", traceId.getId(), addSpace(COMPLETE_PREFIX, traceId.getLevel()), status.getMessage(), resultTimeMs); } else { log.info("[{}] {}{} time={}ms ex={}", traceId.getId(), addSpace(EX_PREFIX, traceId.getLevel()), status.getMessage(), resultTimeMs, e.toString()); } } private static String addSpace(String prefix, int level) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < level; i++) { sb.append((i == level - 1) ? "|" + prefix : "| "); } return sb.toString(); }}
@RestController@RequiredArgsConstructorpublic class OrderControllerV2 { private final OrderServiceV2 orderService; private final HelloTraceV2 trace; @GetMapping("/v2/request") public String request(String itemId){ System.out.println(itemId); TraceStatus status = null; try { status = trace.begin("OrderController.request()"); orderService.orderItem(status.getTraceId(), itemId); trace.end(status); return "ok"; }catch (Exception e){ trace.exception(status, e); throw e; // 예외를 반드시 던져 줘야 한다. } }}
@Service@RequiredArgsConstructorpublic class OrderServiceV2 { private final OrderRepositoryV2 orderRepository; private final HelloTraceV2 trace; public void orderItem(TraceId traceId, String itemId){ TraceStatus status = null; try { status = trace.beginSync(traceId, "OrderService.orderItem()"); orderRepository.save(status.getTraceId(),itemId); trace.end(status); }catch (Exception e){ trace.exception(status, e); throw e; // 예외를 반드시 던져 줘야 한다. } }}
@Repository@RequiredArgsConstructorpublic class OrderRepositoryV2 { private final HelloTraceV2 trace; public void save(TraceId traceId, String itemId){ TraceStatus status = null; try { status = trace.beginSync(traceId,"OrderRepository.save()"); // 저장 로직 if(itemId.equals("ex")){ throw new IllegalStateException("예외 발생!"); } sleep(1000); trace.end(status); }catch (Exception e){ trace.exception(status, e); throw e; // 예외를 반드시 던져 줘야 한다. } } private void sleep(int millis) { try{ Thread.sleep(millis); }catch (InterruptedException e){ e.printStackTrace(); } }}