fix: log trace 기능 업데이트

dev
gitea-관리자 1 year ago
parent f942f124ff
commit 3b2458d6cd

@ -1,6 +1,8 @@
package kr.xit.core.aop; package kr.xit.core.aop;
import java.util.Arrays; import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -9,13 +11,17 @@ import java.util.concurrent.Future;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import kr.xit.core.support.utils.LogUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.json.simple.JSONObject;
import org.slf4j.MDC; import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@ -69,8 +75,17 @@ public class TraceLoggerAspect {
@Value("${app.slack-webhook.enabled:false}") @Value("${app.slack-webhook.enabled:false}")
private boolean isSlackEnabled; private boolean isSlackEnabled;
@Value("#{'${app.mdc.log.trace.uris}'.split(',')}") @Value("${app.log.request.custom-enabled:false}")
private String[] uris; private boolean isReqLogEnabled;
@Value("${app.log.response-enabled:false}")
private boolean isResLogEnabled;
@Value("${app.log.mdc.enabled:false}")
private boolean isMdcLogEnabled;
@Value("#{'${app.log.mdc.exclude-patterns}'.split(',')}")
private String[] excludes;
private final ILoggingService loggingService; private final ILoggingService loggingService;
private final SlackWebhookPush slackWebhookPush; private final SlackWebhookPush slackWebhookPush;
@ -83,12 +98,31 @@ public class TraceLoggerAspect {
this.slackWebhookPush = slackWebhookPush; this.slackWebhookPush = slackWebhookPush;
} }
@Pointcut("execution(public * egovframework..web.*.*(..)) || execution(public * kr.xit..web.*.*(..))")
public void requestPointCut() {
}
@Pointcut("execution(public * egovframework..*.*(..)) || execution(public * kr.xit..*.*(..))") @Pointcut("execution(public * egovframework..*.*(..)) || execution(public * kr.xit..*.*(..))")
public void errorPointCut() { public void errorPointCut() {
} }
@Pointcut("execution(public * egovframework..web.*.*(..)) || execution(public * kr.xit..web.*.*(..))")
public void resultPointCut() {
}
@Before(value = "requestPointCut()")
public void logBefore(JoinPoint joinPoint) {
if(!isReqLogEnabled) return;
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes != null? attributes.getRequest(): null;
requestLog(request, getParams(request));
log.info("Before: " + joinPoint.getSignature().getName());
}
@Around(value = "@annotation(kr.xit.core.spring.annotation.TraceLogging)") @Around(value = "@annotation(kr.xit.core.spring.annotation.TraceLogging)")
public Object serviceTraceLogging(final ProceedingJoinPoint pjp) throws Throwable { public Object serviceTraceLogging(final ProceedingJoinPoint pjp) throws Throwable {
if(!isMdcLogEnabled) return pjp.proceed();
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes != null? attributes.getRequest(): null; HttpServletRequest request = attributes != null? attributes.getRequest(): null;
@ -108,14 +142,22 @@ public class TraceLoggerAspect {
return result; return result;
} }
@AfterReturning(pointcut = "resultPointCut()", returning = "result")
public void logAfterReturning(final JoinPoint jp, final Object result) {
if(isResLogEnabled) {
log.info("{}{}{}",
"\n//============================= Http Response ==============================",
LogUtils.toString(result),
"\n=========================================================================//"
);
}
}
//@AfterThrowing(value = "@annotation(kr.xit.core.spring.annotation.TraceLogging)", throwing = "error")
@AfterThrowing(value = "errorPointCut()", throwing="error") @AfterThrowing(value = "errorPointCut()", throwing="error")
public void afterThrowingProceed(final JoinPoint jp, final Throwable error) { public void afterThrowingProceed(final JoinPoint jp, final Throwable error) {
traceLoggingError(jp, error); traceLoggingError(jp, error);
} }
/** /**
* set MDC batch reading , tasklet set trace_id set * set MDC batch reading , tasklet set trace_id set
* @param params * @param params
@ -124,7 +166,7 @@ public class TraceLoggerAspect {
protected void traceLogging(final String params, final HttpServletRequest request) { protected void traceLogging(final String params, final HttpServletRequest request) {
if(request != null) { if(request != null) {
String uri = request.getRequestURI().toString(); String uri = request.getRequestURI().toString();
if(Arrays.asList(uris).stream().anyMatch(regx -> uri.matches(regx))) return; if(Arrays.asList(excludes).stream().anyMatch(regx -> uri.matches(regx))) return;
MDC.put(REQUEST_TRACE_ID, MDC.put(REQUEST_TRACE_ID,
StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("/-/g", ""))); StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("/-/g", "")));
@ -257,4 +299,41 @@ log.info("@@@@@@@@@@@@@@@@@로깅 start : [\n{}\n]",MDC.getCopyOfContextMap());
//if(RequestContextHolder.getRequestAttributes() != null) //if(RequestContextHolder.getRequestAttributes() != null)
MDC.clear(); MDC.clear();
} }
private void requestLog(HttpServletRequest request, JSONObject params) {
if (log.isDebugEnabled()) {
Map<String, Object> map = new LinkedHashMap<>();
//sb.append("Ajax Call : " + "XMLHttpRequest".equals(request.getHeader(Globals.AJAX_HEADER))).append("\n");
map.put("URI", request.getRequestURI());
map.put("URL", request.getRequestURL());
map.put("IP", request.getRemoteAddr());
map.put("Referer URI", request.getHeader("referer"));
map.put("Method", request.getMethod());
map.put("User Agent", request.getHeader("User-Agent"));
map.put("Session", request.getSession().getId());
map.put("Locale", request.getLocale().getCountry());
map.put("ContentType", request.getContentType());
map.put("Parameters", params);
log.info("{}{}{}",
"\n//============================= Http Request ==============================",
LogUtils.toString(map),
"\n=========================================================================//"
);
map.clear();
}
}
private JSONObject getParams(HttpServletRequest request) {
JSONObject jsonObject = new JSONObject();
Enumeration<String> params = request.getParameterNames();
while (params.hasMoreElements()) {
String param = params.nextElement();
String replaceParam = param.replaceAll("\\.", "-");
jsonObject.put(replaceParam, request.getParameter(param));
}
return jsonObject;
}
} }

@ -39,8 +39,7 @@ public class SpringDocsApiConfig {
return GroupedOpenApi.builder() return GroupedOpenApi.builder()
.group("2. 카카오페이 MyDoc API") .group("2. 카카오페이 MyDoc API")
.pathsToMatch( .pathsToMatch(
"/api/kakaopay/v1/**", "/api/kakaopay/**"
"/api/kakaopay/v2/**"
) )
.build(); .build();
} }
@ -50,7 +49,7 @@ public class SpringDocsApiConfig {
return GroupedOpenApi.builder() return GroupedOpenApi.builder()
.group("3. Nice CI API") .group("3. Nice CI API")
.pathsToMatch( .pathsToMatch(
"/api/nice/v1/**" "/api/nice/**"
) )
.build(); .build();
} }
@ -60,7 +59,7 @@ public class SpringDocsApiConfig {
return GroupedOpenApi.builder() return GroupedOpenApi.builder()
.group("6. 전자고지 문서 확인 API") .group("6. 전자고지 문서 확인 API")
.pathsToMatch( .pathsToMatch(
"/api/ens/v1/**" "/api/ens/**"
) )
.build(); .build();
} }

@ -1,187 +0,0 @@
package kr.xit.core.spring.config;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import kr.xit.core.consts.Constants;
import kr.xit.core.spring.config.auth.AuthentificationInterceptor;
import kr.xit.core.spring.config.properties.CorsProperties;
import kr.xit.core.spring.filter.LoggingFilter;
import kr.xit.core.spring.filter.ReadableRequestWrapperFilter;
import kr.xit.core.spring.resolver.CustomArgumentResolver;
import kr.xit.core.spring.resolver.PageableArgumentResolver;
import lombok.RequiredArgsConstructor;
/**
* <pre>
* description : Spring MVC
* - filter, interceptor
* - AuthentificationInterceptor :
* - CommonsRequestLoggingFilter : request logging
* - ReadableRequestWrapperFilter : post logging
* - CORS
* packageName : kr.xit.core.spring.config
* fileName : WebMvcConfig
* author : julim
* date : 2023-04-28
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-04-28 julim
*
* </pre>
* @see AuthentificationInterceptor
* @see CommonsRequestLoggingFilter
* @see ReadableRequestWrapperFilter
* @see LoggingFilter
*/
@RequiredArgsConstructor
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
/**
* logging exclude path
*/
@Value("${app.param.log.exclude-patterns}")
private List<String> EXCLUDE_URL_REGEXS;
private final CorsProperties corsProperties;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthentificationInterceptor())
.addPathPatterns("/**/*")
.excludePathPatterns(
"/api/core/*"
);
}
// -------------------------------------------------------------
// RequestMappingHandlerMapping 설정 View Controller 추가
// -------------------------------------------------------------
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/cmmn/validator.do")
.setViewName("cmmn/validator");
registry.addViewController("/").setViewName("forward:/index.html");
}
//TODO :: ArgumentResolver add
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CustomArgumentResolver());
resolvers.add(new PageableArgumentResolver());
}
/**
* CommonsRequestLoggingFiler
* app.param.log.enabled: true
* @return
*/
@ConditionalOnProperty(value = "app.param.log.enabled", havingValue = "true", matchIfMissing = false)
@Bean
public FilterRegistrationBean requestLoggingFilter() {
CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter(){
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getServletPath();
return EXCLUDE_URL_REGEXS.stream().anyMatch(regex -> path.matches(regex));
}
};
loggingFilter.setIncludeClientInfo(true);
loggingFilter.setIncludeHeaders(false);
loggingFilter.setBeforeMessagePrefix("\n//========================== Request(Before) ================================\n");
loggingFilter.setBeforeMessageSuffix("\n//===========================================================================");
loggingFilter.setIncludeQueryString(true);
loggingFilter.setIncludePayload(true);
loggingFilter.setMaxPayloadLength(1024* 1024);
loggingFilter.setAfterMessagePrefix("\n//=========================== Request(After) ================================\n");
loggingFilter.setAfterMessageSuffix("\n//===========================================================================");
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>(loggingFilter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean;
}
/**
* exclude pattern
* @return FilterRegistrationBean
*/
@ConditionalOnProperty(value = "app.param.log.custom.enabled", havingValue = "true", matchIfMissing = false)
@Bean
public FilterRegistrationBean loggingFilter() {
Map<String, String> initMap = new HashMap<>();
initMap.put("excludedUrls", StringUtils.join(EXCLUDE_URL_REGEXS,","));
FilterRegistrationBean<Filter> frb = new FilterRegistrationBean<>(new LoggingFilter());
frb.setOrder(1);
frb.addUrlPatterns(Constants.API_URL_PATTERNS);
frb.setInitParameters(initMap);
frb.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC);
return frb;
}
/**
* Post request(stream) logging
* @return
*/
@ConditionalOnProperty(value = "app.param.log.custom.enabled", havingValue = "true", matchIfMissing = false)
@Bean
public FilterRegistrationBean readableRequestWrapperFilter() {
ReadableRequestWrapperFilter readableRequestWrapperFilter = new ReadableRequestWrapperFilter();
FilterRegistrationBean bean = new FilterRegistrationBean(readableRequestWrapperFilter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(corsProperties.getAllowedOrigins().split(","))
.allowedMethods(corsProperties.getAllowedMethods().split(","))
.allowedHeaders(corsProperties.getAllowedHeaders().split(","))
.allowCredentials(corsProperties.getAllowCredentials())
.maxAge(corsProperties.getMaxAge())
.exposedHeaders(corsProperties.getExposeHeader());
}
// /**
// * HandlerExceptionResolver 를 상속받은 resolver 등록
// * @param resolvers the list of configured resolvers to extend
// */
// @Override
// public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
// HandlerExceptionResolver exceptionHandlerExceptionResolver = resolvers.stream().filter(x -> x instanceof ExceptionHandlerExceptionResolver).findAny().get();
// int index = resolvers.indexOf(exceptionHandlerExceptionResolver);
// resolvers.add(index, new CustomRuntimeResolver());
// WebMvcConfigurer.super.extendHandlerExceptionResolvers(resolvers);
// }
}

