반응형
1. 개요
- 일반 log4j2설정으로는 원하는 로그를 설정할 수 없음
- client가 많은 서비스에서 쿼리까지 보는데 log가 많이 쌓임
- 서비스 구동하는 동안 request count가 필요했음
- requset한 parameter, client 브라우저등 과 같은 커스텀한 log를 만들고 싶었음
2. 설정 방법
- request가 들어올때 servlet에서 url mapping 전에 interceptor를 먼저 탐 이를 이용하여 log 설정을 진행(interceptor를 활용하여 주로 로그인 권한을 체크함)
- servlet 설정에서 interceptor 추가
-
경로 : 서비스명\src\main\webapp\WEB-INF\config\egovframework\springmvc\egov-com-servlet.xml
-
소스 추가 :
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="egovframework.com.cmm.interceptor.LoggerInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
- bean class에 명시한 경로에 java file 생성
-
경로 : 서비스명\src\main\java\egovframework\com\cmm\interceptor\LoggerInterceptor.java
-
소스 추가 :
package egovframework.com.cmm.interceptor;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import egovframework.service.util.NetworkUtil;
/**
* 로그용 인터셉터
* @author
* @since
* @version 1.0
* @see
*/
public class LoggerInterceptor extends HandlerInterceptorAdapter {
// 로그 고유번호 변수선언 및 초기화
public long lognumber = 0;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 인터셉터 접근 시 로그 고유번호 증가
lognumber++;
// request 객체에 로그 고유 번호 set
request.setAttribute("requestLogId", lognumber);
// 로그에 담을 서버 현재 날짜 및 시간 세팅
// 날짜 포맷 지정
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 서버의 현재 날짜 객체 생성
Date date = new Date();
// 날짜 포맷 형태로 서버 현재 날짜 및 시간 변수 선언 및 초기화
String requestTime = dateFormat.format(date);
// client의 브라우저 명칭을 담을 변수 선언 및 초기화
String browser ="";
// client header에서 브라우저 언어를 담을 변수 선언 및 초기화
String acceptLang = request.getHeader("Accept-Language");
// client의 브라우저 언어를 담을 변수 선언
String browserLanguage = "No Data";
// header에 브라우저 언어가 있을경우 분기 처리
if(acceptLang != null){
// header에서 브라우저 언어 추출
browserLanguage = acceptLang.split(",")[0];
}
try {
// client header에서 브라우저 정보를 담을 변수 선언 및 초기화
String browserInfo = request.getHeader("User-Agent"); // 사용자 User-Agent 값 얻기
// header에 브라우저 정보가 있을 경우 분기 처리
if (browserInfo != null) {
// header에서 Trident 문자열이 있을 경우 브라우저 언어는 Internet Explore
if (browserInfo.indexOf("Trident") > -1) {
browser = "MSIE";
// header에서 Chrome 문자열이 있을 경우 브라우저 언어는 Internet Explore
} else if (browserInfo.indexOf("Chrome") > -1) {
browser = "Chrome";
// header에서 Opera 문자열이 있을 경우 브라우저 언어는 Internet Explore
} else if (browserInfo.indexOf("Opera") > -1) {
browser = "Opera";
// header에서 Firefox 문자열이 있을 경우 브라우저 언어는 Internet Explore
} else if (browserInfo.indexOf("Firefox") > -1) {
browser = "Firefox";
// header에서 iPhone 문자열이 있을 경우 브라우저 언어는 Internet Explore
} else if (browserInfo.indexOf("iPhone") > -1 && browserInfo.indexOf("Mobile") > -1) {
browser = "iPhone";
// header에서 Android 문자열이 있을 경우 브라우저 언어는 Internet Explore
} else if (browserInfo.indexOf("Android") > -1 && browserInfo.indexOf("Mobile") > -1) {
browser = "Android";
}
}
} catch (Exception e) {
e.printStackTrace();
}
// client IP를 담을 변수 선언 및 초기화
// client IP가 아닌 서버 IP를 담는 이슈로 인해 정상 처리를 위한 함수 호출
String clientIp = NetworkUtil.getClientIpAddr(request);
// request method를 담을 변수 선언 및 초기화
String requestMethod = request.getMethod();
// request한 uri를 담을 변수 선언
// request한 프로토콜 명
String uri = request.getScheme() + "://" +
// request한 서버 이름
request.getServerName() +
// request한 스키마가 http이면서 80포트이거나, request 스키마가 https이면서 443포트인 경우 포트 생략 아닐 경우 :포트번호 추가
("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) +
// request한 uri
request.getRequestURI() +
// request한 쿼리가 있으면 쿼리 스트링의 시작을 알리는 ?와 쿼리스트링 추가 없을경우 빈값
(request.getQueryString() != null ? "?" + request.getQueryString() : "");
// 서버 ip를 담을 변수 선언 및 초기화
// 현재 서버의 localhost명을 담을 변수 선언 및 초기화
InetAddress address = InetAddress.getLocalHost();
// 서버 ip를 담을 변수 선언 및 초기화
String serverIp = address.getHostAddress();
// request된 파라미터를 정리하여 log로 뿌려줄 변수 선언 및 초기화
String params ="";
// request된 파라미터를 담을 변수 선언 및 초기화
Enumeration param = request.getParameterNames();
// request된 param가 있을 때까지 반복
while(param.hasMoreElements()){
// request된 파라미터의 이름을 담을 변수 선언 및 초기화
String name = (String)param.nextElement();
// request된 파라미터의 값을 담을 변수 선언 및 초기화
String value = request.getParameter(name);
// value값이 있을 경우 params 변수에 이름:값 탭을 추가
if(null != value && !"".equals(value)){
params += (name+":"+value+"\t");
}
}
// 로그 정리
System.out.println("\n\n=========================================\tREQUEST START\t=========================================");
System.out.println(" Log ID \t: " +request.getAttribute("requestLogId"));
System.out.println(" Request Time \t: "+ requestTime);
System.out.println(" BrowserLanguage: " + browserLanguage);
System.out.println(" BrowserInfo \t: " + browser);
System.out.println(" Client IP \t: " + clientIp);
System.out.println(" Method \t: " + requestMethod);
System.out.println(" Request URL \t: "+ uri);
System.out.println(" Server IP \t: "+ serverIp);
System.out.println(" Parameters \t: " + params);
System.out.println("=========================================\tREQUEST END\t\t=========================================\n\n");
// request된 intercepter 종료
return super.preHandle(request, response, handler);
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 로그에 담을 서버 현재 날짜 및 시간 세팅
// 날짜 포맷 지정
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 서버의 현재 날짜 객체 생성
Date date = new Date();
// 날짜 포맷 형태로 서버 현재 날짜 및 시간 변수 선언 및 초기화
String responseTime = dateFormat.format(date);
// request한 uri를 담을 변수 선언
// request한 프로토콜 명
String uri = request.getScheme() + "://" +
// request한 서버 이름
request.getServerName() +
// request한 스키마가 http이면서 80포트이거나, request 스키마가 https이면서 443포트인 경우 포트 생략 아닐 경우 :포트번호 추가
("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) +
// request한 uri
request.getRequestURI() +
// request한 쿼리가 있으면 쿼리 스트링의 시작을 알리는 ?와 쿼리스트링 추가 없을경우 빈값
(request.getQueryString() != null ? "?" + request.getQueryString() : "");
// 로그 정리
System.out.println("\n\n=========================================\tRESPONSE START\t=========================================");
System.out.println(" Log ID \t: " + request.getAttribute("requestLogId"));
System.out.println(" Response Time \t: "+ responseTime);
System.out.println(" Request URL \t: "+ uri);
// java 버전 이슈로 인해 response객체의 status값(200, 403 ... )을 받아오지 못해 주석 처리
// System.out.println(" Response status: " + response.getStatus());
System.out.println("=========================================\tRESPONSE END\t\t=========================================\n\n");
// response된 intercepter 종료
super.postHandle(request, response, handler, modelAndView);
}
}
3. 단점
- log가 여러줄로 처리되어 다른 log와 중첩되어 보여지는 경우가 간혹 발생하며,
서버 side에서 늦게 처리되는경우 request와 respone를 각각 확인하기 어려운 경우가 있음
반응형