您的位置:首页 > 理论基础 > 计算机网络

java使用filter收集http访问

2015-12-04 14:47 176 查看
收集访问web服务器的http信息,实现过程:写filter拦截每个请求或特定请求,记录访问时间,立刻filter的时间,所耗时间可作为服务器响应时间参考,收集放到List中,当超过一定数量(比如200)或达到一定时间了(弄个定时器),则把记录异步保存(比如创建线程去把数据保存到数据库或通过JMS等手段)。

结果如下图



下面贴源码



web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>testweb</display-name>

<!-- 监控收集 -->
<listener>
<listener-class>com.fei.monitor.SessionMonitoringListener</listener-class>
</listener>
<filter>
<filter-name>httpMonitoringFilter</filter-name>
<filter-class>com.fei.monitor.HttpMonitoringFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMonitoringFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 监控收集 -->

<servlet>
<description></description>
<display-name>TestMonitorServlet</display-name>
<servlet-name>TestMonitorServlet</servlet-name>
<servlet-class>com.fei.monitor.TestMonitorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestMonitorServlet</servlet-name>
<url-pattern>/testMonitorServlet</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>


HttpMonitoringFilter.java

package com.fei.monitor;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HttpMonitoringFilter implements Filter {

private static final ThreadMXBean THREAD_BEAN = ManagementFactory.getThreadMXBean();
//jvm是否支持线程对cpu的监控
private static final boolean CPU_TIME_ENABLED = THREAD_BEAN.isThreadCpuTimeSupported()
&& THREAD_BEAN.isThreadCpuTimeEnabled();

public HttpMonitoringFilter() {

}

public void init(FilterConfig fConfig) throws ServletException {

}

public void destroy() {

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
FilterServletResponseWrapper wrapperReponse = new FilterServletResponseWrapper(res);

String uri = req.getRequestURI().substring(req.getContextPath().length());
final int lastIndexOfSemiColon = uri.lastIndexOf(';');
if (lastIndexOfSemiColon != -1) {
uri = uri.substring(0, lastIndexOfSemiColon);
}

String queryString = req.getQueryString();

String method ;//GET,POST,PUT
//判断是不是ajax请求
if ("XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
method = "ajax " + req.getMethod();
} else {
method = req.getMethod();
}

String remoteAddress = req.getRemoteAddr();

final long start = System.currentTimeMillis();
final long startCpuTime = getCurrentThreadCpuTime();
String sessionId = req.getSession().getId();
boolean isSystemError = false;
Throwable systemException = null;
try {

chain.doFilter(request, wrapperReponse);
wrapperReponse.flushBuffer();

} catch (Exception e) {
isSystemError = true;
systemException = e;
}finally{
long duration = Math.max(System.currentTimeMillis() - start, 0);
long cpuUsedMillis = (getCurrentThreadCpuTime() - startCpuTime) / 1000000;

String error = "";
if(wrapperReponse.getCurrentStatus() >= HttpServletResponse.SC_BAD_REQUEST){
isSystemError = true;
error = "error "+wrapperReponse.getCurrentStatus();
}

if(isSystemError && systemException != null){
error = systemException.getMessage();
}
RequestCounter requestCounter = new RequestCounter(remoteAddress,uri,queryString,method,start,duration,
cpuUsedMillis,isSystemError,error,sessionId);
Counter.addCounter(requestCounter);
}

}

static long getCurrentThreadCpuTime() {
return getThreadCpuTime(Thread.currentThread().getId());
}

static long getThreadCpuTime(long threadId) {
if (CPU_TIME_ENABLED) {
return THREAD_BEAN.getThreadCpuTime(threadId);
}
return 0;
}

}
Counter.java