@ -3,21 +3,28 @@
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
app: app:
# request log #---------------------------------------------------------------
param: # log 설정
log: # request:
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
# response-enabled : 호출 결과 출력 - 운영시 false
# mdc : api 호출(서비스) 로그 기록
# uris : api 호출 로그 제외 패턴
#---------------------------------------------------------------
log:
request:
# exclude pattern : CommonsRequestLoggingFilter && LoggingFilter 적용 # exclude pattern : CommonsRequestLoggingFilter && LoggingFilter 적용
exclude-patterns: '/swagger-ui/(.*), /api-docs/(.*)' exclude-patterns: '/swagger-ui/(.*), /api-docs/(.*)'
custom-enabled: false
# CommonsRequestLoggingFilter 사용 parameter 로그 출력 # CommonsRequestLoggingFilter 사용 parameter 로그 출력
enabled: true common-enabled: false
# parameter custom 로그 출력(LoggerAspect) # Filter를 사용한 로그 출력
custom.enabled: false filter-enabled: false
# MDC logging trace 활성 response-enabled: false
mdc: mdc:
log: enabled: false
trace: exclude-patterns: '/api/kakao/(.*), /api/v1/ens/sendBulks(.*)'
enabled: false
uris: '/api/kakao/(.*), /api/v1/ens/sendBulks(.*)'
# slack # slack
slack-webhook: slack-webhook:

