zoukankan      html  css  js  c++  java
  • spring mvc记录各个controller访问开始结束时间,以及耗时时间 线程安全

    package cn.test.web.interceptor;  
    public class StopWatchHandlerInterceptor extends HandlerInterceptorAdapter {  
        private NamedThreadLocal<Long>  startTimeThreadLocal =   
    new NamedThreadLocal<Long>("StopWatch-StartTime");  
        @Override  
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response,   
    Object handler) throws Exception {  
            long beginTime = System.currentTimeMillis();//1、开始时间  
            startTimeThreadLocal.set(beginTime);//线程绑定变量(该数据只有当前请求的线程可见)  
            return true;//继续流程  
        }  
          
        @Override  
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response,   
    Object handler, Exception ex) throws Exception {  
            long endTime = System.currentTimeMillis();//2、结束时间  
            long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)  
            long consumeTime = endTime - beginTime;//3、消耗的时间  
            if(consumeTime > 500) {//此处认为处理时间超过500毫秒的请求为慢请求  
                //TODO 记录到日志文件  
                System.out.println(  
    String.format("%s consume %d millis", request.getRequestURI(), consumeTime));  
            }          
        }  
    }  
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.NamedThreadLocal;
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    import com.common.interceptor
    /**
     *拦截所有用户的操作,记录操作日志
     * 
     * @author 
     * @version 1.00.00
     *
     */
    public class UserActionLogInterceptor extends HandlerInterceptorAdapter{
        private static final Logger logger = LoggerFactory.getLogger(UserActionLogInterceptor.class.getName());
        
        private NamedThreadLocal<Long> startTimeThreadLocal=new NamedThreadLocal<Long>("StartTime-EndTime");
        
        @Autowired
        private JdbcTemplate jdbcTemplate;
        
        @Override
        public boolean preHandle(HttpServletRequest request, 
        HttpServletResponse response, Object handler) throws Exception {
        String url=request.getRequestURI();
        String reqId=UUID.randomUUID().toString();
        //前段如果已经传入请求标识,则继续沿用
        if(request.getParameter("reqId")==null){    
    
        request.setAttribute("reqId", reqId);
        }else{
        reqId=request.getParameter("reqId");
        //encode一次,防止前段sql注入
        reqId=URLEncoder.encode(reqId, reqId);
        request.setAttribute("reqId", reqId);
        }     
    
        logger.debug("进了Web端的logger interceptor,请求Url:"+url+"  请求标识为:" + reqId+"  开始处理请求Start");
        Long startTime=System.currentTimeMillis();
        startTimeThreadLocal.set(startTime);    
    
        return true;
        }
        
        @Override
        public void afterCompletion(HttpServletRequest request, 
        HttpServletResponse response, Object handler, Exception ex) throws Exception {
        
        String url=request.getRequestURI();    
        Long startTime=startTimeThreadLocal.get();
        Long endTime  =System.currentTimeMillis();
        String reqId=(String)request.getAttribute("reqId");    
    
        User user = SecurityUtils.getSessionUser();    
    
        if(user!=null){  
        String loginid=user.getLoginId();
        String ip     =request.getRemoteAddr();
        String loginType=user.getLoginType();
        logger.debug("UserActionLogInterceptor:用户名:"+loginid+",  IP:"+ip);
        if(handler instanceof HandlerMethod){
        HandlerMethod method=(HandlerMethod)handler;
        String className=method.getBean().getClass().getSimpleName();
        String methodName=method.getMethod().getName();
        //记录日志-//xxhCommonController 不做日志记录
        if(!"xxhCommonController".equals(className)&&!"MenuHintsController".equals(className)){    
    
            
    String msg=ex==null?"操作成功":"操作失败:"+ex.getMessage();
            
    if(msg.length()>512){//数据库长度为1536,全部为汉字时是512个字符
            
    msg=msg.substring(0, 512);
            
    }
            
    if(reqId.length()>96){
            
    msg=msg.substring(0, 95);
            
    }
            
    UserActionLogger logBean=new UserActionLogger();
        logBean.setUserId(loginid);
        logBean.setPostClassId(className);
        logBean.setPostAction(methodName);
        logBean.setLogType(loginType);
        logBean.setClientIP(ip);
        logBean.setProcessTime(endTime-startTime);
        logBean.setObjId(reqId);
        logBean.setBookId(user.getCurrentSetsOfBooksId());
        logBean.setDetail(msg);
        log2DB(logBean);
        }else{
        logger.debug("UserActionLogInterceptor:请求来自xxhCommonController,MenuHintsController,无需记录日志");
        }
        }else{
        logger.debug("UserActionLogInterceptor:非业务处理类的controller,无需记录日志");
        }
        }else{
        logger.debug("UserActionLogInterceptor:未登录用户,无法获取用户信息");
        }
        if(ex!=null){
        logger.debug("UserActionLogInterceptor拦截到来自controller的异常信息", ex);
        }
        logger.debug("进了Web端的logger interceptor,请求Url:"+url+",  请求标识为:" + reqId+"  结束End");
        
        }  
        
        private void log2DB(UserActionLogger logInfo){
        String insertSql=" insert into xxh_opt_log "+
        " (syslogid, "+
        " logtime, "+
        " logtype, "+
        " postclassid, "+
        " postaction, "+
        " objid, "+
        " userid, "+
        " clientip, "+
        " bookid, "+
        " detail, "+
        " processtime) "+
        " values "+
        " ("
        + " SQ_xxh_OPT_LOG.Nextval, "+
        " sysdate, "+
        " '"+logInfo.getLogType()+"', "+
        " '"+logInfo.getPostClassId()+"', "+
        " '"+logInfo.getPostAction()+"', "+
        " '"+logInfo.getObjId()+"', "+
        " '"+logInfo.getUserId()+"', "+
        " '"+logInfo.getClientIP()+"', "+
        " "+logInfo.getBookId()+", "+
        " '"+logInfo.getDetail()+"', "+
        " "+logInfo.getProcessTime()+""
        +")";
        try {jdbcTemplate.execute(insertSql);} catch (Exception e) {logger.error("UserActionLogInterceptor_logInDB_error",e);}
        }
    }
    
    XML 配置:
    
       <mvc:interceptors>   
          
            <mvc:interceptor>    
                <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->  
                <mvc:mapping path="/**" /> 
                <bean class="com.common.interceptor.UserActionLogInterceptor"></bean>    <!-- 自定义拦截器路径 -->
            </mvc:interceptor>  
            <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->  
        </mvc:interceptors>
  • 相关阅读:
    触摸屏与usb鼠标同时支持
    QT国际化(lupdate/linguits/lrelease)生成.ts,转换成.qm方法
    Qt5 使用lambda
    c++中lambda表达式的用法
    异或运算的作用
    函数指针和指针函数用法和区别
    前端html页面学习---html部分
    二:maven构建module
    一:使用maven构建项目
    maven项目发布到tomcat后没有lib目录解决方案
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13317469.html
Copyright © 2011-2022 走看看