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>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值