package com.fei.monitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Counter {

//达到最大量,则保存
private static final int MAX_SIZE = 200;

private static final List<RequestCounter> requestList = new ArrayList<RequestCounter>();

private static final ConcurrentMap<String,SessionCounter> sessionMap = new ConcurrentHashMap<String,SessionCounter>();

public static void addCounter(RequestCounter counter){
requestList.add(counter);
if(requestList.size()>= MAX_SIZE){
saveRequestCounter();
}
}
/**
* 保存requestCounter
*/
public static void saveRequestCounter(){
if(!requestList.isEmpty()){
//1.保存到数据库,或通过JMS等技术传到另一个监控收集平台
//异步保存

//2.清空list
requestList.clear();
}
}

public static void addCount(SessionCounter counter){
sessionMap.put(counter.getSessionId(), counter);
if(sessionMap.size()>= MAX_SIZE){
saveSessionCounter();
}
}

/**
* 保存sessionCounter
*/
public static void saveSessionCounter(){
if(!sessionMap.isEmpty()){
//1.保存到数据库,或通过JMS等技术传到另一个监控收集平台
//异步保存

//2.清空list
sessionMap.clear();
}
}

public static void saveAll(){
saveRequestCounter();
saveSessionCounter();
}
public static List<RequestCounter> getRequestlist() {
return requestList;
}
public static Map<String, SessionCounter> getSessionmap() {
return sessionMap;
}
}
RequestCounter.java

package com.fei.monitor;
/**
* http请求成功,获取该请求的一些信息
*/
public class RequestCounter {

/**
* 请求的uri
*/
private String uri;
/**
* 请求的参数
*/
private String queryString;
/**
* 访问方式GET,POST,PUT
*/
private String type;//GET,POST,PUT
/**
* 客户地址
*/
private String remoteAddress;
/**
* 进入filter时间
*/
private long visitTime;//访问时间
/**
* 耗时,进入filter到离开filter
*/
private long durationTime;
/**
* 线程使用cpu时间(ms)
*/
private long cpuTime;
/**
* 是不是系统出错了,true是,false否
*/
private boolean isSystemError;
/**
* 错误原因
*/
private String errorReason;
/**
* 对应哪个sessionId
*/
private String sessionId;

public RequestCounter(String remoteAddress,String uri, String queryString, String type,
long visitTime, long durationTime, long cpuTime,
boolean isSystemError, String errorReason,String sessionId) {
super();
this.remoteAddress = remoteAddress;
this.uri = uri;
this.queryString = queryString;
this.type = type;
this.visitTime = visitTime;
this.durationTime = durationTime;
this.cpuTime = cpuTime;
this.isSystemError = isSystemError;
this.errorReason = errorReason;
this.sessionId = sessionId;
}

public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public long getVisitTime() {
return visitTime;
}
public void setVisitTime(long visitTime) {
this.visitTime = visitTime;
}
public long getDurationTime() {
return durationTime;
}
public void setDurationTime(long durationTime) {
this.durationTime = durationTime;
}
public long getCpuTime() {
return cpuTime;
}
public void setCpuTime(long cpuTime) {
this.cpuTime = cpuTime;
}
public boolean isSystemError() {
return isSystemError;
}
public void setSystemError(boolean isSystemError) {
this.isSystemError = isSystemError;
}
public String getErrorReason() {
return errorReason;
}
public void setErrorReason(String errorReason) {
this.errorReason = errorReason;
}

public String getSessionId() {
return sessionId;
}

public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}

public String getQueryString() {
return queryString;
}

public void setQueryString(String queryString) {
this.queryString = queryString;
}

public String getRemoteAddress() {
return remoteAddress;
}

public void setRemoteAddress(String remoteAddress) {
this.remoteAddress = remoteAddress;
}
}


FilterServletResponseWrapper.java

package com.fei.monitor;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class FilterServletResponseWrapper extends HttpServletResponseWrapper {

private int status;

public FilterServletResponseWrapper(HttpServletResponse response) {
super(response);

}

@Override
public void setStatus(int sc) {
super.setStatus(sc);
this.status = sc;
}

public int getCurrentStatus() {
return status;
}

@Override
public void sendError(int sc, String msg) throws IOException {
super.sendError(sc, msg);
this.status = sc;
}

@Override
public void sendError(int sc) throws IOException {
super.sendError(sc);
this.status = sc;
}

}