@ -51,14 +51,23 @@ app:
data: data:
root: root:
path: /data path: /data
param:
log: #---------------------------------------------------------------
# CommonsRequestLoggingFilter 사용 parameter 로그 출력 # log 설정
# request:
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
# response-enabled : 호출 결과 출력 - 운영시 false
# mdc : api 호출(서비스) 로그 기록
# uris : api 호출 로그 제외 패턴
#---------------------------------------------------------------
log:
request:
custom-enabled: true
response-enabled: true
# MDC logging trace 활성
mdc:
enabled: true enabled: true
# parameter custom 로그 출력(LoggerAspect)
custom.enabled: true
# MDC logging trace 활성
mdc.log.trace.enabled: true
# slack # slack
slack-webhook: slack-webhook:

@ -73,14 +73,23 @@ app:
data: data:
root: root:
path: D:/data path: D:/data
param:
log: #---------------------------------------------------------------
# CommonsRequestLoggingFilter 사용 parameter 로그 출력 # log 설정
enabled: true # request:
# parameter custom 로그 출력(LoggerAspect) # custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
custom.enabled: true # --> 운영: common-enabled, 개발: custom-enabled 사용 권장
# MDC logging trace 활성 # response-enabled : 호출 결과 출력 - 운영시 false
mdc.log.trace.enabled: true # mdc : api 호출(서비스) 로그 기록
# uris : api 호출 로그 제외 패턴
#---------------------------------------------------------------
log:
request:
custom-enabled: true
response-enabled: true
# MDC logging trace 활성
mdc:
enabled: false
# slack # slack
slack-webhook: slack-webhook:

@ -77,14 +77,21 @@ app:
data: data:
root: root:
path: d:/data path: d:/data
param: #---------------------------------------------------------------
log: # log 설정
# CommonsRequestLoggingFilter 사용 parameter 로그 출력 # request:
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
# response-enabled : 호출 결과 출력 - 운영시 false
# mdc : api 호출(서비스) 로그 기록
# uris : api 호출 로그 제외 패턴
#---------------------------------------------------------------
log:
request:
common-enabled: true
# MDC logging trace 활성
mdc:
enabled: true enabled: true
# parameter custom 로그 출력(LoggerAspect)
custom.enabled: true
# MDC logging trace 활성
mdc.log.trace.enabled: true
# slack # slack
slack-webhook: slack-webhook:

@ -69,8 +69,8 @@ public class TraceLoggerAspect {
@Value("${app.slack-webhook.enabled:false}") @Value("${app.slack-webhook.enabled:false}")
private boolean isSlackEnabled; private boolean isSlackEnabled;
@Value("#{'${app.mdc.log.trace.uris}'.split(',')}") @Value("#{'${app.log.mdc.exclude-patterns}'.split(',')}")
private String[] uris; private String[] excludes;
private final ILoggingService loggingService; private final ILoggingService loggingService;
private final SlackWebhookPush slackWebhookPush; private final SlackWebhookPush slackWebhookPush;
@ -124,7 +124,7 @@ public class TraceLoggerAspect {
protected void traceLogging(final String params, final HttpServletRequest request) { protected void traceLogging(final String params, final HttpServletRequest request) {
if(request != null) { if(request != null) {
String uri = request.getRequestURI().toString(); String uri = request.getRequestURI().toString();
if(Arrays.asList(uris).stream().anyMatch(regx -> uri.matches(regx))) return; if(Arrays.asList(excludes).stream().anyMatch(regx -> uri.matches(regx))) return;
MDC.put(REQUEST_TRACE_ID, MDC.put(REQUEST_TRACE_ID,
StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("/-/g", ""))); StringUtils.defaultString(MDC.get("request_trace_batch_id"), UUID.randomUUID().toString().replaceAll("/-/g", "")));

@ -50,8 +50,8 @@ public class SpringDocsConfig {
.description("잘못된 부분이나 오류 발생 시 바로 말씀해주세요.") // 문서 설명 .description("잘못된 부분이나 오류 발생 시 바로 말씀해주세요.") // 문서 설명
.contact(new Contact() // 연락처 .contact(new Contact() // 연락처
.name("관리자") .name("관리자")
.email("admin@xit.co.kr") .email("admin@xit.co.kr"));
.url("http://www.xerotech.co.kr/")); //.url("http://www.xerotech.co.kr/"));
List<Server> servers = Collections.singletonList(new Server().url(url).description(name + "(" + active + ")")); List<Server> servers = Collections.singletonList(new Server().url(url).description(name + "(" + active + ")"));

@ -3,12 +3,18 @@ package kr.xit.core.spring.config;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import kr.xit.core.consts.Constants;
import kr.xit.core.spring.config.auth.AuthentificationInterceptor;
import kr.xit.core.spring.config.properties.CorsProperties;
import kr.xit.core.spring.filter.LoggingFilter;
import kr.xit.core.spring.filter.ReadableRequestWrapperFilter;
import kr.xit.core.spring.resolver.CustomArgumentResolver;
import kr.xit.core.spring.resolver.PageableArgumentResolver;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -19,20 +25,11 @@ import org.springframework.core.Ordered;
import org.springframework.web.filter.CommonsRequestLoggingFilter; import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import kr.xit.core.consts.Constants;
import kr.xit.core.spring.config.auth.AuthentificationInterceptor;
import kr.xit.core.spring.config.properties.CorsProperties;
import kr.xit.core.spring.filter.LoggingFilter;
import kr.xit.core.spring.filter.ReadableRequestWrapperFilter;
import kr.xit.core.spring.filter.SimpleCORSFilter;
import kr.xit.core.spring.resolver.CustomArgumentResolver;
import kr.xit.core.spring.resolver.PageableArgumentResolver;
import lombok.RequiredArgsConstructor;
/** /**
* <pre> * <pre>
* description : Spring MVC * description : Spring MVC
@ -54,16 +51,16 @@ import lombok.RequiredArgsConstructor;
* @see AuthentificationInterceptor * @see AuthentificationInterceptor
* @see CommonsRequestLoggingFilter * @see CommonsRequestLoggingFilter
* @see ReadableRequestWrapperFilter * @see ReadableRequestWrapperFilter
* @see SimpleCORSFilter
* @see LoggingFilter * @see LoggingFilter
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Configuration @Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {
/** /**
* logging exclude path * logging exclude path
*/ */
@Value("${app.param.log.exclude-patterns}") @Value("${app.log.request.exclude-patterns}")
private List<String> EXCLUDE_URL_REGEXS; private List<String> EXCLUDE_URL_REGEXS;
private final CorsProperties corsProperties; private final CorsProperties corsProperties;
@ -87,12 +84,29 @@ public class WebMvcConfig implements WebMvcConfigurer {
registry.addViewController("/").setViewName("forward:/index.html"); registry.addViewController("/").setViewName("forward:/index.html");
} }
//TODO :: ArgumentResolver add
@Override @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { public void addCorsMappings(CorsRegistry registry) {
resolvers.add(new CustomArgumentResolver()); registry.addMapping("/api/**")
resolvers.add(new PageableArgumentResolver()); .allowedOrigins(corsProperties.getAllowedOrigins().split(","))
//WebMvcConfigurer.super.addArgumentResolvers(resolvers); .allowedMethods(corsProperties.getAllowedMethods().split(","))
.allowedHeaders(corsProperties.getAllowedHeaders().split(","))
.allowCredentials(corsProperties.getAllowCredentials())
.maxAge(corsProperties.getMaxAge())
.exposedHeaders(corsProperties.getExposeHeader());
}
/**
* Post request(stream) logging
* @return
*/
@Bean
public FilterRegistrationBean readableRequestWrapperFilter() {
ReadableRequestWrapperFilter readableRequestWrapperFilter = new ReadableRequestWrapperFilter();
FilterRegistrationBean bean = new FilterRegistrationBean(readableRequestWrapperFilter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean;
} }
/** /**
@ -100,7 +114,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
* app.param.log.enabled: true * app.param.log.enabled: true
* @return * @return
*/ */
@ConditionalOnProperty(value = "app.param.log.enabled", havingValue = "true", matchIfMissing = false) @ConditionalOnProperty(value = "app.log.request.common-enabled", havingValue = "true", matchIfMissing = false)
@Bean @Bean
public FilterRegistrationBean requestLoggingFilter() { public FilterRegistrationBean requestLoggingFilter() {
CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter(){ CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter(){
@ -128,10 +142,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
} }
/** /**
* exclude pattern * Logging Filter
* @return FilterRegistrationBean * @return FilterRegistrationBean
*/ */
@ConditionalOnProperty(value = "app.param.log.custom.enabled", havingValue = "true", matchIfMissing = false) @ConditionalOnProperty(value = "app.log.request.filter-enabled", havingValue = "true", matchIfMissing = false)
@Bean @Bean
public FilterRegistrationBean loggingFilter() { public FilterRegistrationBean loggingFilter() {
Map<String, String> initMap = new HashMap<>(); Map<String, String> initMap = new HashMap<>();
@ -146,34 +160,11 @@ public class WebMvcConfig implements WebMvcConfigurer {
return frb; return frb;
} }
/** //TODO :: ArgumentResolver add
* Post request(stream) logging
* @return
*/
@ConditionalOnProperty(value = "app.param.log.custom.enabled", havingValue = "true", matchIfMissing = false)
@Bean
public FilterRegistrationBean readableRequestWrapperFilter() {
ReadableRequestWrapperFilter readableRequestWrapperFilter = new ReadableRequestWrapperFilter();
FilterRegistrationBean bean = new FilterRegistrationBean(readableRequestWrapperFilter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean;
}
/**
* CORS Filter
* @return
*/
@Override @Override
public void addCorsMappings(CorsRegistry registry) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
registry.addMapping("/batch/**") resolvers.add(new CustomArgumentResolver());
.allowedOrigins(corsProperties.getAllowedOrigins().split(",")) resolvers.add(new PageableArgumentResolver());
.allowedMethods(corsProperties.getAllowedMethods().split(","))
.allowedHeaders(corsProperties.getAllowedHeaders().split(","))
.allowCredentials(corsProperties.getAllowCredentials())
.maxAge(corsProperties.getMaxAge())
.exposedHeaders(corsProperties.getExposeHeader());
} }

@ -32,7 +32,7 @@ import lombok.extern.slf4j.Slf4j;
/** /**
* <pre> * <pre>
* description : POST request parameter logging * description : POST request parameter logging
* packageName : kr.xit.core.spring.filter * packageName : kr.xit.core.spring.filter
* fileName : ReadableRequestWrapper * fileName : ReadableRequestWrapper
* author : julim * author : julim

@ -14,7 +14,7 @@ import lombok.extern.slf4j.Slf4j;
/** /**
* <pre> * <pre>
* description : POST request parameter logging * description : POST request parameter logging Filter
* packageName : kr.xit.core.spring.filter * packageName : kr.xit.core.spring.filter
* fileName : ReadableRequestWrapperFilter * fileName : ReadableRequestWrapperFilter
* author : julim * author : julim

Loading…
Cancel
Save