반응형

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를 각각 확인하기 어려운 경우가 있음

반응형

+ Recent posts