TestMonitorServlet.java

package com.fei.monitor;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 测试监控
* @author weijianfei
*
*/
public class TestMonitorServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String type = request.getParameter("type");
if("tomcatInfo".equals(type)){
this.tomcatInfo(request, response);
}else if("threadInfo".equals(type)){
this.threadInfo(request, response);
}else if("requestCounter".equals(type)){
this.requestCounter(request, response);
}else if("sessionCounter".endsWith(type)){
this.sessionCounter(request, response);
}
}

private void tomcatInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
StringBuffer sb = new StringBuffer();
sb.append("<h3>========tomcatInfo========</h3><br/>");
for(TomcatInformations info : TomcatInformations.buildTomcatInformationsList()){
sb.append(info).append("<br/><br/>");
}
sb.append("<br/><br/>");
//输出
outToClient(response, sb.toString());

}

private void threadInfo(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
StringBuffer sb = new StringBuffer();
sb.append("<h3>========threadInfo========</h3><br/>");
for(ThreadInformations t : ThreadInformations.buildThreadInformationsList()){
sb.append(t).append("<br/><br/>");
}
sb.append("<br/><br/>");
//输出
outToClient(response, sb.toString());

}

private void requestCounter(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
StringBuffer sb = new StringBuffer();
sb.append("<h3>========requestCounter========</h3><br/>");
sb.append("<table border=1><tr><th>uri</th><th>queryString</th><th>type</th>")
.append("<th>客户地址</th><th>访问时间</th><th>耗时ms</th><th>使用cpu时间(ms)</th><th>是否访问错误</th><th>错误原因</th></tr>");

for(RequestCounter  t : Counter.getRequestlist()){
sb.append("<tr>");

sb.append("<td>").append(t.getUri()).append("</td>");
sb.append("<td>").append(t.getQueryString()).append("</td>");
sb.append("<td>").append(t.getType()).append("</td>");
sb.append("<td>").append(t.getRemoteAddress()).append("</td>");
sb.append("<td>").append(getTimeString(t.getVisitTime())).append("</td>");
sb.append("<td>").append(t.getDurationTime()).append("</td>");
sb.append("<td>").append(t.getCpuTime()).append("</td>");
sb.append("<td>").append(t.isSystemError()).append("</td>");
sb.append("<td>").append(t.getErrorReason()).append("</td>");

sb.append("</tr>");
}
sb.append("</table>");
sb.append("<br/><br/>");
//输出
outToClient(response, sb.toString());

}

private void sessionCounter(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
StringBuffer sb = new StringBuffer();
sb.append("<h3>========sessionCounter========</h3><br/>");
sb.append("<table border=1><tr><th>sessionId</th><th>访问时间</th><th>立刻时间</th><th>停留时间(ms)</th></tr>");
SessionCounter c = null;
for(String  k : Counter.getSessionmap().keySet()){
c = Counter.getSessionmap().get(k);
sb.append("<tr>");
sb.append("<td>").append(c.getSessionId()).append("</td>");
sb.append("<td>").append(getTimeString(c.getCreateTime())).append("</td>");
sb.append("<td>").append(getTimeString(c.getEndTime())).append("</td>");
sb.append("<td>").append(c.getDurationTime()).append("</td>");

sb.append("</tr>");
}
sb.append("</table>");
sb.append("<br/><br/>");
//输出
outToClient(response, sb.toString());

}

private void outToClient(HttpServletResponse response,String content){
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer;
try {
writer = response.getWriter();
writer.write(content);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}

}

private String getTimeString(long time){
Date d = new Date(time);
return sdf.format(d);
}
}


完整例子源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: