서블릿 필터(Servlet Filter)를 이용한 접속통계
[프로그램 설명]
제목: 서블릿 필터(Servlet Filter)를 이용한 접속통계
실행환경: 톰캣(JSP 컨테이너),MySQL,Commons-DBCP,Commons-DbUtils
최종수정일: 2006년 05월 23일
기존 로그분석기 Webalizer와 같은 접속통계(로그분석기) 프로그램은
접속로그파일을 가지고 통계를 낸다.
단점은 로그파일에 로그인 아이디나 세션을 쓰기가 까다롭다.
그래서 서블릿 필터를 이용하여 DB에 접속정보를 직접 Insert하여
통계를 내는 걸로 생각해보았다.
장점은 로그가 DB화 되어 다루기 쉽고
로그인 아이디도 넣을 수 있어 관리자 측면에서 회원관리가 쉬워진다.
서블릿 필터는 하나의 Request에 대해서 서버단에서 바로 프로그램 할 수있다.
즉 소스 수정없이 전체소스에 프로그램 할 수 있다는 장점이 있다.
여기에 사용한 접속통계 프로그램은
서블릿필터를 하나 만들어 접속 정보들을 수집한다.
그리고 수집한 접속 정보을 JSP에서 통계를 내어 사용자 및 관리자에게 보여준다.
[소스 설명]
1. 테이블 스키마(MySQL)
CREATE TABLE dbtool_access_log (
no int(11) NOT NULL auto_increment,
request_uri varchar(100) NOT NULL default '',
query_string varchar(200) NOT NULL default '',
remote_address varchar(30) NOT NULL default '',
server_name varchar(60) NOT NULL default '',
server_port varchar(10) NOT NULL default '',
locale varchar(20) NOT NULL default '',
browser varchar(100) NOT NULL default '',
referer varchar(255) NOT NULL default '',
session_id varchar(80) NOT NULL default '',
user_id varchar(20) NOT NULL default '',
response_time int(11) NOT NULL default 0,
reg_date datetime NOT NULL default '',
PRIMARY KEY (no)
);
2. 설정(web.xml)
{your_context}/WEB-INF/web.xml을 다음과 같이 설정한다.
SetCharacterEncodingFilter는 한글설정을 위해서 넣었다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>kr.co.dbtool.filter.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>EUC_KR</param-value>
</init-param>
</filter>
<filter>
<filter-name>AccessLogFilter</filter-name>
<filter-class>kr.co.dbtool.filter.AccessLogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AccessLogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3. 설정(server.xml)
{tomcat_home}/conf/server.xml을 다음과 같이 설정한다.
DB 정보는 자신의 환경에 맞게 설정하면 된다.
<Context path="/stat" docBase="/home/stat.dbtool.co.kr" debug="0" reloadable="true" crossContext="true">
<Resource name="jdbc/dbtool" auth="Container" type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/dbtool"
username="****"
password="****"
maxActive="100"
maxIdle="10"
removeAbandoned="true"
maxWait="5000" />
</Context>
혹시 한글이 안될경우
아래와 같이 URIEncoding="euc-kr"를 server.xml에 설정하면 된다.
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="euc-kr" />
4. AccessLogFilter.java
서블릿 필터이다.
모든 사용자 Request에 대해 정보를 수집한다.
package kr.co.dbtool.filter;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import kr.co.dbtool.db.DatabaseHandler;
public class AccessLogFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
long start_time = System.currentTimeMillis();
//request에서 각정보를 구함.
String request_uri = request.getRequestURI()==null?"":request.getRequestURI();
String query_string = request.getQueryString()==null?"":request.getQueryString();
String remote_address = request.getRemoteAddr()==null?"":request.getRemoteAddr();
String server_name = request.getServerName()==null?"":request.getServerName();
int server_port = request.getServerPort();
Locale locale = request.getLocale();
String browser = request.getHeader("User-Agent")==null?"":request.getHeader("User-Agent");
String referer = (request.getHeader("referer")==null)? "":request.getHeader("referer");
//세션을 구한다.
HttpSession session = request.getSession();
String session_id = session.getId();
//사용자 아이디를 구한다.
String user_id = (session.getAttribute("user_id")==null)?"":(String)session.getAttribute("user_id");
//응답을 보낸다.
chain.doFilter(req, res);
long stop_time = System.currentTimeMillis();
long response_time = stop_time-start_time;
//DB에 하나의 요청에 대해 정보를 insert 한다.
DatabaseHandler dh = new DatabaseHandler("jdbc/dbtool");
StringBuffer sb = new StringBuffer();
sb.append("insert into dbtool_access_log \n");
sb.append("(request_uri,query_string,remote_address,server_name,server_port,locale,browser");
sb.append(",referer,session_id,user_id,response_time,reg_date) \n");
sb.append("values (?,?,?,?,?,?,?,?,?,?,?,now()) \n");
String sql = sb.toString();
ArrayList params = new ArrayList();
params.add(request_uri);
params.add(query_string);
params.add(remote_address);
params.add(server_name);
params.add(server_port+"");
params.add(locale+"");
params.add(browser);
params.add(referer);
params.add(session_id);
params.add(user_id);
params.add(response_time+"");
dh.update(sql,params);
System.out.println("dbtool_access_log insert 완료:"+(System.currentTimeMillis()-start_time)+"(msec)");
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
5. 기타 참고사항
다운받은 소스를 압축 풀고 {your_context} 하위에 위치시키고
위의 설정을 한 다음 톰캣을 실행하면 된다.
이소스는 dbcp와 dbutils란 패키지를 사용하였다.
다운받은 소스를 압축 풀면 WEB-INF/lib 디렉토리에
다음 파일들이 있다.
commons-dbcp-1.2.1.jar
commons-dbutils-1.0.jar
mysql-connector-java-3.1.12-bin.jar
이파일들은
{your_context}/WEB-INF/lib/ 또는 {tomcat_home}/common/lib/ 하위에 두면 된다.
6. 나머지 소스는 다운로드한 파일을 참고
summary.jsp
메인페이지등에서 사용할 수 있는 접속통계정보를 요약하여 보여준다.
stat_graph.jsp와 AJAX로 연동된다.
stat.jsp
상세 접속정보를 보여준다.
관리자페이지에서 사용하면 된다.
이 소스에서는 보안상 일부 정보들을 ***** 와 같이 처리하였다.
여러분이 수정해서 사용하기 바랍니다.
[소스 및 데모]
http://www.dbtool.co.kr/examples/stat/?topmenu=4&leftmenu=2