apache-tomcat log 필터

/**
 MicroFocus WebInpsect의 apache-tomcat access.log에 대한 Crawling 로그 기록을
 차단하기 위한 필터 모듈

 -작성일: 2018.04.02.
 -작성자: 이존석 (hasu0707@esvali.com)
*/

/**
■ 빌드 방법

CLASSPATH=%CLASSPATH%;D:\working\apache-log4j-2.11.0-bin\log4j-api-2.11.0.jar;D:\working\apache-tomcat-7.0.85\lib\servlet-api.jar
javac -encoding utf-8 WebInspectLogFilter.java


■ 적용 방법

1.class 파일을 webapps/<webapp-name>/WEB-INF/classes/ 밑에 복사


2.conf/server.xml에서 AccessLogValve에 condition을 아래와 같이 추가해 준다.
    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log." suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b"
           condition="WICRAWL" />


3.webapps/<webapp-name>/WEB-INF/web.xml에 아래를 삽입
    <!-- START: Filter for HPE WebInspect blocking logs -->
    <filter>
        <filter-name>WebInspectLogFilter</filter-name>
        <filter-class>WebInspectLogFilter</filter-class>
        <init-param>
            <param-name>wi_ipaddr1</param-name>
            <param-value>172.21.90.48</param-value>
        </init-param>
        <init-param>
            <param-name>wi_ipaddr2</param-name>
            <param-value>172.21.90.49</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>WebInspectLogFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- END:   Filter for HPE WebInspect blocking logs -->


4.webapps/<webapp-name>/WEB-INF/log4j2.xml에서 로그파일 기술 부분에 아래를 삽입
    <RollingFile...>
    ...
        <!-- START: Filter for HPE WebInspect blocking logs -->
        <Filters>
            <ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL">
                <KeyValuePair key="WICRAWL" value="true"/>
            </ThreadContextMapFilter>
        </Filters>
        <!-- END:   Filter for HPE WebInspect blocking logs -->
    ...
    </RollingFile>


※참고: https://www.innoq.com/en/blog/per-request-debugging-with-log4j2/
*/

import org.apache.logging.log4j.ThreadContext;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public final class WebInspectLogFilter implements Filter {

    private FilterConfig config = null;
    private String wi_ipaddr1 = null;
    private String wi_ipaddr2 = null;
    private String keystring = "WICRAWL";
    private String keystring_value = "true";

    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        //config.getServletContext().log("Logs capturing started");
     }

    // doFilter 메서드 구현
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        try {
            // server.xml에서 파라메터로 WebInspect 서버의 아이피 주소를 알아낸다.
            // WebInspect 서버가 2대 이므로 1,2로 구분
            String remote_ipaddr = request.getRemoteAddr();
            wi_ipaddr1 = config.getInitParameter("wi_ipaddr1");
            wi_ipaddr2 = config.getInitParameter("wi_ipaddr2");

            // WebInspect IP주소면 http header와 log4j2의 ThreadContext에 WICRAWL 속성을 추가한다.
            if (remote_ipaddr.equals(wi_ipaddr1) || remote_ipaddr.equals(wi_ipaddr2)) {
                request.setAttribute(keystring, keystring_value);
                ThreadContext.put(keystring, keystring_value);
            }

            // 여기서 변경된 정보를 가지고 다음 필터로 넘어간다.
            chain.doFilter(request, response);
        } finally {
            // ThreadContext 스택에서 삭제
            ThreadContext.remove(keystring);
        }
    }

    public void destroy() {
        this.config = null;
        this.wi_ipaddr1 = null;
        this.wi_ipaddr2 = null;
    }
}
위로 스크롤