From 5ee5c5eec3a106b19f8a1703c36f22b2fee65480 Mon Sep 17 00:00:00 2001 From: limju Date: Thu, 16 Nov 2023 12:51:49 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20batch=20logging=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kr/xit/core/aop/TraceLoggerAspect.java | 279 ------------------ .../core/biz/batch/task/BatchEndTasklet.java | 2 +- .../biz/batch/task/BatchFailEndTasklet.java | 2 - .../mapper/core/logging-mysql-mapper.xml | 80 ----- 4 files changed, 1 insertion(+), 362 deletions(-) delete mode 100644 mens-batch/src/main/java/kr/xit/core/aop/TraceLoggerAspect.java delete mode 100644 mens-batch/src/main/resources/egovframework/mapper/core/logging-mysql-mapper.xml diff --git a/mens-batch/src/main/java/kr/xit/core/aop/TraceLoggerAspect.java b/mens-batch/src/main/java/kr/xit/core/aop/TraceLoggerAspect.java deleted file mode 100644 index 6bd0cf9..0000000 --- a/mens-batch/src/main/java/kr/xit/core/aop/TraceLoggerAspect.java +++ /dev/null @@ -1,279 +0,0 @@ -package kr.xit.core.aop; - -import java.util.Arrays; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import javax.servlet.http.HttpServletRequest; -import kr.xit.core.biz.model.LoggingDTO; -import kr.xit.core.biz.service.ILoggingService; -import kr.xit.core.exception.BizRuntimeException; -import kr.xit.core.model.ApiResponseDTO; -import kr.xit.core.spring.util.error.ErrorParse; -import kr.xit.core.support.slack.SlackWebhookPush; -import kr.xit.core.support.utils.JsonUtils; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.AfterThrowing; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Pointcut; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Lazy; -import org.springframework.http.HttpStatus; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -/** - *
- * description : logging trace aspect
- *               공통 core 모듈의 LoggerAspect 상속 -> traceLogging / traceLoggingError / traceLoggingResult 구현
- *
- *               Logging trace 구현시
- *               - MDC(Mapped Diagnostic Context : logback, log4j에 포함) 사용 로깅
- *               - ThreadLocal 사용
- *               - nginx : proxy_set_header X-RequestID $request_id;
- *               - logback log pattern : [traceId=%X{request_id}]
- *
- *               app.slack-webhook.enabled: true인 경우 slack push
- *               Slack webhook : SlackWebhookPush
- *
- * packageName : kr.xit.core.aop
- * fileName    : TraceLoggerAspect
- * author      : julim
- * date        : 2023-04-28
- * ======================================================================
- * 변경일         변경자        변경 내용
- * ----------------------------------------------------------------------
- * 2023-04-28    julim       최초 생성
- * 2023-06-12    julim       배치처리시 RequestContextHolder.HttpServletRequest 객체 미사용에 따른 처리 추가
- * 
- * @see kr.xit.core.support.slack.SlackWebhookPush#sendSlackAlertLog(String, String, String) - */ - -@Slf4j -//@Aspect -//@Component -public class TraceLoggerAspect { - - @Value("${app.slack-webhook.enabled:false}") - private boolean isSlackEnabled; - - @Value("#{'${app.log.mdc.exclude-patterns}'.split(',')}") - private String[] excludes; - - private final ILoggingService loggingService; - private final SlackWebhookPush slackWebhookPush; - private static final String REQUEST_TRACE_ID = "request_trace_id"; - - public TraceLoggerAspect(@Lazy ILoggingService loggingService, SlackWebhookPush slackWebhookPush) { - this.loggingService = loggingService; - this.slackWebhookPush = slackWebhookPush; - } - - @Pointcut("execution(public * egovframework..*.*(..)) || execution(public * kr.xit..*.*(..))") - public void errorPointCut() { - } - - @Around(value = "@annotation(kr.xit.core.spring.annotation.TraceLogging)") - public Object serviceTraceLogging(final ProceedingJoinPoint pjp) throws Throwable { - ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); - HttpServletRequest request = attributes != null? attributes.getRequest(): null; - - traceLogging(JsonUtils.toJson(pjp.getArgs()), request); - Object result = pjp.proceed(); - - //noinspection rawtypes - if(result instanceof CompletableFuture future){ - while(true) { - if (future.isDone()) break; - } - traceLoggingResult(future.get()); - }else{ - traceLoggingResult(result); - } - return result; - } - - - //@AfterThrowing(value = "@annotation(kr.xit.core.spring.annotation.TraceLogging)", throwing = "error") - @AfterThrowing(value = "errorPointCut()", throwing="error") - public void afterThrowingProceed(final JoinPoint jp, final Throwable error) { - log.error("+++++++++++++++>>>>>>> Batch Error log trace::{}", error.getMessage()); - traceLoggingError(jp, error); - } - - - /** - * 배치 실행시 여기에서 set한 MDC 값이 batch 모듈에서 reading이 불가하여, 배치 tasklet에서 set한 trace_id로 set - * @param params - * @param request - */ - protected void traceLogging(final String params, final HttpServletRequest request) { - if(request != null) { - String uri = request.getRequestURI().toString(); - if(Arrays.asList(excludes).stream().anyMatch(regx -> uri.matches(regx))) return; - - MDC.put(REQUEST_TRACE_ID, - StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("/-/g", ""))); - MDC.put("method", request.getMethod()); - MDC.put("uri", uri); - MDC.put("ip", request.getRemoteAddr()); - MDC.put("sessionId", request.getSession().getId()); - - // batch로 실행되는 경우 task에서 설정 : uri / method - }else{ - // request_id는 중복 처리 되면 않되므로 여기에서 생성 - MDC.put(REQUEST_TRACE_ID, StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("-", ""))); - } -//TODO::systemId, reqSystemId 설정 필요 -log.info("@@@@@@@@@@@@@@@@@로깅 start : [\n{}\n]",MDC.getCopyOfContextMap()); - MDC.put("systemId", "ENS"); - MDC.put("reqSystemId", "KAKAO"); - MDC.put("param", params); - MDC.put("accessToken", ""); - - LoggingDTO loggingDTO = LoggingDTO.builder() - .requestId(MDC.getCopyOfContextMap().get(REQUEST_TRACE_ID)) - .systemId("ENS") - .reqSystemId("KAKAO") - .method(MDC.getCopyOfContextMap().get("method")) - .uri(MDC.getCopyOfContextMap().get("uri")) - .param(params) - .ip(MDC.getCopyOfContextMap().get("ip")) - .accessToken("") - .sessionId(MDC.getCopyOfContextMap().get("sessionId")) - .build(); - loggingService.saveLogging(loggingDTO); - - } - - protected void traceLoggingResult(final Object result) { - String success = "true"; - //FIXME: slack webhook log push - if(result instanceof ApiResponseDTO apiResponseDTO){ - if(!apiResponseDTO.isSuccess()){ - success = "false"; - - if(isSlackEnabled) { - - if(RequestContextHolder.getRequestAttributes() != null) { - slackWebhookPush.sendSlackAlertLog( - String.format("[%s]%s", MDC.get(REQUEST_TRACE_ID), apiResponseDTO.getMessage()), - ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest()); - }else{ - slackWebhookPush.sendSlackAlertLog( - String.format("[%s]%s", MDC.get(REQUEST_TRACE_ID), apiResponseDTO.getMessage()), - MDC.get("uri"), - "batch call"); - } - } - }else{ - if(apiResponseDTO.getData() != null){ - log.info("~~~~"); - } - } - } - - LoggingDTO reqDTO = LoggingDTO - .builder() - .requestId(MDC.get(REQUEST_TRACE_ID)) - .success(success) - .response(getResult(result)) - .message(HttpStatus.OK.name()) - .build(); - //} - loggingService.modifyLogging(reqDTO); - //loggingService.saveLogging(reqDTO); - - log.info("@@@@@@@@@@@@@@로깅 end[\n{}\n]", MDC.getCopyOfContextMap()); - - //if(RequestContextHolder.getRequestAttributes() != null) - MDC.clear(); - //} - } - - private String getResult(final Object o){ - //noinspection rawtypes - if(o instanceof Future future) { - try { - return JsonUtils.toJson(future.get()); - } catch (InterruptedException ie){ - // thread pool에 에러 상태 전송 - Thread.currentThread().interrupt(); - throw BizRuntimeException.create(ie); - - } catch (ExecutionException ee) { - throw BizRuntimeException.create(ee); - } - }else{ - return JsonUtils.toJson(o); - } - } - - protected void traceLoggingError(final JoinPoint jp, final Throwable e) { - log.info("~~~~~~~~~~~~~~~~~~~~~~~>>>>{}", MDC.get(REQUEST_TRACE_ID)); -// if(Checks.isEmpty(MDC.get(REQUEST_TRACE_ID))) return; - - @SuppressWarnings("rawtypes") - ApiResponseDTO dto = ErrorParse.extractError(e); - - loggingService.modifyLogging( - LoggingDTO - .builder() - .requestId(MDC.get(REQUEST_TRACE_ID)) - .success("false") - .response(JsonUtils.toJson(dto)) - .message(dto.getMessage()) - .build()); - - //FIXME :: slack webhook log push - if(isSlackEnabled){ - if(RequestContextHolder.getRequestAttributes() != null) { - slackWebhookPush.sendSlackAlertLog( - String.format("[%s]%s(%s)", MDC.get(REQUEST_TRACE_ID), dto.getCode(), dto.getMessage()), - ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest()); - }else{ - slackWebhookPush.sendSlackAlertLog( - String.format("[%s]%s(%s)", MDC.get(REQUEST_TRACE_ID), dto.getCode(), dto.getMessage()), - MDC.get("uri"), - "batch call"); - } - } - log.info("@@@@@@@@@@@@ 로깅 end[\n{}\n]", MDC.getCopyOfContextMap()); - //if(RequestContextHolder.getRequestAttributes() != null) - MDC.clear(); - } - - @Getter - enum ApiSystemId { - KAKAO("KAKAO", "카카오", "/kakao/"), - KT_BC("KT-BC", "공공알림문자", "/kt/"), - PPLUS("POST-PLUS", "Post Plus", "/pplus/"), - NICE("NICE", "NICE CI", "/nice/"), - EPOST("EPOST", "E-POST", "/ag/"), - NONE("NONE", "미정의", "/미정의/"), - ; - - private final String code; - private final String desc; - private final String uri; - - ApiSystemId(final String code, final String desc, final String uri) { - this.code = code; - this.desc = desc; - this.uri = uri; - } - - public static ApiSystemId compareByUri(final String uri){ - return Arrays.stream(ApiSystemId.values()) - .filter(ssc -> uri.contains(ssc.getUri())) - .findFirst() - .orElseGet(() -> ApiSystemId.valueOf("NONE")); - } - } -} diff --git a/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchEndTasklet.java b/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchEndTasklet.java index 71960ae..23584fe 100644 --- a/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchEndTasklet.java +++ b/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchEndTasklet.java @@ -49,7 +49,7 @@ public class BatchEndTasklet implements Tasklet { .batchLogId(MDC.get("batch_log_id")) .traceId(StringUtils.defaultString(MDC.get("request_trace_id"), MDC.get("request_trace_batch_id"))) .build(); -log.info("@@@@@@@@@@@@@ BatchEndTask :: {}", MDC.getCopyOfContextMap()); + batchCmmService.modifyBatchLock(dto); batchCmmService.modifyBatchLog(dto); return RepeatStatus.FINISHED; diff --git a/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchFailEndTasklet.java b/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchFailEndTasklet.java index b4ec0b5..9cf277c 100644 --- a/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchFailEndTasklet.java +++ b/mens-batch/src/main/java/kr/xit/core/biz/batch/task/BatchFailEndTasklet.java @@ -49,11 +49,9 @@ public class BatchFailEndTasklet implements Tasklet { .batchLogId(MDC.get("batch_log_id")) .traceId(StringUtils.defaultString(MDC.get("request_trace_id"), MDC.get("request_trace_batch_id"))) .build(); - log.info("@@@@@@@@@@@@@ Batch Fail EndTask :: {}", MDC.getCopyOfContextMap()); batchCmmService.modifyBatchLock(dto); batchCmmService.modifyBatchLog(dto); - return RepeatStatus.FINISHED; } } diff --git a/mens-batch/src/main/resources/egovframework/mapper/core/logging-mysql-mapper.xml b/mens-batch/src/main/resources/egovframework/mapper/core/logging-mysql-mapper.xml deleted file mode 100644 index ac4db08..0000000 --- a/mens-batch/src/main/resources/egovframework/mapper/core/logging-mysql-mapper.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - /** logging-mysql-mapper|saveLogging|julim */ - INSERT INTO tb_cmm_api_log ( - request_id - , system_id - , req_system_id - , method - , uri - , param - , ip - , access_token - , session_id - , success - , response - , message - , regist_dt - , regist_id - ) VALUES ( - #{requestId} - , #{systemId} - , #{reqSystemId} - , #{method} - , #{uri} - , #{param} - , #{ip} - , #{accessToken} - , #{sessionId} - , #{success} - , #{response} - , #{message} - , now(3) - , #{registId} - ) - - - - /** logging-mysql-mapper|updateLogging|julim */ - UPDATE tb_cmm_api_log - SET success = #{success} - , response = #{response} - , message = #{message} - , updt_dt = now(3) - , updt_id = #{updtId} - WHERE request_id = #{requestId} - - - -