본문 바로가기
  • A space that records me :)
Language/JAVA

[JAVA] FilterChain, doFilter - API 호출 기록 DB에 저장하기

by yjkim_97 2020. 11. 19.

 

FilterChain의 doFilter사용

 

 


Bean 등록 - BeanConfig.java

    @Bean
    public ApiLoggingFilter getApiLogginFilter()
    {
    	ApiLoggingFilter apiLoggingFilter = new ApiLoggingFilter();
    	return apiLoggingFilter;
    }

 

FilterChain.doFilter() - ApiLoggingFilter.java

package com.kt.tbb.iptv.coupon.framework.servlet;

import com.kt.tbb.iptv.coupon.business.interlock.e2e.E2eService;
import com.kt.tbb.iptv.coupon.business.operation.model.ApiLog;
import com.kt.tbb.iptv.coupon.business.operation.service.ApiLogService;
import com.kt.tbb.iptv.coupon.framework.CpnConstants;
import com.kt.tbb.iptv.coupon.framework.model.ErrorResponse;
import com.kt.tbb.iptv.coupon.framework.model.HttpRequestThreadLocal;
import com.kt.tbb.iptv.coupon.framework.model.ApiRequestCache;
import java.io.IOException;
import java.util.Date;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.util.ContentCachingResponseWrapper;

public class ApiLoggingFilter extends GenericFilterBean
{

	private static final Logger LOGGER = LoggerFactory.getLogger(ApiLoggingFilter.class);

	@Autowired
	private ApiLogService apiLogService;

	@Autowired
	private E2eService e2eService;

	@Value("${cpn.process.name}")
	private String cpnProcessName;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException
	{

		LOGGER.debug("ApiLoggingFilter doFilter executed.");

		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String requestUri = httpServletRequest.getRequestURI(); // URI
		String transactionId = httpServletRequest.getHeader(CpnConstants.IPTV_TX_ID); // 트랜잭션 ID
		Date start = new Date(); // 수신시간

		chain.doFilter(request, response);

		if (StringUtils.isEmpty(transactionId))
		{
			HttpRequestThreadLocal.remove();
			return;
		}

		Long elapsedTimeMillis = System.currentTimeMillis() - start.getTime();

		ApiRequestCache restApiResponse = HttpRequestThreadLocal.getRestApiResponse();
		HttpStatus httpSttus = restApiResponse.getHttpSttus();
		ErrorResponse errorResponse = restApiResponse.getErrorResponse();
		HttpRequestThreadLocal.remove();

		try
		{
			// String serverName = request.getLocalAddr(); // HOST : 요청을 한 서버의 호스트 이름
			HttpServletRequest servletRequest = ((HttpServletRequest) request);
			String clientIp = servletRequest.getHeader("x-client-ip");
			if (StringUtils.isEmpty(clientIp))
			{
				clientIp = request.getRemoteAddr();
			}
			// String serverName = request.getServerName(); // HOST : 요청을 한 서버의 호스트 이름
			String method = servletRequest.getMethod();
			String reqBody = restApiResponse.getRequestBody();
			long contentLength = 0;
			if (response instanceof ContentCachingResponseWrapper)
			{
				contentLength = ((ContentCachingResponseWrapper) response).getContentSize();
			} else
			{
				String cl = ((HttpServletResponse) response).getHeader("Content-Length");
				contentLength = NumberUtils.toLong(cl, -1);
			}

			ApiLog apiLog = new ApiLog();
			apiLog.setRecvDt(start);
			apiLog.setElapsMs(elapsedTimeMillis.intValue());
			apiLog.setTrId(transactionId);
			apiLog.setHost(cpnProcessName);
			apiLog.setClntAddr(clientIp);
			apiLog.setMethod(method);
			apiLog.setUri(requestUri);
			apiLog.setReqBody(reqBody);
			apiLog.setRespLen(contentLength);

			if (ObjectUtils.isEmpty(httpSttus) || httpSttus == HttpStatus.OK)
			{
				apiLog.setHttpStatus(HttpStatus.OK.value());
				apiLog.setSuccYn(true);
			} else
			{
				apiLog.setHttpStatus(httpSttus.value());
				apiLog.setSuccYn(false);
				apiLog.setErrCd(errorResponse.getErrorCode()); // CPN 에러 코드
				apiLog.setErrMsg(errorResponse.getErrorMessage());
				// E2E 에 에러내용 전송.
				e2eService.addErrorLog(transactionId, errorResponse.getErrorCode(), errorResponse.getErrorMessage());
			}

			// Thread.sleep(3*1000);
			apiLogService.addApiLog(apiLog);
		} catch (Exception ex)
		{
			logger.warn(ex.getMessage(), ex);
		}
	}
}