java使用filter收集http访问

       收集访问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);
	}
}


完整例子源码下载




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值