java使用filter收集http访问

来源:互联网 发布:索尼耳机 知乎 编辑:程序博客网 时间:2024/06/03 14:44

       收集访问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.清空listrequestList.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.清空listsessionMap.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);}@Overridepublic void setStatus(int sc) {super.setStatus(sc);this.status = sc;}public int getCurrentStatus() {return status;}@Overridepublic void sendError(int sc, String msg) throws IOException {super.sendError(sc, msg);this.status = sc;}@Overridepublic 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);}}


完整例子源码下载




0 0
原创粉丝点击